]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java
Salome HOME
Compare method signature and DocToCompareDTO are added.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StepServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   06.10.2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package org.splat.service;
11
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16
17 import org.hibernate.criterion.Restrictions;
18 import org.splat.dal.bo.kernel.Relation;
19 import org.splat.dal.bo.kernel.User;
20 import org.splat.dal.bo.som.ConvertsRelation;
21 import org.splat.dal.bo.som.Document;
22 import org.splat.dal.bo.som.DocumentType;
23 import org.splat.dal.bo.som.File;
24 import org.splat.dal.bo.som.KnowledgeElement;
25 import org.splat.dal.bo.som.ProjectElement;
26 import org.splat.dal.bo.som.Publication;
27 import org.splat.dal.bo.som.Scenario;
28 import org.splat.dal.bo.som.SimulationContext;
29 import org.splat.dal.bo.som.StepCommentAttribute;
30 import org.splat.dal.bo.som.UsedByRelation;
31 import org.splat.dal.bo.som.UsesRelation;
32 import org.splat.dal.bo.som.VersionsRelation;
33 import org.splat.dal.dao.kernel.RelationDAO;
34 import org.splat.dal.dao.kernel.UserDAO;
35 import org.splat.dal.dao.som.DocumentDAO;
36 import org.splat.dal.dao.som.FileDAO;
37 import org.splat.dal.dao.som.ProjectElementDAO;
38 import org.splat.dal.dao.som.PublicationDAO;
39 import org.splat.dal.dao.som.SimulationContextDAO;
40 import org.splat.dal.dao.som.StepCommentAttributeDAO;
41 import org.splat.dal.dao.som.VersionsRelationDAO;
42 import org.splat.exception.DocumentIsUsedException;
43 import org.splat.exception.InvalidParameterException;
44 import org.splat.kernel.InvalidPropertyException;
45 import org.splat.kernel.MismatchException;
46 import org.splat.kernel.MissedPropertyException;
47 import org.splat.kernel.MultiplyDefinedException;
48 import org.splat.kernel.NotApplicableException;
49 import org.splat.log.AppLogger;
50 import org.splat.service.dto.StepCommentDTO;
51 import org.splat.service.technical.IndexService;
52 import org.splat.service.technical.ProjectSettingsService;
53 import org.splat.som.Revision;
54 import org.splat.som.Step;
55 import org.splat.util.BeanHelper;
56 import org.springframework.transaction.annotation.Transactional;
57
58
59 /**
60  * Step service implementation.
61  *
62  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
63  */
64 public class StepServiceImpl implements StepService {
65
66         /**
67          * logger for the service.
68          */
69         public final static AppLogger LOG = AppLogger
70                         .getLogger(StepServiceImpl.class);
71         /**
72          * Injected index service.
73          */
74         private IndexService _indexService;
75         /**
76          * Injected document service.
77          */
78         private DocumentService _documentService;
79         /**
80          * Injected document type service.
81          */
82         private DocumentTypeService _documentTypeService;
83         /**
84          * Injected document DAO.
85          */
86         private DocumentDAO _documentDAO;
87         /**
88          * Injected relation DAO.
89          */
90         private RelationDAO _relationDAO;
91         /**
92          * Injected file DAO.
93          */
94         private FileDAO _fileDAO;
95         /**
96          * Injected simulation context service.
97          */
98         private SimulationContextService _simulationContextService;
99         /**
100          * Injected simulation context DAO.
101          */
102         private SimulationContextDAO _simulationContextDAO;
103         /**
104          * Injected project element DAO.
105          */
106         private ProjectElementDAO _projectElementDAO;
107         /**
108          * Injected versions relation DAO.
109          */
110         private VersionsRelationDAO _versionsRelationDAO;
111         /**
112          * Injected project service.
113          */
114         private ProjectSettingsService _projectSettings;
115         /**
116          * Injected publication DAO.
117          */
118         private PublicationDAO _publicationDAO;
119
120         /**
121          * Injected text attribute DAO.
122          */
123         private StepCommentAttributeDAO _stepCommentAttributeDAO;
124
125         /**
126          * Injected user DAO.
127          */
128         private UserDAO _userDAO;
129
130
131         /**
132          * {@inheritDoc}
133          *
134          * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
135          */
136         @Override
137         public SimulationContext addSimulationContext(final Step aStep,
138                         final SimulationContext.Properties dprop)
139                         throws MissedPropertyException, InvalidPropertyException,
140                         MultiplyDefinedException {
141                 SimulationContext context = new SimulationContext(dprop.setStep(aStep
142                                 .getStep()));
143                 return addSimulationContext(aStep, context);
144         }
145
146         /**
147          * {@inheritDoc}
148          *
149          * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
150          */
151         @Override
152         @Transactional
153         public SimulationContext addSimulationContext(final Step aStep,
154                         final SimulationContext context) {
155                 SimulationContext res = null;
156                 getSimulationContextService().hold(context); // Increments the reference count of simulation context
157                 if (aStep.getOwner().isSaved()) {
158                         try {
159                                 if (!context.isSaved()) {
160                                         getSimulationContextDAO().create(context);
161                                 }
162                                 aStep.getOwner().add(context);
163                                 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
164                                 getProjectElementDAO().update(aStep.getOwner());
165                                 updateKnowledgeElementsIndex(aStep);
166                                 res = context;
167                         } catch (Exception error) {
168                                 LOG.debug(error.getMessage(), error);
169                         }
170                 } else { // Happens when copying a scenario
171                         aStep.getOwner().add(context);
172                         aStep.getContex().add(context); // The context is also referenced from this (transient) Step
173                         // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
174                         res = context;
175                 }
176                 return res;
177         }
178
179         /**
180          * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
181          *
182          * @param aStep
183          *            the step (activity)
184          */
185         private void updateKnowledgeElementsIndex(final Step aStep) {
186                 Scenario[] scenarii;
187                 if (aStep.getOwner() instanceof Scenario) {
188                         scenarii = new Scenario[1];
189                         scenarii[0] = (Scenario) aStep.getOwner();
190                 } else {
191                         scenarii = aStep.getOwnerStudy().getScenarii();
192                 }
193                 try {
194                         for (int i = 0; i < scenarii.length; i++) {
195                                 Scenario scene = scenarii[i];
196                                 List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
197                                 for (Iterator<KnowledgeElement> j = knelm.iterator(); j
198                                                 .hasNext();) {
199                                         KnowledgeElement kelm = j.next();
200                                         getIndexService().update(kelm);
201                                 }
202                                 updateScenarioIndex(scene);
203                         }
204                 } catch (Exception error) {
205                         LOG.error("Unable to re-index Knowledge Elements, reason:", error);
206                 }
207         }
208
209         /**
210          * Update lucene index for knowledge elements of the scenario.
211          *
212          * @param scene
213          *            the scenario
214          * @throws IOException
215          *             if can't update lucene index
216          */
217         private void updateScenarioIndex(final Scenario scene) throws IOException {
218                 if (scene.getUcase() == null) {
219                         for (Iterator<KnowledgeElement> i = scene.getKnowledgeElements()
220                                         .iterator(); i.hasNext();) {
221                                 KnowledgeElement kelm = i.next();
222                                 if (!kelm.getType().equals("usecase")) {
223                                         continue;
224                                 }
225                                 scene.setUcase(kelm);
226                                 break;
227                         }
228                 }
229                 getIndexService().update(scene.getUcase());
230         }
231
232         /**
233          * {@inheritDoc}
234          *
235          * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
236          */
237         @Override
238         @Transactional
239         public boolean removeSimulationContext(final Step aStep,
240                         final SimulationContext context) {
241                 SimulationContext torem = aStep
242                                 .getSimulationContext(context.getIndex());
243
244                 boolean isOk = (torem != null) && (aStep.getOwner().remove(torem));
245                 if (isOk) {
246
247                         aStep.getContex().remove(torem);
248                         getProjectElementDAO().update(aStep.getOwner());
249                         if (torem.isShared()) {
250                                 getSimulationContextService().release(torem);
251                                 getSimulationContextDAO().update(torem);
252                         } else {
253                                 getSimulationContextDAO().delete(torem);
254                         }
255                 }
256                 return isOk;
257         }
258
259         /**
260          * {@inheritDoc}
261          *
262          * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
263          */
264         @Override
265         @Transactional
266         public Publication createDocument(final Step aStep,
267                         final Document.Properties dprop) throws MissedPropertyException,
268                         InvalidPropertyException, MultiplyDefinedException, IOException {
269                 if (LOG.isDebugEnabled()) {
270                         LOG.debug("Local index before: "
271                                         + aStep.getOwnerStudy().getLastLocalIndex());
272                 }
273                 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
274                                 .setStep(aStep.getStep()));
275                 getDocumentService().generateDocumentId(newdoc, dprop);
276
277                 // Creation of the save directory
278                 java.io.File wdir = getDocumentService().getSaveDirectory(newdoc);
279                 if ((!wdir.exists()) && (!wdir.mkdirs())) {
280                         throw new IOException(
281                                         "Cannot create the repository vault directory");
282                 }
283
284                 // Identification and save
285                 if (LOG.isDebugEnabled()) {
286                         LOG.debug("Local index after: "
287                                         + aStep.getOwnerStudy().getLastLocalIndex());
288                 }
289                 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
290                 getDocumentDAO().create(newdoc);
291
292                 return new Publication(newdoc, aStep.getOwner());
293         }
294
295         /**
296          * {@inheritDoc}
297          *
298          * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
299          */
300         @Override
301         public Publication assignDocument(final Step aStep,
302                         final Document.Properties dprop) throws MissedPropertyException,
303                         InvalidPropertyException, NotApplicableException {
304                 String refid = dprop.getReference();
305                 Publication res = null;
306                 if (refid != null) {
307                         Document slot = getDocumentService().selectDocument(refid,
308                                         new Revision().toString());
309                         if ((slot != null) && (slot.isUndefined())) {
310                                 getDocumentService().initialize(slot,
311                                                 dprop.setOwner(aStep.getOwnerStudy()));
312                                 res = new Publication(slot, aStep.getOwner());
313                         }
314                 }
315                 return res;
316         }
317
318         /**
319          * Create a new version of a document in the given study step.
320          *
321          * @param aStep
322          *            the study step
323          * @param base
324          *            the base document published version
325          * @return the new version publication
326          * @throws MissedPropertyException
327          *             if a mandatory property is missed
328          * @throws InvalidPropertyException
329          *             if some property doesn't exist
330          * @throws MultiplyDefinedException
331          *             if some property is defined several times
332          * @throws IOException
333          *             if a file system error occurs
334          * @throws MismatchException
335          *             if the document is not applicable to the given study step
336          */
337         public Publication versionDocument(final Step aStep, final Publication base)
338                         throws MissedPropertyException, InvalidPropertyException,
339                         MultiplyDefinedException, IOException, MismatchException {
340                 return versionDocument(aStep, base, new Document.Properties());
341         }
342
343         /**
344          * Create a new version of a document in the given study step.
345          *
346          * @param aStep
347          *            the study step
348          * @param base
349          *            the base document published version
350          * @param reason
351          *            the comment for the new version
352          * @return the new version publication
353          * @throws MissedPropertyException
354          *             if a mandatory property is missed
355          * @throws InvalidPropertyException
356          *             if some property doesn't exist
357          * @throws MultiplyDefinedException
358          *             if some property is defined several times
359          * @throws IOException
360          *             if a file system error occurs
361          * @throws MismatchException
362          *             if the document is not applicable to the given study step
363          */
364         public Publication versionDocument(final Step aStep,
365                         final Publication base, final String reason)
366                         throws MissedPropertyException, InvalidPropertyException,
367                         MultiplyDefinedException, IOException, MismatchException {
368                 return versionDocument(aStep, base, new Document.Properties()
369                                 .setDescription(reason));
370         }
371
372         /**
373          * Create a new version of a document in the given study step.
374          *
375          * @param aStep
376          *            the study step
377          * @param base
378          *            the base document published version
379          * @param dprop
380          *            properties of the new version
381          * @return the new version publication
382          * @throws MissedPropertyException
383          *             if a mandatory property is missed
384          * @throws InvalidPropertyException
385          *             if some property doesn't exist
386          * @throws MultiplyDefinedException
387          *             if some property is defined several times
388          * @throws IOException
389          *             if a file system error occurs
390          * @throws MismatchException
391          *             if the document is not applicable to the given study step
392          */
393         @Override
394         @Transactional
395         public Publication versionDocument(final Step aStep,
396                         final Publication base, final Document.Properties dprop)
397                         throws MissedPropertyException, InvalidPropertyException,
398                         MultiplyDefinedException, IOException, MismatchException {
399                 Document previous = base.value();
400
401                 // RKV: Keep the new file format if it is related to the same document type on this step.
402                 String newFormat = dprop.getFormat();
403
404                 dprop.setDocument(previous, getProjectSettings().getStep(
405                                 base.getStep().getNumber())); // Initializes the Step property
406                 if (dprop.getStep().getNumber() != aStep.getNumber()) {
407                         throw new MismatchException();
408                 }
409
410                 if (newFormat != null
411                                 /*&& previous.getType().equals(
412                                                 getProjectSettings().getDefaultDocumentType(
413                                                                 aStep.getStep(), newFormat))*/) {
414                         dprop.setFormat(newFormat);
415                 }
416
417                 if (dprop.getAuthor() == null) {
418                         dprop.setAuthor(previous.getAuthor());
419                 }
420                 String summary = dprop.getDescription();
421
422                 // Creation of the document
423                 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
424                                 .setStep(aStep.getStep()));
425                 getDocumentService().generateDocumentId(newdoc, dprop);
426                 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwner(),
427                                 previous);
428                 getDocumentDAO().create(newdoc);
429
430                 // Versioning
431                 VersionsRelation aRel;
432                 aRel = new VersionsRelation(newdoc, previous, summary);
433                 // getVersionsRelationDAO().create(aRel);
434                 newdoc.addRelation(aRel);
435
436                 // Update of usedby relations, if exist
437                 /*
438                  * RKV: Consider the new version as not used by old dependent documents. So these documents must be marked as outdated then. List<Relation>
439                  * relist = previous.getRelations(UsedByRelation.class); Study scope = aStep.getOwnerStudy(); for (Iterator<Relation> i =
440                  * relist.iterator(); i.hasNext();) { UsedByRelation relation = (UsedByRelation) i.next(); Document relatedoc = relation.getTo(); if
441                  * (scope.shares(relatedoc)) { relatedoc.addRelation(new UsesRelation(relatedoc, newdoc)); } else { relation.moveTo(newdoc); } }
442                  */
443                 return new Publication(newdoc, aStep.getOwner());
444         }
445
446         /**
447          * Get document types which are applicable for the given study step (activity).
448          *
449          * @param aStep
450          *            the study step
451          * @return the list of document types
452          */
453         @Override
454         public List<DocumentType> getValidDocumentTypes(final Step aStep) {
455                 return getDocumentTypeService().selectTypesOf(aStep.getStep());
456         }
457
458         /**
459          * Add a document publication to the given step.
460          *
461          * @param aStep
462          *            the target study step
463          * @param newdoc
464          *            the document publication to add
465          * @return true if publication succeeded
466          */
467         @Override
468         public boolean add(final Step aStep, final Publication newdoc) {
469                 boolean res = aStep.getOwner().add(newdoc); // Updates the study in memory
470                 if (res) {
471                         aStep.getDocuments().add(0, newdoc); // Updates this step
472                         getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
473                         // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
474                         // database (it will be saved later by cascading the update of owner scenario).
475                 }
476                 return res;
477         }
478
479         /**
480          * Remove a document publication from the given step.
481          *
482          * @param aStep
483          *            the study step
484          * @param oldoc
485          *            the document publication to remove
486          * @return true if removing of the publication succeeded
487          */
488         @Override
489         public boolean remove(final Step aStep, final Publication oldoc) {
490                 aStep.getDocuments().remove(oldoc); // Updates this step
491                 aStep.getOwner().remove(oldoc); // remove from the parent project element
492                 getProjectElementDAO().merge(aStep.getOwner());
493                 getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
494                 // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
495                 return true;
496         }
497
498         /**
499          * Remove a document from the given step and from the database if it is no more used.
500          * 
501          * @param aStep
502          *            the study step
503          * @param docId
504          *            the document id
505          * @return true if removing of the document succeeded
506          * @throws DocumentIsUsedException
507          *             if the document is used by other documents
508          */
509         @Override
510         @Transactional
511         public boolean removeDocument(final Step aStep, final long docId)
512                         throws DocumentIsUsedException {
513                 Publication torem = aStep.getDocument(docId);
514                 boolean res = (torem != null);
515                 if (res) {
516                         if (!torem.value().getRelations(UsedByRelation.class).isEmpty()) {
517                                 throw new DocumentIsUsedException(torem.value().getTitle());
518                         }
519                         remove(aStep, torem);
520                         Document value = torem.value();
521                         if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
522                                 List<Document> using = new ArrayList<Document>();
523                                 List<File> files = new ArrayList<File>();
524                                 for (Relation link : value.getAllRelations()) {
525                                         if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
526                                                 files.add((File) link.getTo());
527                                         } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
528                                                 using.add((Document) link.getTo());
529                                         }
530                                 }
531                                 // Remove relations from depending documents
532                                 if (LOG.isDebugEnabled()) {
533                                         LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
534                                 }
535                                 for (Document doc : using) {
536                                         if (LOG.isDebugEnabled()) {
537                                                 LOG.debug("Remove UsedByRelation from "
538                                                                 + doc.getTitle() + " to " + value.getTitle());
539                                                 LOG.debug("Nb relations of doc " + doc.getTitle()
540                                                                 + " before: " + doc.getAllRelations().size());
541                                         }
542                                         doc.removeRelation(UsedByRelation.class, value);
543                                         if (LOG.isDebugEnabled()) {
544                                                 LOG.debug("Nb relations of doc " + doc.getTitle()
545                                                                 + " after: " + doc.getAllRelations().size());
546                                         }
547                                         getDocumentDAO().merge(doc);
548                                 }
549                                 // Synchronize deleted objects with the database to avoid hibernate exception
550                                 // org.hibernate.PropertyValueException: not-null property references a null or transient value
551                                 getDocumentDAO().flush();
552                                 // The corresponding physical file is not removed from the vault
553                                 getDocumentDAO().delete(getDocumentDAO().merge(torem.value()));
554                                 // Delete document's files
555                                 for (File file : files) {
556                                         getFileDAO().delete(getFileDAO().merge(file)); // The corresponding physical file is not removed from the vault
557                                 }
558                         }
559                 }
560                 return res;
561
562
563         }
564
565         /**
566          * {@inheritDoc}
567          *
568          * @see org.splat.service.StepService#addComment(org.splat.som.Step, org.splat.dal.bo.som.CommentAttribute)
569          */
570         @Override
571         @Transactional
572         public void addStepComment(final StepCommentDTO comment) throws InvalidParameterException {
573
574                 if(comment.getId()!= null) {
575                         throw new InvalidParameterException("id", String.valueOf(comment.getId()));
576                 }
577                 User user = getUserDAO().get(comment.getUserId());
578                 if (user == null) {
579                         throw new InvalidParameterException("userId", String.valueOf(comment.getUserId()));
580                 }
581                 ProjectElement projectElement = getProjectElementDAO().get(comment.getProjectElementId());
582                 if (projectElement==null) {
583                         throw new InvalidParameterException("projectElementId", comment.getProjectElementId().toString());
584                 }
585                 if(comment.getStep() == null || comment.getStep()<0) {
586                         throw new InvalidParameterException("step", String.valueOf(comment.getStep()));
587                 }
588                 if(comment.getDate() == null) {
589                         throw new InvalidParameterException("date", String.valueOf(comment.getDate()));
590                 }
591                 if(comment.getTitle() == null) {
592                         throw new InvalidParameterException("title", String.valueOf(comment.getTitle()));
593                 }
594
595                 StepCommentAttribute newComment = new StepCommentAttribute(
596                                 projectElement,
597                                 comment.getText(),
598                                 comment.getDate(),
599                                 comment.getStep(),
600                                 user,
601                                 comment.getTitle()
602                                 );
603
604                 Long resultKey=getStepCommentAttributeDAO().create(newComment);
605                 comment.setId(resultKey);
606         }
607
608         /** 
609          * {@inheritDoc}
610          * @see org.splat.service.StepService#getStepComments(org.splat.som.Step)
611          */
612         @Override
613         @Transactional(readOnly = true)
614         public List<StepCommentDTO> getStepComments(final Step step) throws InvalidParameterException {
615                 ProjectElement owner = _projectElementDAO.get(step.getOwner().getRid());
616                 if(owner == null) {
617                         throw new InvalidParameterException("step owner id",
618                                         Long.valueOf(step.getOwner().getRid()).toString());
619                 }
620                 List<StepCommentAttribute> comments = _stepCommentAttributeDAO.getFilteredList(
621                                 Restrictions.and(
622                                                 Restrictions.eq("step", Integer.valueOf(step.getNumber())),
623                                                 Restrictions.eq("owner", owner)));
624                 List<StepCommentDTO> commentDTOs = new ArrayList<StepCommentDTO>();
625                 for(StepCommentAttribute comment : comments) {
626                          StepCommentDTO stepCommentDTO = BeanHelper.copyBean(comment, StepCommentDTO.class);
627                          stepCommentDTO.setText(comment.getValue());
628                          stepCommentDTO.setId(Long.valueOf(comment.getRid()));
629                          commentDTOs.add(stepCommentDTO);
630                 }
631                 return commentDTOs;
632         }
633         
634         /** 
635          * {@inheritDoc}
636          * @see org.splat.service.StepService#removeStepComment(long)
637          */
638         @Override
639         @Transactional
640         public void removeStepComment(final long commentId) throws InvalidParameterException {
641                 StepCommentAttribute stepComment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
642                 if(stepComment == null) {
643                         throw new InvalidParameterException("commentId",String.valueOf(commentId));
644                 }
645                 _stepCommentAttributeDAO.delete(stepComment);
646         }
647
648         /** 
649          * {@inheritDoc}
650          * @see org.splat.service.StepService#editStepComment(long, java.lang.String, java.lang.String)
651          */
652         @Override
653         @Transactional
654         public void editStepComment(final long commentId, final String newValue, final String newTitle)
655                         throws InvalidParameterException {
656                 StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
657                 if(comment == null) {
658                         throw new InvalidParameterException("commentId",String.valueOf(commentId));
659                 }
660                 if(newTitle != null) {
661                         comment.setTitle(newTitle);
662                 }
663                 if(newValue != null) {
664                         comment.setValue(newValue);
665                 }
666                 _stepCommentAttributeDAO.update(comment);
667         }
668
669         /** 
670          * {@inheritDoc}
671          * @see org.splat.service.StepService#isCommentMadeByUser(long, long)
672          */
673         @Override
674         @Transactional(readOnly = true)
675         public boolean isCommentMadeByUser(final long commentId, final long userId)
676                         throws InvalidParameterException {
677                 StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long.valueOf(commentId));
678                 if(comment == null) {
679                         throw new InvalidParameterException("commentId", String.valueOf(commentId));
680                 }
681                 return comment.getUser().getIndex() == userId;
682         }
683         
684         /**
685          * Get the documentService.
686          *
687          * @return the documentService
688          */
689         public DocumentService getDocumentService() {
690                 return _documentService;
691         }
692
693         /**
694          * Set the documentService.
695          *
696          * @param documentService
697          *            the documentService to set
698          */
699         public void setDocumentService(final DocumentService documentService) {
700                 _documentService = documentService;
701         }
702
703         /**
704          * Get the simulationContextService.
705          *
706          * @return the simulationContextService
707          */
708         public SimulationContextService getSimulationContextService() {
709                 return _simulationContextService;
710         }
711
712         /**
713          * Set the simulationContextService.
714          *
715          * @param simulationContextService
716          *            the simulationContextService to set
717          */
718         public void setSimulationContextService(
719                         final SimulationContextService simulationContextService) {
720                 _simulationContextService = simulationContextService;
721         }
722
723         /**
724          * Get the documentDAO.
725          *
726          * @return the documentDAO
727          */
728         public DocumentDAO getDocumentDAO() {
729                 return _documentDAO;
730         }
731
732         /**
733          * Set the documentDAO.
734          *
735          * @param documentDAO
736          *            the documentDAO to set
737          */
738         public void setDocumentDAO(final DocumentDAO documentDAO) {
739                 _documentDAO = documentDAO;
740         }
741
742         /**
743          * Get the simulationContextDAO.
744          *
745          * @return the simulationContextDAO
746          */
747         public SimulationContextDAO getSimulationContextDAO() {
748                 return _simulationContextDAO;
749         }
750
751         /**
752          * Set the simulationContextDAO.
753          *
754          * @param simulationContextDAO
755          *            the simulationContextDAO to set
756          */
757         public void setSimulationContextDAO(
758                         final SimulationContextDAO simulationContextDAO) {
759                 _simulationContextDAO = simulationContextDAO;
760         }
761
762         /**
763          * Get the projectElementDAO.
764          *
765          * @return the projectElementDAO
766          */
767         public ProjectElementDAO getProjectElementDAO() {
768                 return _projectElementDAO;
769         }
770
771         /**
772          * Set the projectElementDAO.
773          *
774          * @param projectElementDAO
775          *            the projectElementDAO to set
776          */
777         public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
778                 _projectElementDAO = projectElementDAO;
779         }
780
781         /**
782          * Get the indexService.
783          *
784          * @return the indexService
785          */
786         public IndexService getIndexService() {
787                 return _indexService;
788         }
789
790         /**
791          * Set the indexService.
792          *
793          * @param indexService
794          *            the indexService to set
795          */
796         public void setIndexService(final IndexService indexService) {
797                 _indexService = indexService;
798         }
799
800         /**
801          * Get the fileDAO.
802          *
803          * @return the fileDAO
804          */
805         public FileDAO getFileDAO() {
806                 return _fileDAO;
807         }
808
809         /**
810          * Set the fileDAO.
811          *
812          * @param fileDAO
813          *            the fileDAO to set
814          */
815         public void setFileDAO(final FileDAO fileDAO) {
816                 _fileDAO = fileDAO;
817         }
818
819         /**
820          * Get the documentTypeService.
821          *
822          * @return the documentTypeService
823          */
824         public DocumentTypeService getDocumentTypeService() {
825                 return _documentTypeService;
826         }
827
828         /**
829          * Set the documentTypeService.
830          *
831          * @param documentTypeService
832          *            the documentTypeService to set
833          */
834         public void setDocumentTypeService(
835                         final DocumentTypeService documentTypeService) {
836                 _documentTypeService = documentTypeService;
837         }
838
839         /**
840          * Get the versionsRelationDAO.
841          *
842          * @return the versionsRelationDAO
843          */
844         public VersionsRelationDAO getVersionsRelationDAO() {
845                 return _versionsRelationDAO;
846         }
847
848         /**
849          * Set the versionsRelationDAO.
850          *
851          * @param versionsRelationDAO
852          *            the versionsRelationDAO to set
853          */
854         public void setVersionsRelationDAO(
855                         final VersionsRelationDAO versionsRelationDAO) {
856                 _versionsRelationDAO = versionsRelationDAO;
857         }
858
859         /**
860          * Get project settings.
861          *
862          * @return Project settings service
863          */
864         private ProjectSettingsService getProjectSettings() {
865                 return _projectSettings;
866         }
867
868         /**
869          * Set project settings service.
870          *
871          * @param projectSettingsService
872          *            project settings service
873          */
874         public void setProjectSettings(
875                         final ProjectSettingsService projectSettingsService) {
876                 _projectSettings = projectSettingsService;
877         }
878
879         /**
880          * Get the stepCommentAttributeDAO.
881          * @return the stepCommentAttributeDAO
882          */
883         public StepCommentAttributeDAO getStepCommentAttributeDAO() {
884                 return _stepCommentAttributeDAO;
885         }
886
887         /**
888          * Set the stepCommentAttributeDAO.
889          * @param commentAttributeDAO the stepCommentAttributeDAO to set
890          */
891         public void setStepCommentAttributeDAO(
892                         final StepCommentAttributeDAO commentAttributeDAO) {
893                 _stepCommentAttributeDAO = commentAttributeDAO;
894         }
895
896         /**
897          * Get the userDAO.
898          * @return the userDAO
899          */
900         public UserDAO getUserDAO() {
901                 return _userDAO;
902         }
903         /**
904          * Set the userDAO.
905          * @param userDAO the userDAO to set
906          */
907         public void setUserDAO(final UserDAO userDAO) {
908                 _userDAO = userDAO;
909         }
910         
911         /**
912          * Get the publicationDAO.
913          * 
914          * @return the publicationDAO
915          */
916         public PublicationDAO getPublicationDAO() {
917                 return _publicationDAO;
918         }
919
920         /**
921          * Set the publicationDAO.
922          * 
923          * @param publicationDAO
924          *            the publicationDAO to set
925          */
926         public void setPublicationDAO(final PublicationDAO publicationDAO) {
927                 this._publicationDAO = publicationDAO;
928         }
929
930         /**
931          * Get the relationDAO.
932          * 
933          * @return the relationDAO
934          */
935         public RelationDAO getRelationDAO() {
936                 return _relationDAO;
937         }
938
939         /**
940          * Set the relationDAO.
941          * 
942          * @param relationDAO
943          *            the relationDAO to set
944          */
945         public void setRelationDAO(final RelationDAO relationDAO) {
946                 _relationDAO = relationDAO;
947         }
948 }