Salome HOME
Compare method signature and DocToCompareDTO are added.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StepServiceImpl.java
index ea57a734c421fad5e72bda09f79c839284d15fe8..9e94849f9ffb93169ff9266b9c90f2a3a089075c 100644 (file)
 package org.splat.service;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
-import java.util.Vector;
 
+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;
 import org.splat.dal.bo.som.File;
 import org.splat.dal.bo.som.KnowledgeElement;
+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.Study;
+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.
- * 
+ *
  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
  */
 public class StepServiceImpl implements StepService {
@@ -55,7 +66,7 @@ public class StepServiceImpl implements StepService {
        /**
         * logger for the service.
         */
-       public final static AppLogger logger = AppLogger
+       public final static AppLogger LOG = AppLogger
                        .getLogger(StepServiceImpl.class);
        /**
         * Injected index service.
@@ -73,6 +84,10 @@ public class StepServiceImpl implements StepService {
         * Injected document DAO.
         */
        private DocumentDAO _documentDAO;
+       /**
+        * Injected relation DAO.
+        */
+       private RelationDAO _relationDAO;
        /**
         * Injected file DAO.
         */
@@ -96,16 +111,33 @@ public class StepServiceImpl implements StepService {
        /**
         * Injected project service.
         */
-       private ProjectSettingsService _projectSettingsService;
+       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);
@@ -113,12 +145,14 @@ public class StepServiceImpl implements StepService {
 
        /**
         * {@inheritDoc}
-        * 
+        *
         * @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) {
+               SimulationContext res = null;
                getSimulationContextService().hold(context); // Increments the reference count of simulation context
                if (aStep.getOwner().isSaved()) {
                        try {
@@ -129,20 +163,22 @@ public class StepServiceImpl implements StepService {
                                aStep.getContex().add(context); // The context is also referenced from this (transient) Step
                                getProjectElementDAO().update(aStep.getOwner());
                                updateKnowledgeElementsIndex(aStep);
+                               res = context;
                        } catch (Exception error) {
-                               return null;
+                               LOG.debug(error.getMessage(), error);
                        }
                } else { // Happens when copying a scenario
                        aStep.getOwner().add(context);
                        aStep.getContex().add(context); // The context is also referenced from this (transient) Step
                        // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
+                       res = context;
                }
-               return context;
+               return res;
        }
 
        /**
         * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
-        * 
+        *
         * @param aStep
         *            the step (activity)
         */
@@ -166,14 +202,13 @@ public class StepServiceImpl implements StepService {
                                updateScenarioIndex(scene);
                        }
                } catch (Exception error) {
-                       logger.error("Unable to re-index Knowledge Elements, reason:",
-                                       error);
+                       LOG.error("Unable to re-index Knowledge Elements, reason:", error);
                }
        }
 
        /**
         * Update lucene index for knowledge elements of the scenario.
-        * 
+        *
         * @param scene
         *            the scenario
         * @throws IOException
@@ -196,16 +231,18 @@ public class StepServiceImpl implements StepService {
 
        /**
         * {@inheritDoc}
-        * 
+        *
         * @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) {
-               boolean isOk = false;
+       public boolean removeSimulationContext(final Step aStep,
+                       final SimulationContext context) {
                SimulationContext torem = aStep
                                .getSimulationContext(context.getIndex());
 
-               if ((torem != null) && (aStep.getOwner().remove(torem))) {
+               boolean isOk = (torem != null) && (aStep.getOwner().remove(torem));
+               if (isOk) {
 
                        aStep.getContex().remove(torem);
                        getProjectElementDAO().update(aStep.getOwner());
@@ -215,34 +252,40 @@ public class StepServiceImpl implements StepService {
                        } else {
                                getSimulationContextDAO().delete(torem);
                        }
-                       isOk = true;
                }
                return isOk;
        }
 
        /**
         * {@inheritDoc}
-        * 
+        *
         * @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);
 
                // Creation of the save directory
                java.io.File wdir = getDocumentService().getSaveDirectory(newdoc);
-               if (!wdir.exists()) {
-                       if (!wdir.mkdirs()) {
-                               throw new IOException(
-                                               "Cannot create the repository vault directory");
-                       }
+               if ((!wdir.exists()) && (!wdir.mkdirs())) {
+                       throw new IOException(
+                                       "Cannot create the repository vault directory");
                }
 
                // Identification and save
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Local index after: "
+                                       + aStep.getOwnerStudy().getLastLocalIndex());
+               }
                getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
                getDocumentDAO().create(newdoc);
 
@@ -251,34 +294,30 @@ public class StepServiceImpl implements StepService {
 
        /**
         * {@inheritDoc}
-        * 
+        *
         * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
         */
-       public Publication assignDocument(final Step aStep, final Document.Properties dprop)
-                       throws MissedPropertyException, InvalidPropertyException,
-                       NotApplicableException {
+       @Override
+       public Publication assignDocument(final Step aStep,
+                       final Document.Properties dprop) throws MissedPropertyException,
+                       InvalidPropertyException, NotApplicableException {
                String refid = dprop.getReference();
-               if (refid == null) {
-                       return null;
-               }
-
-               Document slot = getDocumentService().selectDocument(refid,
-                               new Revision().toString());
-               if (slot == null) {
-                       return null;
-               }
-               if (!slot.isUndefined()) {
-                       return null; // Should not happen
+               Publication res = null;
+               if (refid != null) {
+                       Document slot = getDocumentService().selectDocument(refid,
+                                       new Revision().toString());
+                       if ((slot != null) && (slot.isUndefined())) {
+                               getDocumentService().initialize(slot,
+                                               dprop.setOwner(aStep.getOwnerStudy()));
+                               res = new Publication(slot, aStep.getOwner());
+                       }
                }
-
-               getDocumentService().initialize(slot,
-                               dprop.setOwner(aStep.getOwnerStudy()));
-               return new Publication(slot, aStep.getOwner());
+               return res;
        }
 
        /**
         * Create a new version of a document in the given study step.
-        * 
+        *
         * @param aStep
         *            the study step
         * @param base
@@ -303,7 +342,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Create a new version of a document in the given study step.
-        * 
+        *
         * @param aStep
         *            the study step
         * @param base
@@ -322,17 +361,17 @@ 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));
        }
 
        /**
         * Create a new version of a document in the given study step.
-        * 
+        *
         * @param aStep
         *            the study step
         * @param base
@@ -351,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());
                }
@@ -379,117 +430,260 @@ 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
-               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());
        }
 
        /**
         * Get document types which are applicable for the given study step (activity).
-        * 
+        *
         * @param aStep
         *            the study step
         * @return the list of document types
         */
+       @Override
        public List<DocumentType> getValidDocumentTypes(final Step aStep) {
                return getDocumentTypeService().selectTypesOf(aStep.getStep());
        }
 
        /**
         * Add a document publication to the given step.
-        * 
+        *
         * @param aStep
         *            the target study step
         * @param newdoc
         *            the document publication to add
         * @return true if publication succeeded
         */
+       @Override
        public boolean add(final Step aStep, final Publication newdoc) {
-               if (!aStep.getOwner().add(newdoc)) {
-                       return false; // Updates the study in memory
+               boolean res = aStep.getOwner().add(newdoc); // Updates the study in memory
+               if (res) {
+                       aStep.getDocuments().add(0, newdoc); // Updates this step
+                       getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
+                       // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
+                       // database (it will be saved later by cascading the update of owner scenario).
                }
-               aStep.getDocuments().add(0, newdoc); // Updates this step
-               getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
-               // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
-               // database (it will be saved later by cascading the update of owner scenario).
-               return true;
+               return res;
        }
 
        /**
         * Remove a document publication from the given step.
-        * 
+        *
         * @param aStep
         *            the study step
         * @param oldoc
         *            the document publication to remove
         * @return true if removing of the publication succeeded
         */
+       @Override
        public boolean remove(final Step aStep, final Publication oldoc) {
-               if (!aStep.getOwner().remove(oldoc)) {
-                       return false; // Updates the study in memory
-               }
                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);
+                       Document value = torem.value();
+                       if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
+                               List<Document> using = new ArrayList<Document>();
+                               List<File> files = new ArrayList<File>();
+                               for (Relation link : value.getAllRelations()) {
+                                       if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
+                                               files.add((File) link.getTo());
+                                       } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
+                                               using.add((Document) link.getTo());
+                                       }
+                               }
+                               // 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
+                               }
+                       }
+               }
+               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 (torem == null) {
-                       return false;
+               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()));
                }
 
-               remove(aStep, torem);
-               getProjectElementDAO().update(aStep.getOwner());
-               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 Vector<Document>();
-                       for (Iterator<Relation> i = links.iterator(); i.hasNext();) {
-                               Relation link = i.next();
-                               if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
-                                       getFileDAO().delete((File) link.getTo()); // The corresponding physical file is not removed from the vault
-                               } 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
-                       }
-                       getDocumentDAO().delete(value); // The corresponding physical file is not removed from the vault
+               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());
                }
-               return true;
+               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;
+       }
+       
+       /** 
+        * {@inheritDoc}
+        * @see org.splat.service.StepService#removeStepComment(long)
+        */
+       @Override
+       @Transactional
+       public void removeStepComment(final long commentId) throws InvalidParameterException {
+               StepCommentAttribute stepComment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
+               if(stepComment == null) {
+                       throw new InvalidParameterException("commentId",String.valueOf(commentId));
+               }
+               _stepCommentAttributeDAO.delete(stepComment);
+       }
+
+       /** 
+        * {@inheritDoc}
+        * @see org.splat.service.StepService#editStepComment(long, java.lang.String, java.lang.String)
+        */
+       @Override
+       @Transactional
+       public void editStepComment(final long commentId, final String newValue, final String newTitle)
+                       throws InvalidParameterException {
+               StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
+               if(comment == null) {
+                       throw new InvalidParameterException("commentId",String.valueOf(commentId));
+               }
+               if(newTitle != null) {
+                       comment.setTitle(newTitle);
+               }
+               if(newValue != null) {
+                       comment.setValue(newValue);
+               }
+               _stepCommentAttributeDAO.update(comment);
        }
 
+       /** 
+        * {@inheritDoc}
+        * @see org.splat.service.StepService#isCommentMadeByUser(long, long)
+        */
+       @Override
+       @Transactional(readOnly = true)
+       public boolean isCommentMadeByUser(final long commentId, final long userId)
+                       throws InvalidParameterException {
+               StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
+               if(comment == null) {
+                       throw new InvalidParameterException("commentId", String.valueOf(commentId));
+               }
+               return comment.getUser().getIndex() == userId;
+       }
+       
        /**
         * Get the documentService.
-        * 
+        *
         * @return the documentService
         */
        public DocumentService getDocumentService() {
@@ -498,7 +692,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the documentService.
-        * 
+        *
         * @param documentService
         *            the documentService to set
         */
@@ -508,7 +702,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the simulationContextService.
-        * 
+        *
         * @return the simulationContextService
         */
        public SimulationContextService getSimulationContextService() {
@@ -517,7 +711,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the simulationContextService.
-        * 
+        *
         * @param simulationContextService
         *            the simulationContextService to set
         */
@@ -528,7 +722,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the documentDAO.
-        * 
+        *
         * @return the documentDAO
         */
        public DocumentDAO getDocumentDAO() {
@@ -537,7 +731,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the documentDAO.
-        * 
+        *
         * @param documentDAO
         *            the documentDAO to set
         */
@@ -547,7 +741,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the simulationContextDAO.
-        * 
+        *
         * @return the simulationContextDAO
         */
        public SimulationContextDAO getSimulationContextDAO() {
@@ -556,7 +750,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the simulationContextDAO.
-        * 
+        *
         * @param simulationContextDAO
         *            the simulationContextDAO to set
         */
@@ -567,7 +761,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the projectElementDAO.
-        * 
+        *
         * @return the projectElementDAO
         */
        public ProjectElementDAO getProjectElementDAO() {
@@ -576,7 +770,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the projectElementDAO.
-        * 
+        *
         * @param projectElementDAO
         *            the projectElementDAO to set
         */
@@ -586,7 +780,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the indexService.
-        * 
+        *
         * @return the indexService
         */
        public IndexService getIndexService() {
@@ -595,7 +789,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the indexService.
-        * 
+        *
         * @param indexService
         *            the indexService to set
         */
@@ -605,7 +799,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the fileDAO.
-        * 
+        *
         * @return the fileDAO
         */
        public FileDAO getFileDAO() {
@@ -614,7 +808,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the fileDAO.
-        * 
+        *
         * @param fileDAO
         *            the fileDAO to set
         */
@@ -624,7 +818,7 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Get the documentTypeService.
-        * 
+        *
         * @return the documentTypeService
         */
        public DocumentTypeService getDocumentTypeService() {
@@ -633,16 +827,18 @@ public class StepServiceImpl implements StepService {
 
        /**
         * Set the documentTypeService.
-        * 
+        *
         * @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() {
@@ -651,29 +847,102 @@ 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;
        }
 
        /**
         * Get project settings.
-        * 
+        *
         * @return Project settings service
         */
        private ProjectSettingsService getProjectSettings() {
-               return _projectSettingsService;
+               return _projectSettings;
        }
 
        /**
         * Set project settings service.
-        * 
+        *
         * @param projectSettingsService
         *            project settings service
         */
        public void setProjectSettings(
                        final ProjectSettingsService projectSettingsService) {
-               _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;
        }
 }