Salome HOME
Creation of a new study from an existing one is implemented.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / ScenarioServiceImpl.java
index 8ee294c347ebc8b99a7dbb461b68f4e8d63e30c4..794dd9029d8a799238c577c7524ad9a97a886a60 100644 (file)
@@ -19,8 +19,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
+import org.hibernate.transform.Transformers;
 import org.splat.common.properties.MessageKeyEnum;
 import org.splat.dal.bo.kernel.Relation;
 import org.splat.dal.bo.kernel.Role;
@@ -32,6 +35,7 @@ import org.splat.dal.bo.som.File;
 import org.splat.dal.bo.som.KnowledgeElement;
 import org.splat.dal.bo.som.KnowledgeElementType;
 import org.splat.dal.bo.som.ProgressState;
+import org.splat.dal.bo.som.ProjectElement;
 import org.splat.dal.bo.som.Publication;
 import org.splat.dal.bo.som.Scenario;
 import org.splat.dal.bo.som.SimulationContext;
@@ -39,6 +43,7 @@ import org.splat.dal.bo.som.SimulationContextType;
 import org.splat.dal.bo.som.Study;
 import org.splat.dal.bo.som.UsedByRelation;
 import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.bo.som.ValidationCycle;
 import org.splat.dal.bo.som.Document.Properties;
 import org.splat.dal.dao.kernel.RoleDAO;
 import org.splat.dal.dao.kernel.UserDAO;
@@ -46,6 +51,8 @@ import org.splat.dal.dao.som.KnowledgeElementDAO;
 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
 import org.splat.dal.dao.som.ScenarioDAO;
 import org.splat.dal.dao.som.StudyDAO;
+import org.splat.dal.dao.som.ValidationCycleDAO;
+import org.splat.exception.InvalidParameterException;
 import org.splat.i18n.I18nUtils;
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MismatchException;
@@ -55,11 +62,15 @@ import org.splat.kernel.NotApplicableException;
 import org.splat.log.AppLogger;
 import org.splat.service.dto.DocumentDTO;
 import org.splat.service.dto.FileDTO;
+import org.splat.service.dto.ScenarioDTO;
 import org.splat.service.dto.StepDTO;
 import org.splat.service.technical.IndexService;
 import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.RepositoryService;
+import org.splat.service.technical.StepsConfigService;
 import org.splat.som.Step;
 import org.splat.util.BeanHelper;
+import org.splat.util.IOUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -75,6 +86,10 @@ public class ScenarioServiceImpl implements ScenarioService {
        public final static AppLogger LOG = AppLogger
                        .getLogger(ScenarioServiceImpl.class);
 
+       /**
+        * " to " literal.
+        */
+       private static final String TO = " to ";
        /**
         * Injected index service.
         */
@@ -139,6 +154,11 @@ public class ScenarioServiceImpl implements ScenarioService {
         */
        private SimulationContextService _simulationContextService;
 
+       /**
+        * Injected simulation context type service.
+        */
+       private SimulationContextTypeService _simulationContextTypeService;
+
        /**
         * Injected project service.
         */
@@ -149,6 +169,21 @@ public class ScenarioServiceImpl implements ScenarioService {
         */
        private DocumentTypeService _documentTypeService;
 
+       /**
+        * Injected validation cycle DAO.
+        */
+       private ValidationCycleDAO _validationCycleDAO;
+
+       /**
+        * Injected project settings service.
+        */
+       private StepsConfigService _stepsConfigService;
+
+       /**
+        * Injected repository service.
+        */
+       private RepositoryService _repositoryService;
+
        /**
         * Get the projectElementService.
         * 
@@ -208,6 +243,262 @@ public class ScenarioServiceImpl implements ScenarioService {
                _stepService = stepService;
        }
 
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ScenarioService#getStudyScenarios(java.lang.Long)
+        */
+       @Override
+       @Transactional(readOnly = true)
+       public List<ScenarioDTO> getStudyScenarios(final Long studyId) {
+               DetachedCriteria query = DetachedCriteria
+                               .forClass(Scenario.class, "scen")
+                               .add(Restrictions.eq("owner.rid", studyId))
+                               .setProjection(
+                                               Projections.projectionList().add(
+                                                               Projections.property("scen.title"), "title")
+                                                               .add(Projections.property("scen.rid"), "index"))
+                               .setResultTransformer(
+                                               Transformers.aliasToBean(ScenarioDTO.class));
+               return getScenarioDAO().getFilteredDTOList(query);
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ScenarioService#copyStudyContent(long, long, int, long)
+        */
+       @Override
+       @Transactional
+       public void copyStudyContent(final long fromStudyId, final long fromScenId,
+                       final int finalStepNum, final long toStudyId)
+                       throws InvalidParameterException, MissedPropertyException,
+                       InvalidPropertyException, MultiplyDefinedException,
+                       NotApplicableException, IOException {
+               Study fromStudy = getStudyService().selectStudy(fromStudyId);
+               if (fromStudy == null) {
+                       throw new InvalidParameterException(MessageKeyEnum.STD_000002
+                                       .toString(), String.valueOf(fromStudyId));
+               }
+               Scenario fromScen = null;
+               for (Scenario scen : fromStudy.getScenariiList()) {
+                       if (scen.getIndex() == fromScenId) {
+                               fromScen = scen;
+                               break;
+                       }
+               }
+
+               Study toStudy = getStudyService().selectStudy(toStudyId);
+               if (toStudy == null) {
+                       throw new InvalidParameterException(MessageKeyEnum.STD_000002
+                                       .toString(), String.valueOf(toStudy));
+               }
+
+               // Check if the step is applied to a scenario and scenario is defined
+               if (fromScen == null
+                               && getStepsConfigService().stepInvolves(finalStepNum,
+                                               Scenario.class)) {
+                       throw new InvalidParameterException(MessageKeyEnum.SCN_000006
+                                       .toString(), String.valueOf(fromScenId));
+               }
+
+               // Copy validation cycles
+               copyValidationCycles(fromStudy, toStudy);
+
+               // Copy content of the study up to the given step
+               Map<Publication, Publication> oldToNewPub = new HashMap<Publication, Publication>();
+               copyDocs(fromStudy, toStudy, finalStepNum, oldToNewPub);
+               if (fromScen != null) {
+                       copyDocs(fromScen, toStudy.getScenariiList().get(0), finalStepNum,
+                                       oldToNewPub);
+               }
+               copyDependencies(fromStudy, finalStepNum, oldToNewPub);
+               if (fromScen != null) {
+                       copyDependencies(fromScen, finalStepNum, oldToNewPub);
+               }
+       }
+
+       /**
+        * Copy validation cycles from study to study.
+        * 
+        * @param fromStudy
+        *            the source study
+        * @param toStudy
+        *            the destination study
+        */
+       private void copyValidationCycles(final Study fromStudy, final Study toStudy) {
+               for (ValidationCycle fromCycle : fromStudy.getValidationCycles()
+                               .values()) {
+                       if (fromCycle.isAssigned()) {
+                               ValidationCycle cycle = fromCycle.clone(toStudy);
+                               getValidationCycleDAO().create(cycle);
+                               toStudy.addRelation(cycle.getContext());
+                               toStudy.getValidationCycles().put(
+                                               cycle.getDocumentType().getName(), cycle); // Replaces the cycle if exists as default,
+                       }
+               }
+       }
+
+       /**
+        * Copy dependencies between documents from the given project element up to <BR>
+        * the given step according to the given map of old publications to new publications.
+        * 
+        * @param from
+        *            the source project element
+        * @param finalStepNum
+        *            the final step for copy processing
+        * @param oldToNewPub
+        *            the old to new publications map
+        */
+       private void copyDependencies(final ProjectElement from,
+                       final int finalStepNum,
+                       final Map<Publication, Publication> oldToNewPub) {
+               // Copy dependencies between copied documents
+               for (Publication pub : from.getDocums()) {
+                       // If the document in the step before the final one
+                       if (pub.value().getStep() <= finalStepNum) {
+                               Publication newPub = oldToNewPub.get(pub);
+                               for (Publication used : pub.getRelations(UsesRelation.class)) {
+                                       newPub.addDependency(oldToNewPub.get(used));
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Copy documents with dependencies up to the given step.
+        * 
+        * @param from
+        *            the source project element
+        * @param to
+        *            the destination project element
+        * @param finalStepNum
+        *            the final step for copy process
+        * @param oldToNewPub2
+        * @throws MissedPropertyException
+        *             if document creation is failed
+        * @throws InvalidPropertyException
+        *             if document creation is failed
+        * @throws MultiplyDefinedException
+        *             if document creation is failed
+        * @throws IOException
+        *             if document file creation is failed
+        * @throws NotApplicableException
+        *             if document state is not applicable
+        * @param oldToNewPub
+        *            the old to new publications map
+        * 
+        */
+       private void copyDocs(final ProjectElement from, final ProjectElement to,
+                       final int finalStepNum,
+                       final Map<Publication, Publication> oldToNewPub)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, NotApplicableException, IOException {
+               Map<Integer, Step> steps = getProjectElementService().getStepsMap(to);
+               // Copy publications without old versions and relations to not copied steps documents
+               for (Publication pub : from.getDocums()) {
+                       // If the document in the step before the final one
+                       if (pub.value().getStep() <= finalStepNum) {
+                               // Copy the document
+                               oldToNewPub.put(pub, createDoc(pub.value(), steps.get(pub
+                                               .value().getStep())));
+                       }
+               }
+       }
+
+       /**
+        * Create a copy of the given document and publish it in the given step.
+        * 
+        * @param fromDoc
+        *            the source document
+        * @param step
+        *            the destination step
+        * @return the created publication
+        * @throws MissedPropertyException
+        *             if document creation is failed
+        * @throws InvalidPropertyException
+        *             if document creation is failed
+        * @throws MultiplyDefinedException
+        *             if document creation is failed
+        * @throws IOException
+        *             if document file creation is failed
+        * @throws NotApplicableException
+        *             if document state is not applicable
+        */
+       private Publication createDoc(final Document fromDoc, final Step step)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException, NotApplicableException {
+
+               java.io.File srcFile = fromDoc.getSourceFile().asFile();
+               // Creation of the document
+               Document.Properties dprop = new Document.Properties().setName(
+                               fromDoc.getTitle()).setType(fromDoc.getType()).setFormat(
+                               fromDoc.getFormat()).setAuthor(fromDoc.getAuthor());
+
+               java.io.File tmpDir = getRepositoryService().getDownloadDirectory(
+                               step.getOwnerStudy().getAuthor());
+
+               // Remove local file index prefix to get original filename.
+               java.io.File upfile = new java.io.File(tmpDir.getPath()
+                               + "/"
+                               + srcFile.getName().substring(
+                                               srcFile.getName().indexOf('_') + 1));
+               // Copy the source file into the temporary folder with original filename.
+               copyFile(srcFile, upfile);
+
+               dprop.setLocalPath(upfile.getPath());
+               Publication addoc = getStepService().createDocument(step, dprop);
+
+               // Move the temporary file into the repository
+               moveFile(upfile, addoc.getSourceFile().asFile());
+
+               getPublicationService().saveAs(addoc, fromDoc.getProgressState());
+
+               // Copy attached files
+               for (Relation rel : fromDoc.getRelations(ConvertsRelation.class)) {
+                       File attach = ((ConvertsRelation) rel).getTo();
+                       ConvertsRelation export = getPublicationService().attach(addoc,
+                                       attach.getFormat());
+                       // Copy the source document attachment file to the new study vault
+                       copyFile(attach.asFile(), export.getTo().asFile());
+               }
+               return addoc;
+       }
+
+       /**
+        * Copy a file. Print info message.
+        * 
+        * @param upfile
+        *            the source file.
+        * @param file
+        *            the target file
+        * @throws IOException
+        *             if failed
+        */
+       private void copyFile(final java.io.File upfile, final java.io.File file)
+                       throws IOException {
+               if (LOG.isInfoEnabled()) {
+                       LOG.info("Copy " + upfile.getAbsolutePath() + TO + file.getPath());
+               }
+               IOUtils.copy(upfile, file);
+       }
+
+       /**
+        * Copy a file. Print info message.
+        * 
+        * @param upfile
+        *            the source file.
+        * @param file
+        *            the target file
+        * @return true if renamed otherwise return false
+        */
+       private boolean moveFile(final java.io.File upfile, final java.io.File file) {
+               if (LOG.isInfoEnabled()) {
+                       LOG.info("Move " + upfile.getAbsolutePath() + TO + file.getPath());
+               }
+               return upfile.renameTo(file);
+       }
+
        /**
         * {@inheritDoc}
         * 
@@ -361,20 +652,37 @@ public class ScenarioServiceImpl implements ScenarioService {
                return study;
        }
 
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
+        */
        @Transactional
-       public void assignContext() throws MissedPropertyException,
+       public void assignStudyContext(final Long studyId, final String ctxType,
+                       final String ctxValue) throws MissedPropertyException,
                        InvalidPropertyException, MultiplyDefinedException {
-               //TODO: complete the method
-               SimulationContext.Properties cprop = new SimulationContext.Properties();
-               Long id = 0L;
-               Study study = getStudyDAO().get(id);
-               if (cprop.getIndex() == 0) { // Input of new project context
-                       cprop.setType(getSimulationContextService().selectType("product"))
-                                       .setValue(cprop.getValue());
+               // Find the study by the given id
+               Study study = getStudyDAO().get(studyId);
+               if (study == null) {
+                       throw new InvalidPropertyException(MessageKeyEnum.STD_000002
+                                       .toString(), studyId);
+               }
+               // Find the context type by its name
+               SimulationContextType celt = getSimulationContextService().selectType(
+                               ctxType);
+               if (celt == null) {
+                       // Creation of a new context type
+                       celt = getSimulationContextTypeService().createType(ctxType,
+                                       getProjectElementService().getFirstStep(study).getStep());
+               }
+               // Find the given context value of the given type
+               SimulationContext context = getSimulationContextService()
+                               .selectSimulationContext(celt, ctxValue);
+               if (context == null) { // Input of a new project context
+                       SimulationContext.Properties cprop = new SimulationContext.Properties();
+                       cprop.setType(celt).setValue(ctxValue);
                        getStudyService().addProjectContext(study, cprop);
                } else { // Selection of existing project context
-                       SimulationContext context = getSimulationContextService()
-                                       .selectSimulationContext(cprop.getIndex());
                        getStudyService().addProjectContext(study, context);
                }
        }
@@ -434,26 +742,6 @@ public class ScenarioServiceImpl implements ScenarioService {
                return kelm;
        }
 
-       /**
-        * Update the scenario in the database.
-        * 
-        * @param aScenario
-        *            the scenario to update
-        * @return true if updating succeeded
-        */
-       @Transactional
-       private boolean update(final Scenario aScenario) {
-               boolean isOk = false;
-               try {
-                       getScenarioDAO().update(aScenario); // Update of relational base
-                       isOk = true;
-               } catch (Exception error) {
-                       LOG.error("Unable to re-index the knowledge element '"
-                                       + aScenario.getIndex() + "', reason:", error);
-               }
-               return isOk;
-       }
-
        /**
         * {@inheritDoc}
         * 
@@ -670,7 +958,7 @@ public class ScenarioServiceImpl implements ScenarioService {
                                Publication newPub = getStepService().createDocument(step,
                                                dprop);
 
-                               // Remeber the new document
+                               // Remember the new document
                                newDocs.add(newPub);
 
                                saveFile(newPub, step, upfile);
@@ -757,15 +1045,11 @@ public class ScenarioServiceImpl implements ScenarioService {
                                // If there is no attachment with this extension then attach the new one
                                ConvertsRelation export = getPublicationService().attach(pub,
                                                fileFormat);
-                               if (LOG.isDebugEnabled()) {
-                                       LOG.debug("Moving " + upfile.getName() + " to "
-                                                       + export.getTo().asFile().getPath());
-                               }
-                               upfile.renameTo(export.getTo().asFile());
+                               moveFile(upfile, export.getTo().asFile());
                        } else {
                                // If an attachment with this extension already exists then
                                // replace it by the new one
-                               upfile.renameTo(attach.asFile());
+                               moveFile(upfile,attach.asFile());
                                // Update attached file modification date
                                attach.setDate(new Date());
                        }
@@ -791,10 +1075,6 @@ public class ScenarioServiceImpl implements ScenarioService {
                        NotApplicableException {
                // Attach the file to the created document
                java.io.File updir = newPub.getSourceFile().asFile();
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("Moving \"" + upfile.getName() + "\" to \""
-                                       + updir.getPath() + "\".");
-               }
                if (updir.exists()) {
                        if (updir.delete()) {
                                LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
@@ -802,18 +1082,17 @@ public class ScenarioServiceImpl implements ScenarioService {
                        } else {
                                throw new IOException(
                                                "Can't delete the existing destination file to move file from "
-                                                               + upfile.getAbsolutePath() + " to "
+                                                               + upfile.getAbsolutePath() + TO
                                                                + updir.getAbsolutePath());
                        }
                }
-               if (upfile.renameTo(updir)) {
+               if (moveFile(upfile, updir)) {
                        // Save the new publication in the scenario.
                        // The old publication is removed from the scenario here.
                        getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
                } else {
                        throw new IOException("Can't move file from "
-                                       + upfile.getAbsolutePath() + " to "
-                                       + updir.getAbsolutePath());
+                                       + upfile.getAbsolutePath() + TO + updir.getAbsolutePath());
                }
        }
 
@@ -1345,4 +1624,83 @@ public class ScenarioServiceImpl implements ScenarioService {
                _roleDAO = roleDAO;
        }
 
+       /**
+        * Get the simulationContextTypeService.
+        * 
+        * @return the simulationContextTypeService
+        */
+       public SimulationContextTypeService getSimulationContextTypeService() {
+               return _simulationContextTypeService;
+       }
+
+       /**
+        * Set the simulationContextTypeService.
+        * 
+        * @param simulationContextTypeService
+        *            the simulationContextTypeService to set
+        */
+       public void setSimulationContextTypeService(
+                       final SimulationContextTypeService simulationContextTypeService) {
+               _simulationContextTypeService = simulationContextTypeService;
+       }
+
+       /**
+        * Get the validationCycleDAO.
+        * 
+        * @return the validationCycleDAO
+        */
+       public ValidationCycleDAO getValidationCycleDAO() {
+               return _validationCycleDAO;
+       }
+
+       /**
+        * Set the validationCycleDAO.
+        * 
+        * @param validationCycleDAO
+        *            the validationCycleDAO to set
+        */
+       public void setValidationCycleDAO(
+                       final ValidationCycleDAO validationCycleDAO) {
+               _validationCycleDAO = validationCycleDAO;
+       }
+
+       /**
+        * Get steps config.
+        * 
+        * @return steps config service
+        */
+       private StepsConfigService getStepsConfigService() {
+               return _stepsConfigService;
+       }
+
+       /**
+        * Set steps config service.
+        * 
+        * @param stepsConfigService
+        *            steps config service
+        */
+       public void setStepsConfigService(
+                       final StepsConfigService stepsConfigService) {
+               _stepsConfigService = stepsConfigService;
+       }
+
+       /**
+        * Get the repositoryService.
+        * 
+        * @return the repositoryService
+        */
+       public RepositoryService getRepositoryService() {
+               return _repositoryService;
+       }
+
+       /**
+        * Set the repositoryService.
+        * 
+        * @param repositoryService
+        *            the repositoryService to set
+        */
+       public void setRepositoryService(final RepositoryService repositoryService) {
+               _repositoryService = repositoryService;
+       }
+
 }