1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
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;
60 * Step service implementation.
62 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
64 public class StepServiceImpl implements StepService {
67 * logger for the service.
69 public final static AppLogger LOG = AppLogger
70 .getLogger(StepServiceImpl.class);
72 * Injected index service.
74 private IndexService _indexService;
76 * Injected document service.
78 private DocumentService _documentService;
80 * Injected document type service.
82 private DocumentTypeService _documentTypeService;
84 * Injected document DAO.
86 private DocumentDAO _documentDAO;
88 * Injected relation DAO.
90 private RelationDAO _relationDAO;
94 private FileDAO _fileDAO;
96 * Injected simulation context service.
98 private SimulationContextService _simulationContextService;
100 * Injected simulation context DAO.
102 private SimulationContextDAO _simulationContextDAO;
104 * Injected project element DAO.
106 private ProjectElementDAO _projectElementDAO;
108 * Injected versions relation DAO.
110 private VersionsRelationDAO _versionsRelationDAO;
112 * Injected project service.
114 private ProjectSettingsService _projectSettings;
116 * Injected publication DAO.
118 private PublicationDAO _publicationDAO;
121 * Injected text attribute DAO.
123 private StepCommentAttributeDAO _stepCommentAttributeDAO;
128 private UserDAO _userDAO;
134 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
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
143 return addSimulationContext(aStep, context);
149 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
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()) {
159 if (!context.isSaved()) {
160 getSimulationContextDAO().create(context);
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);
167 } catch (Exception error) {
168 LOG.debug(error.getMessage(), error);
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
180 * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
183 * the step (activity)
185 private void updateKnowledgeElementsIndex(final Step aStep) {
187 if (aStep.getOwner() instanceof Scenario) {
188 scenarii = new Scenario[1];
189 scenarii[0] = (Scenario) aStep.getOwner();
191 scenarii = aStep.getOwnerStudy().getScenarii();
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
199 KnowledgeElement kelm = j.next();
200 getIndexService().update(kelm);
202 updateScenarioIndex(scene);
204 } catch (Exception error) {
205 LOG.error("Unable to re-index Knowledge Elements, reason:", error);
210 * Update lucene index for knowledge elements of the scenario.
214 * @throws IOException
215 * if can't update lucene index
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")) {
225 scene.setUcase(kelm);
229 getIndexService().update(scene.getUcase());
235 * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
239 public boolean removeSimulationContext(final Step aStep,
240 final SimulationContext context) {
241 SimulationContext torem = aStep
242 .getSimulationContext(context.getIndex());
244 boolean isOk = (torem != null) && (aStep.getOwner().remove(torem));
247 aStep.getContex().remove(torem);
248 getProjectElementDAO().update(aStep.getOwner());
249 if (torem.isShared()) {
250 getSimulationContextService().release(torem);
251 getSimulationContextDAO().update(torem);
253 getSimulationContextDAO().delete(torem);
262 * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
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());
273 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
274 .setStep(aStep.getStep()));
275 getDocumentService().generateDocumentId(newdoc, dprop);
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");
284 // Identification and save
285 if (LOG.isDebugEnabled()) {
286 LOG.debug("Local index after: "
287 + aStep.getOwnerStudy().getLastLocalIndex());
289 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
290 getDocumentDAO().create(newdoc);
292 return new Publication(newdoc, aStep.getOwner());
298 * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
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;
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());
319 * Create a new version of a document in the given study step.
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
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());
344 * Create a new version of a document in the given study step.
349 * the base document published version
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
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));
373 * Create a new version of a document in the given study step.
378 * the base document published version
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
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();
401 // RKV: Keep the new file format if it is related to the same document type on this step.
402 String newFormat = dprop.getFormat();
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();
410 if (newFormat != null
411 /*&& previous.getType().equals(
412 getProjectSettings().getDefaultDocumentType(
413 aStep.getStep(), newFormat))*/) {
414 dprop.setFormat(newFormat);
417 if (dprop.getAuthor() == null) {
418 dprop.setAuthor(previous.getAuthor());
420 String summary = dprop.getDescription();
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(),
428 getDocumentDAO().create(newdoc);
431 VersionsRelation aRel;
432 aRel = new VersionsRelation(newdoc, previous, summary);
433 // getVersionsRelationDAO().create(aRel);
434 newdoc.addRelation(aRel);
436 // Update of usedby relations, if exist
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); } }
443 return new Publication(newdoc, aStep.getOwner());
447 * Get document types which are applicable for the given study step (activity).
451 * @return the list of document types
454 public List<DocumentType> getValidDocumentTypes(final Step aStep) {
455 return getDocumentTypeService().selectTypesOf(aStep.getStep());
459 * Add a document publication to the given step.
462 * the target study step
464 * the document publication to add
465 * @return true if publication succeeded
468 public boolean add(final Step aStep, final Publication newdoc) {
469 boolean res = aStep.getOwner().add(newdoc); // Updates the study in memory
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).
480 * Remove a document publication from the given step.
485 * the document publication to remove
486 * @return true if removing of the publication succeeded
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.
499 * Remove a document from the given step and from the database if it is no more used.
505 * @return true if removing of the document succeeded
506 * @throws DocumentIsUsedException
507 * if the document is used by other documents
511 public boolean removeDocument(final Step aStep, final long docId)
512 throws DocumentIsUsedException {
513 Publication torem = aStep.getDocument(docId);
514 boolean res = (torem != null);
516 if (!torem.value().getRelations(UsedByRelation.class).isEmpty()) {
517 throw new DocumentIsUsedException(torem.value().getTitle());
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());
531 // Remove relations from depending documents
532 if (LOG.isDebugEnabled()) {
533 LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
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());
542 doc.removeRelation(UsedByRelation.class, value);
543 if (LOG.isDebugEnabled()) {
544 LOG.debug("Nb relations of doc " + doc.getTitle()
545 + " after: " + doc.getAllRelations().size());
547 getDocumentDAO().merge(doc);
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
568 * @see org.splat.service.StepService#addComment(org.splat.som.Step, org.splat.dal.bo.som.CommentAttribute)
572 public void addStepComment(final StepCommentDTO comment) throws InvalidParameterException {
574 if(comment.getId()!= null) {
575 throw new InvalidParameterException("id", String.valueOf(comment.getId()));
577 User user = getUserDAO().get(comment.getUserId());
579 throw new InvalidParameterException("userId", String.valueOf(comment.getUserId()));
581 ProjectElement projectElement = getProjectElementDAO().get(comment.getProjectElementId());
582 if (projectElement==null) {
583 throw new InvalidParameterException("projectElementId", comment.getProjectElementId().toString());
585 if(comment.getStep() == null || comment.getStep()<0) {
586 throw new InvalidParameterException("step", String.valueOf(comment.getStep()));
588 if(comment.getDate() == null) {
589 throw new InvalidParameterException("date", String.valueOf(comment.getDate()));
591 if(comment.getTitle() == null) {
592 throw new InvalidParameterException("title", String.valueOf(comment.getTitle()));
595 StepCommentAttribute newComment = new StepCommentAttribute(
604 Long resultKey=getStepCommentAttributeDAO().create(newComment);
605 comment.setId(resultKey);
610 * @see org.splat.service.StepService#getStepComments(org.splat.som.Step)
613 @Transactional(readOnly = true)
614 public List<StepCommentDTO> getStepComments(final Step step) throws InvalidParameterException {
615 ProjectElement owner = _projectElementDAO.get(step.getOwner().getRid());
617 throw new InvalidParameterException("step owner id",
618 Long.valueOf(step.getOwner().getRid()).toString());
620 List<StepCommentAttribute> comments = _stepCommentAttributeDAO.getFilteredList(
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);
636 * @see org.splat.service.StepService#removeStepComment(long)
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));
645 _stepCommentAttributeDAO.delete(stepComment);
650 * @see org.splat.service.StepService#editStepComment(long, java.lang.String, java.lang.String)
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));
660 if(newTitle != null) {
661 comment.setTitle(newTitle);
663 if(newValue != null) {
664 comment.setValue(newValue);
666 _stepCommentAttributeDAO.update(comment);
671 * @see org.splat.service.StepService#isCommentMadeByUser(long, long)
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));
681 return comment.getUser().getIndex() == userId;
685 * Get the documentService.
687 * @return the documentService
689 public DocumentService getDocumentService() {
690 return _documentService;
694 * Set the documentService.
696 * @param documentService
697 * the documentService to set
699 public void setDocumentService(final DocumentService documentService) {
700 _documentService = documentService;
704 * Get the simulationContextService.
706 * @return the simulationContextService
708 public SimulationContextService getSimulationContextService() {
709 return _simulationContextService;
713 * Set the simulationContextService.
715 * @param simulationContextService
716 * the simulationContextService to set
718 public void setSimulationContextService(
719 final SimulationContextService simulationContextService) {
720 _simulationContextService = simulationContextService;
724 * Get the documentDAO.
726 * @return the documentDAO
728 public DocumentDAO getDocumentDAO() {
733 * Set the documentDAO.
736 * the documentDAO to set
738 public void setDocumentDAO(final DocumentDAO documentDAO) {
739 _documentDAO = documentDAO;
743 * Get the simulationContextDAO.
745 * @return the simulationContextDAO
747 public SimulationContextDAO getSimulationContextDAO() {
748 return _simulationContextDAO;
752 * Set the simulationContextDAO.
754 * @param simulationContextDAO
755 * the simulationContextDAO to set
757 public void setSimulationContextDAO(
758 final SimulationContextDAO simulationContextDAO) {
759 _simulationContextDAO = simulationContextDAO;
763 * Get the projectElementDAO.
765 * @return the projectElementDAO
767 public ProjectElementDAO getProjectElementDAO() {
768 return _projectElementDAO;
772 * Set the projectElementDAO.
774 * @param projectElementDAO
775 * the projectElementDAO to set
777 public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
778 _projectElementDAO = projectElementDAO;
782 * Get the indexService.
784 * @return the indexService
786 public IndexService getIndexService() {
787 return _indexService;
791 * Set the indexService.
793 * @param indexService
794 * the indexService to set
796 public void setIndexService(final IndexService indexService) {
797 _indexService = indexService;
803 * @return the fileDAO
805 public FileDAO getFileDAO() {
815 public void setFileDAO(final FileDAO fileDAO) {
820 * Get the documentTypeService.
822 * @return the documentTypeService
824 public DocumentTypeService getDocumentTypeService() {
825 return _documentTypeService;
829 * Set the documentTypeService.
831 * @param documentTypeService
832 * the documentTypeService to set
834 public void setDocumentTypeService(
835 final DocumentTypeService documentTypeService) {
836 _documentTypeService = documentTypeService;
840 * Get the versionsRelationDAO.
842 * @return the versionsRelationDAO
844 public VersionsRelationDAO getVersionsRelationDAO() {
845 return _versionsRelationDAO;
849 * Set the versionsRelationDAO.
851 * @param versionsRelationDAO
852 * the versionsRelationDAO to set
854 public void setVersionsRelationDAO(
855 final VersionsRelationDAO versionsRelationDAO) {
856 _versionsRelationDAO = versionsRelationDAO;
860 * Get project settings.
862 * @return Project settings service
864 private ProjectSettingsService getProjectSettings() {
865 return _projectSettings;
869 * Set project settings service.
871 * @param projectSettingsService
872 * project settings service
874 public void setProjectSettings(
875 final ProjectSettingsService projectSettingsService) {
876 _projectSettings = projectSettingsService;
880 * Get the stepCommentAttributeDAO.
881 * @return the stepCommentAttributeDAO
883 public StepCommentAttributeDAO getStepCommentAttributeDAO() {
884 return _stepCommentAttributeDAO;
888 * Set the stepCommentAttributeDAO.
889 * @param commentAttributeDAO the stepCommentAttributeDAO to set
891 public void setStepCommentAttributeDAO(
892 final StepCommentAttributeDAO commentAttributeDAO) {
893 _stepCommentAttributeDAO = commentAttributeDAO;
898 * @return the userDAO
900 public UserDAO getUserDAO() {
905 * @param userDAO the userDAO to set
907 public void setUserDAO(final UserDAO userDAO) {
912 * Get the publicationDAO.
914 * @return the publicationDAO
916 public PublicationDAO getPublicationDAO() {
917 return _publicationDAO;
921 * Set the publicationDAO.
923 * @param publicationDAO
924 * the publicationDAO to set
926 public void setPublicationDAO(final PublicationDAO publicationDAO) {
927 this._publicationDAO = publicationDAO;
931 * Get the relationDAO.
933 * @return the relationDAO
935 public RelationDAO getRelationDAO() {
940 * Set the relationDAO.
943 * the relationDAO to set
945 public void setRelationDAO(final RelationDAO relationDAO) {
946 _relationDAO = relationDAO;