Salome HOME
Show and Edit description functionalities are implemented
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StepServiceImpl.java
index 934b29682797e9ec6cd932545dbef15426eeca77..af8ffcb90112268733c14743203b04d3f23f9c81 100644 (file)
@@ -13,9 +13,10 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
+import org.hibernate.criterion.Restrictions;
 import org.splat.dal.bo.kernel.Relation;
+import org.splat.dal.bo.kernel.User;
 import org.splat.dal.bo.som.ConvertsRelation;
 import org.splat.dal.bo.som.Document;
 import org.splat.dal.bo.som.DocumentType;
@@ -25,26 +26,36 @@ 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;
+import org.splat.dal.bo.som.StepCommentAttribute;
 import org.splat.dal.bo.som.UsedByRelation;
 import org.splat.dal.bo.som.UsesRelation;
 import org.splat.dal.bo.som.VersionsRelation;
+import org.splat.dal.dao.kernel.RelationDAO;
+import org.splat.dal.dao.kernel.UserDAO;
 import org.splat.dal.dao.som.DocumentDAO;
 import org.splat.dal.dao.som.FileDAO;
 import org.splat.dal.dao.som.ProjectElementDAO;
+import org.splat.dal.dao.som.PublicationDAO;
 import org.splat.dal.dao.som.SimulationContextDAO;
+import org.splat.dal.dao.som.StepCommentAttributeDAO;
 import org.splat.dal.dao.som.VersionsRelationDAO;
+import org.splat.exception.DocumentIsUsedException;
+import org.splat.exception.InvalidParameterException;
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MismatchException;
 import org.splat.kernel.MissedPropertyException;
 import org.splat.kernel.MultiplyDefinedException;
 import org.splat.kernel.NotApplicableException;
 import org.splat.log.AppLogger;
+import org.splat.service.dto.StepCommentDTO;
 import org.splat.service.technical.IndexService;
 import org.splat.service.technical.ProjectSettingsService;
 import org.splat.som.Revision;
 import org.splat.som.Step;
+import org.splat.util.BeanHelper;
 import org.springframework.transaction.annotation.Transactional;
 
+
 /**
  * Step service implementation.
  * 
@@ -73,6 +84,10 @@ public class StepServiceImpl implements StepService {
         * Injected document DAO.
         */
        private DocumentDAO _documentDAO;
+       /**
+        * Injected relation DAO.
+        */
+       private RelationDAO _relationDAO;
        /**
         * Injected file DAO.
         */
@@ -97,15 +112,32 @@ public class StepServiceImpl implements StepService {
         * Injected project service.
         */
        private ProjectSettingsService _projectSettings;
+       /**
+        * Injected publication DAO.
+        */
+       private PublicationDAO _publicationDAO;
+
+       /**
+        * Injected text attribute DAO.
+        */
+       private StepCommentAttributeDAO _stepCommentAttributeDAO;
 
+       /**
+        * Injected user DAO.
+        */
+       private UserDAO _userDAO;
+       
+       
        /**
         * {@inheritDoc}
         * 
         * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
         */
+       @Override
        public SimulationContext addSimulationContext(final Step aStep,
-                       final SimulationContext.Properties dprop) throws MissedPropertyException,
-                       InvalidPropertyException, MultiplyDefinedException {
+                       final SimulationContext.Properties dprop)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException {
                SimulationContext context = new SimulationContext(dprop.setStep(aStep
                                .getStep()));
                return addSimulationContext(aStep, context);
@@ -116,6 +148,7 @@ public class StepServiceImpl implements StepService {
         * 
         * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
         */
+       @Override
        @Transactional
        public SimulationContext addSimulationContext(final Step aStep,
                        final SimulationContext context) {
@@ -169,8 +202,7 @@ public class StepServiceImpl implements StepService {
                                updateScenarioIndex(scene);
                        }
                } catch (Exception error) {
-                       LOG.error("Unable to re-index Knowledge Elements, reason:",
-                                       error);
+                       LOG.error("Unable to re-index Knowledge Elements, reason:", error);
                }
        }
 
@@ -202,8 +234,10 @@ public class StepServiceImpl implements StepService {
         * 
         * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
         */
+       @Override
        @Transactional
-       public boolean removeSimulationContext(final Step aStep, final SimulationContext context) {
+       public boolean removeSimulationContext(final Step aStep,
+                       final SimulationContext context) {
                SimulationContext torem = aStep
                                .getSimulationContext(context.getIndex());
 
@@ -227,10 +261,15 @@ public class StepServiceImpl implements StepService {
         * 
         * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
         */
+       @Override
        @Transactional
-       public Publication createDocument(final Step aStep, final Document.Properties dprop)
-                       throws MissedPropertyException, InvalidPropertyException,
-                       MultiplyDefinedException, IOException {
+       public Publication createDocument(final Step aStep,
+                       final Document.Properties dprop) throws MissedPropertyException,
+                       InvalidPropertyException, MultiplyDefinedException, IOException {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Local index before: "
+                                       + aStep.getOwnerStudy().getLastLocalIndex());
+               }
                Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
                                .setStep(aStep.getStep()));
                getDocumentService().generateDocumentId(newdoc, dprop);
@@ -243,6 +282,10 @@ public class StepServiceImpl implements StepService {
                }
 
                // Identification and save
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Local index after: "
+                                       + aStep.getOwnerStudy().getLastLocalIndex());
+               }
                getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
                getDocumentDAO().create(newdoc);
 
@@ -254,6 +297,7 @@ public class StepServiceImpl implements StepService {
         * 
         * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
         */
+       @Override
        public Publication assignDocument(final Step aStep,
                        final Document.Properties dprop) throws MissedPropertyException,
                        InvalidPropertyException, NotApplicableException {
@@ -317,10 +361,10 @@ public class StepServiceImpl implements StepService {
         * @throws MismatchException
         *             if the document is not applicable to the given study step
         */
-       public Publication versionDocument(final Step aStep, final Publication base,
-                       final String reason) throws MissedPropertyException,
-                       InvalidPropertyException, MultiplyDefinedException, IOException,
-                       MismatchException {
+       public Publication versionDocument(final Step aStep,
+                       final Publication base, final String reason)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException, MismatchException {
                return versionDocument(aStep, base, new Document.Properties()
                                .setDescription(reason));
        }
@@ -346,18 +390,30 @@ public class StepServiceImpl implements StepService {
         * @throws MismatchException
         *             if the document is not applicable to the given study step
         */
+       @Override
        @Transactional
-       public Publication versionDocument(final Step aStep, final Publication base,
-                       final Document.Properties dprop) throws MissedPropertyException,
-                       InvalidPropertyException, MultiplyDefinedException, IOException,
-                       MismatchException {
+       public Publication versionDocument(final Step aStep,
+                       final Publication base, final Document.Properties dprop)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException, MismatchException {
                Document previous = base.value();
 
-               dprop.setDocument(previous, getProjectSettings().getStep(base.getStep().getNumber())); // Initializes the Step property
+               // RKV: Keep the new file format if it is related to the same document type on this step.
+               String newFormat = dprop.getFormat();
+
+               dprop.setDocument(previous, getProjectSettings().getStep(
+                               base.getStep().getNumber())); // Initializes the Step property
                if (dprop.getStep().getNumber() != aStep.getNumber()) {
                        throw new MismatchException();
                }
 
+               if (newFormat != null
+                               /*&& previous.getType().equals(
+                                               getProjectSettings().getDefaultDocumentType(
+                                                               aStep.getStep(), newFormat))*/) {
+                       dprop.setFormat(newFormat);
+               }
+
                if (dprop.getAuthor() == null) {
                        dprop.setAuthor(previous.getAuthor());
                }
@@ -374,24 +430,16 @@ public class StepServiceImpl implements StepService {
                // Versioning
                VersionsRelation aRel;
                aRel = new VersionsRelation(newdoc, previous, summary);
-//             getVersionsRelationDAO().create(aRel);
+               // getVersionsRelationDAO().create(aRel);
                newdoc.addRelation(aRel);
-               
+
                // Update of usedby relations, if exist
-/* RKV: Consider the new version as not used by old dependent documents. 
- * So these documents must be marked as outdated then.
-               List<Relation> relist = previous.getRelations(UsedByRelation.class);
-               Study scope = aStep.getOwnerStudy();
-               for (Iterator<Relation> i = relist.iterator(); i.hasNext();) {
-                       UsedByRelation relation = (UsedByRelation) i.next();
-                       Document relatedoc = relation.getTo();
-                       if (scope.shares(relatedoc)) {
-                               relatedoc.addRelation(new UsesRelation(relatedoc, newdoc));
-                       } else {
-                               relation.moveTo(newdoc);
-                       }
-               }
-*/
+               /*
+                * RKV: Consider the new version as not used by old dependent documents. So these documents must be marked as outdated then. List<Relation>
+                * relist = previous.getRelations(UsedByRelation.class); Study scope = aStep.getOwnerStudy(); for (Iterator<Relation> i =
+                * relist.iterator(); i.hasNext();) { UsedByRelation relation = (UsedByRelation) i.next(); Document relatedoc = relation.getTo(); if
+                * (scope.shares(relatedoc)) { relatedoc.addRelation(new UsesRelation(relatedoc, newdoc)); } else { relation.moveTo(newdoc); } }
+                */
                return new Publication(newdoc, aStep.getOwner());
        }
 
@@ -402,6 +450,7 @@ public class StepServiceImpl implements StepService {
         *            the study step
         * @return the list of document types
         */
+       @Override
        public List<DocumentType> getValidDocumentTypes(final Step aStep) {
                return getDocumentTypeService().selectTypesOf(aStep.getStep());
        }
@@ -415,6 +464,7 @@ public class StepServiceImpl implements StepService {
         *            the document publication to add
         * @return true if publication succeeded
         */
+       @Override
        public boolean add(final Step aStep, final Publication newdoc) {
                boolean res = aStep.getOwner().add(newdoc); // Updates the study in memory
                if (res) {
@@ -435,58 +485,149 @@ public class StepServiceImpl implements StepService {
         *            the document publication to remove
         * @return true if removing of the publication succeeded
         */
+       @Override
        public boolean remove(final Step aStep, final Publication oldoc) {
-               boolean res = aStep.getOwner().remove(oldoc); // Updates the study in memory
-               if (res) {
-                       aStep.getDocuments().remove(oldoc); // Updates this step
-                       ProjectElement owner = aStep.getOwner();
-                       if (owner != null) {
-                               owner.remove(oldoc);
-                       }
-                       getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
-                       // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
-               }
-               return res;
+               aStep.getDocuments().remove(oldoc); // Updates this step
+               aStep.getOwner().remove(oldoc); // remove from the parent project element
+               getProjectElementDAO().merge(aStep.getOwner());
+               getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
+               // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
+               return true;
        }
 
        /**
-        * Remove a document from the given step.
+        * Remove a document from the given step and from the database if it is no more used.
         * 
         * @param aStep
         *            the study step
-        * @param doctag
-        *            the document publication
+        * @param docId
+        *            the document id
         * @return true if removing of the document succeeded
+        * @throws DocumentIsUsedException
+        *             if the document is used by other documents
         */
+       @Override
        @Transactional
-       public boolean removeDocument(final Step aStep, final Publication doctag) {
-               Document value = doctag.value();
-               getDocumentDAO().update(value);
-               Publication torem = aStep.getDocument(value.getIndex());
-
+       public boolean removeDocument(final Step aStep, final long docId)
+                       throws DocumentIsUsedException {
+               Publication torem = aStep.getDocument(docId);
                boolean res = (torem != null);
                if (res) {
+                       if (!torem.value().getRelations(UsedByRelation.class).isEmpty()) {
+                               throw new DocumentIsUsedException(torem.value().getTitle());
+                       }
                        remove(aStep, torem);
-                       getProjectElementDAO().update(aStep.getOwner());
+                       Document value = torem.value();
                        if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
-                               Set<Relation> links = value.getAllRelations(); // Get all relation of the document to remove them
                                List<Document> using = new ArrayList<Document>();
-                               for (Iterator<Relation> i = links.iterator(); i.hasNext();) {
-                                       Relation link = i.next();
+                               List<File> files = new ArrayList<File>();
+                               for (Relation link : value.getAllRelations()) {
                                        if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
-                                               getFileDAO().delete((File) link.getTo()); // The corresponding physical file is not removed from the vault
+                                               files.add((File) link.getTo());
                                        } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
                                                using.add((Document) link.getTo());
                                        }
                                }
-                               for (Iterator<Document> i = using.iterator(); i.hasNext();) {
-                                       i.next().removeRelation(UsedByRelation.class, value); // TODO: RKV: don't use Database.getSession in removeRelation
+                               // Remove relations from depending documents
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
+                               }
+                               for (Document doc : using) {
+                                       if (LOG.isDebugEnabled()) {
+                                               LOG.debug("Remove UsedByRelation from "
+                                                               + doc.getTitle() + " to " + value.getTitle());
+                                               LOG.debug("Nb relations of doc " + doc.getTitle()
+                                                               + " before: " + doc.getAllRelations().size());
+                                       }
+                                       doc.removeRelation(UsedByRelation.class, value);
+                                       if (LOG.isDebugEnabled()) {
+                                               LOG.debug("Nb relations of doc " + doc.getTitle()
+                                                               + " after: " + doc.getAllRelations().size());
+                                       }
+                                       getDocumentDAO().merge(doc);
+                               }
+                               // Synchronize deleted objects with the database to avoid hibernate exception
+                               // org.hibernate.PropertyValueException: not-null property references a null or transient value
+                               getDocumentDAO().flush();
+                               // The corresponding physical file is not removed from the vault
+                               getDocumentDAO().delete(getDocumentDAO().merge(torem.value()));
+                               // Delete document's files
+                               for (File file : files) {
+                                       getFileDAO().delete(getFileDAO().merge(file)); // The corresponding physical file is not removed from the vault
                                }
-                               getDocumentDAO().delete(value); // The corresponding physical file is not removed from the vault
                        }
                }
                return res;
        }
+       
+       /**
+        * {@inheritDoc}
+        *
+        * @see org.splat.service.StepService#addComment(org.splat.som.Step, org.splat.dal.bo.som.CommentAttribute)
+        */
+       @Override
+       @Transactional
+       public void addStepComment(final StepCommentDTO comment) throws InvalidParameterException {
+
+               if(comment.getId()!= null) {
+                       throw new InvalidParameterException("id", String.valueOf(comment.getId()));
+               }
+               User user = getUserDAO().get(comment.getUserId());
+               if (user == null) {
+                       throw new InvalidParameterException("userId", String.valueOf(comment.getUserId()));
+               }
+               ProjectElement projectElement = getProjectElementDAO().get(comment.getProjectElementId());
+               if (projectElement==null) {
+                       throw new InvalidParameterException("projectElementId", comment.getProjectElementId().toString());
+               }
+               if(comment.getStep() == null || comment.getStep()<0) {
+                       throw new InvalidParameterException("step", String.valueOf(comment.getStep()));
+               }
+               if(comment.getDate() == null) {
+                       throw new InvalidParameterException("date", String.valueOf(comment.getDate()));
+               }
+               if(comment.getTitle() == null) {
+                       throw new InvalidParameterException("title", String.valueOf(comment.getTitle()));
+               }
+
+               StepCommentAttribute newComment = new StepCommentAttribute(
+                               projectElement,
+                               comment.getText(),
+                               comment.getDate(),
+                               comment.getStep(),
+                               user,
+                               comment.getTitle()
+                               );
+
+               Long resultKey=getStepCommentAttributeDAO().create(newComment);
+               comment.setId(resultKey);
+       }
+
+       /**
+        * {@inheritDoc}
+        * @see org.splat.service.StepService#getStepComments(org.splat.som.Step)
+        */
+       @Override
+       @Transactional(readOnly = true)
+       public List<StepCommentDTO> getStepComments(final Step step) throws InvalidParameterException {
+               ProjectElement owner = _projectElementDAO.get(step.getOwner().getRid());
+               if(owner == null) {
+                       throw new InvalidParameterException("step owner id",
+                                       Long.valueOf(step.getOwner().getRid()).toString());
+               }
+               List<StepCommentAttribute> comments = _stepCommentAttributeDAO.getFilteredList(
+                               Restrictions.and(
+                                               Restrictions.eq("step", Integer.valueOf(step.getNumber())),
+                                               Restrictions.eq("owner", owner)));
+               List<StepCommentDTO> commentDTOs = new ArrayList<StepCommentDTO>();
+               for(StepCommentAttribute comment : comments) {
+                        StepCommentDTO stepCommentDTO = BeanHelper.copyBean(comment, StepCommentDTO.class);
+                        stepCommentDTO.setText(comment.getValue());
+                        stepCommentDTO.setId(Long.valueOf(comment.getRid()));
+                        commentDTOs.add(stepCommentDTO);
+               }
+               return commentDTOs;
+       }
 
        /**
         * Get the documentService.
@@ -638,12 +779,14 @@ public class StepServiceImpl implements StepService {
         * @param documentTypeService
         *            the documentTypeService to set
         */
-       public void setDocumentTypeService(final DocumentTypeService documentTypeService) {
+       public void setDocumentTypeService(
+                       final DocumentTypeService documentTypeService) {
                _documentTypeService = documentTypeService;
        }
 
        /**
         * Get the versionsRelationDAO.
+        * 
         * @return the versionsRelationDAO
         */
        public VersionsRelationDAO getVersionsRelationDAO() {
@@ -652,9 +795,12 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the versionsRelationDAO.
-        * @param versionsRelationDAO the versionsRelationDAO to set
+        * 
+        * @param versionsRelationDAO
+        *            the versionsRelationDAO to set
         */
-       public void setVersionsRelationDAO(final VersionsRelationDAO versionsRelationDAO) {
+       public void setVersionsRelationDAO(
+                       final VersionsRelationDAO versionsRelationDAO) {
                _versionsRelationDAO = versionsRelationDAO;
        }
 
@@ -666,7 +812,7 @@ public class StepServiceImpl implements StepService {
        private ProjectSettingsService getProjectSettings() {
                return _projectSettings;
        }
-
+       
        /**
         * Set project settings service.
         * 
@@ -677,4 +823,74 @@ public class StepServiceImpl implements StepService {
                        final ProjectSettingsService projectSettingsService) {
                _projectSettings = projectSettingsService;
        }
+       
+       /**
+        * Get the stepCommentAttributeDAO.
+        * @return the stepCommentAttributeDAO
+        */
+       public StepCommentAttributeDAO getStepCommentAttributeDAO() {
+               return _stepCommentAttributeDAO;
+       }
+
+       /**
+        * Set the stepCommentAttributeDAO.
+        * @param commentAttributeDAO the stepCommentAttributeDAO to set
+        */
+       public void setStepCommentAttributeDAO(
+                       final StepCommentAttributeDAO commentAttributeDAO) {
+               _stepCommentAttributeDAO = commentAttributeDAO;
+       }
+
+       /**
+        * Get the userDAO.
+        * @return the userDAO
+        */
+       public UserDAO getUserDAO() {
+               return _userDAO;
+       }
+       /**
+        * Set the userDAO.
+        * @param userDAO the userDAO to set
+        */
+       public void setUserDAO(final UserDAO userDAO) {
+               _userDAO = userDAO;
+       }
+
+       /**
+        * Get the publicationDAO.
+        * 
+        * @return the publicationDAO
+        */
+       public PublicationDAO getPublicationDAO() {
+               return _publicationDAO;
+       }
+
+       /**
+        * Set the publicationDAO.
+        * 
+        * @param publicationDAO
+        *            the publicationDAO to set
+        */
+       public void setPublicationDAO(final PublicationDAO publicationDAO) {
+               this._publicationDAO = publicationDAO;
+       }
+
+       /**
+        * Get the relationDAO.
+        * 
+        * @return the relationDAO
+        */
+       public RelationDAO getRelationDAO() {
+               return _relationDAO;
+       }
+
+       /**
+        * Set the relationDAO.
+        * 
+        * @param relationDAO
+        *            the relationDAO to set
+        */
+       public void setRelationDAO(final RelationDAO relationDAO) {
+               _relationDAO = relationDAO;
+       }
 }