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.List;
16 import org.hibernate.criterion.Restrictions;
17 import org.splat.dal.bo.kernel.Relation;
18 import org.splat.dal.bo.kernel.User;
19 import org.splat.dal.bo.som.ConvertsRelation;
20 import org.splat.dal.bo.som.Document;
21 import org.splat.dal.bo.som.DocumentType;
22 import org.splat.dal.bo.som.File;
23 import org.splat.dal.bo.som.KnowledgeElement;
24 import org.splat.dal.bo.som.ProjectElement;
25 import org.splat.dal.bo.som.Publication;
26 import org.splat.dal.bo.som.Scenario;
27 import org.splat.dal.bo.som.SimulationContext;
28 import org.splat.dal.bo.som.StepCommentAttribute;
29 import org.splat.dal.bo.som.UsedByRelation;
30 import org.splat.dal.bo.som.UsesRelation;
31 import org.splat.dal.bo.som.VersionsRelation;
32 import org.splat.dal.dao.kernel.RelationDAO;
33 import org.splat.dal.dao.kernel.UserDAO;
34 import org.splat.dal.dao.som.DocumentDAO;
35 import org.splat.dal.dao.som.FileDAO;
36 import org.splat.dal.dao.som.ProjectElementDAO;
37 import org.splat.dal.dao.som.PublicationDAO;
38 import org.splat.dal.dao.som.SimulationContextDAO;
39 import org.splat.dal.dao.som.StepCommentAttributeDAO;
40 import org.splat.dal.dao.som.VersionsRelationDAO;
41 import org.splat.exception.DocumentIsUsedException;
42 import org.splat.exception.InvalidParameterException;
43 import org.splat.kernel.InvalidPropertyException;
44 import org.splat.kernel.MismatchException;
45 import org.splat.kernel.MissedPropertyException;
46 import org.splat.kernel.MultiplyDefinedException;
47 import org.splat.kernel.NotApplicableException;
48 import org.splat.log.AppLogger;
49 import org.splat.service.dto.StepCommentDTO;
50 import org.splat.service.technical.IndexService;
51 import org.splat.service.technical.ProjectSettingsService;
52 import org.splat.som.Revision;
53 import org.splat.som.Step;
54 import org.splat.util.BeanHelper;
55 import org.springframework.transaction.annotation.Transactional;
58 * Step service implementation.
60 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
62 public class StepServiceImpl implements StepService {
65 * logger for the service.
67 public final static AppLogger LOG = AppLogger
68 .getLogger(StepServiceImpl.class);
70 * Injected index service.
72 private IndexService _indexService;
74 * Injected document service.
76 private DocumentService _documentService;
78 * Injected document type service.
80 private DocumentTypeService _documentTypeService;
82 * Injected document DAO.
84 private DocumentDAO _documentDAO;
86 * Injected relation DAO.
88 private RelationDAO _relationDAO;
92 private FileDAO _fileDAO;
94 * Injected simulation context service.
96 private SimulationContextService _simulationContextService;
98 * Injected simulation context DAO.
100 private SimulationContextDAO _simulationContextDAO;
102 * Injected project element DAO.
104 private ProjectElementDAO _projectElementDAO;
106 * Injected versions relation DAO.
108 private VersionsRelationDAO _versionsRelationDAO;
110 * Injected project service.
112 private ProjectSettingsService _projectSettings;
114 * Injected publication DAO.
116 private PublicationDAO _publicationDAO;
119 * Injected text attribute DAO.
121 private StepCommentAttributeDAO _stepCommentAttributeDAO;
126 private UserDAO _userDAO;
131 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
134 public SimulationContext addSimulationContext(final Step aStep,
135 final SimulationContext.Properties dprop)
136 throws MissedPropertyException, InvalidPropertyException,
137 MultiplyDefinedException {
138 SimulationContext context = new SimulationContext(dprop.setStep(aStep
140 return addSimulationContext(aStep, context);
146 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
150 public SimulationContext addSimulationContext(final Step aStep,
151 final SimulationContext context) {
152 SimulationContext res = null;
153 getSimulationContextService().hold(context); // Increments the reference count of simulation context
154 if (aStep.getOwner().isSaved()) {
156 if (!context.isSaved()) {
157 getSimulationContextDAO().create(context);
159 aStep.getOwner().add(context);
160 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
161 getProjectElementDAO().update(aStep.getOwner());
162 updateKnowledgeElementsIndex(aStep);
164 } catch (Exception error) {
165 LOG.debug(error.getMessage(), error);
167 } else { // Happens when copying a scenario
168 aStep.getOwner().add(context);
169 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
170 // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
177 * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
180 * the step (activity)
182 private void updateKnowledgeElementsIndex(final Step aStep) {
184 if (aStep.getOwner() instanceof Scenario) {
185 scenarii = new Scenario[1];
186 scenarii[0] = (Scenario) aStep.getOwner();
188 scenarii = aStep.getOwnerStudy().getScenarii();
190 for (int i = 0; i < scenarii.length; i++) {
191 Scenario scene = scenarii[i];
192 updateScenarioIndex(scene);
197 * Update lucene index for knowledge elements of the scenario.
202 private void updateScenarioIndex(final Scenario scene) {
203 if (scene.getUcase() == null) {
204 for (KnowledgeElement kelm : scene.getKnowledgeElements()) {
205 if (kelm.getType().equals("usecase")) {
206 scene.setUcase(kelm);
216 * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
220 public boolean removeSimulationContext(final Step aStep,
221 final SimulationContext context) {
222 SimulationContext torem = aStep
223 .getSimulationContext(context.getIndex());
225 boolean isOk = (torem != null) && (aStep.getOwner().remove(torem));
228 aStep.getContex().remove(torem);
229 getProjectElementDAO().update(aStep.getOwner());
230 if (torem.isShared()) {
231 getSimulationContextService().release(torem);
232 getSimulationContextDAO().update(torem);
234 getSimulationContextDAO().delete(torem);
243 * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
247 public Publication createDocument(final Step aStep,
248 final Document.Properties dprop) throws MissedPropertyException,
249 InvalidPropertyException, MultiplyDefinedException, IOException {
250 if (LOG.isDebugEnabled()) {
251 LOG.debug("Local index before: "
252 + aStep.getOwnerStudy().getLastLocalIndex());
254 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
255 .setStep(aStep.getStep()));
256 getDocumentService().generateDocumentId(newdoc, dprop);
258 // Creation of the save directory
259 java.io.File wdir = getDocumentService().getSaveDirectory(newdoc);
260 if ((!wdir.exists()) && (!wdir.mkdirs())) {
261 throw new IOException(
262 "Cannot create the repository vault directory");
265 // Identification and save
266 if (LOG.isDebugEnabled()) {
267 LOG.debug("Local index after: "
268 + aStep.getOwnerStudy().getLastLocalIndex());
270 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
271 getDocumentDAO().create(newdoc);
273 return new Publication(newdoc, aStep.getOwner());
279 * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
282 public Publication assignDocument(final Step aStep,
283 final Document.Properties dprop) throws MissedPropertyException,
284 InvalidPropertyException, NotApplicableException {
285 String refid = dprop.getReference();
286 Publication res = null;
288 Document slot = getDocumentService().selectDocument(refid,
289 new Revision().toString());
290 if ((slot != null) && (slot.isUndefined())) {
291 getDocumentService().initialize(slot,
292 dprop.setOwner(aStep.getOwnerStudy()));
293 res = new Publication(slot, aStep.getOwner());
300 * Create a new version of a document in the given study step.
305 * the base document published version
306 * @return the new version publication
307 * @throws MissedPropertyException
308 * if a mandatory property is missed
309 * @throws InvalidPropertyException
310 * if some property doesn't exist
311 * @throws MultiplyDefinedException
312 * if some property is defined several times
313 * @throws IOException
314 * if a file system error occurs
315 * @throws MismatchException
316 * if the document is not applicable to the given study step
318 public Publication versionDocument(final Step aStep, final Publication base)
319 throws MissedPropertyException, InvalidPropertyException,
320 MultiplyDefinedException, IOException, MismatchException {
321 return versionDocument(aStep, base, new Document.Properties());
325 * Create a new version of a document in the given study step.
330 * the base document published version
332 * the comment for the new version
333 * @return the new version publication
334 * @throws MissedPropertyException
335 * if a mandatory property is missed
336 * @throws InvalidPropertyException
337 * if some property doesn't exist
338 * @throws MultiplyDefinedException
339 * if some property is defined several times
340 * @throws IOException
341 * if a file system error occurs
342 * @throws MismatchException
343 * if the document is not applicable to the given study step
345 public Publication versionDocument(final Step aStep,
346 final Publication base, final String reason)
347 throws MissedPropertyException, InvalidPropertyException,
348 MultiplyDefinedException, IOException, MismatchException {
349 return versionDocument(aStep, base, new Document.Properties()
350 .setDescription(reason));
354 * Create a new version of a document in the given study step.
359 * the base document published version
361 * properties of the new version
362 * @return the new version publication
363 * @throws MissedPropertyException
364 * if a mandatory property is missed
365 * @throws InvalidPropertyException
366 * if some property doesn't exist
367 * @throws MultiplyDefinedException
368 * if some property is defined several times
369 * @throws IOException
370 * if a file system error occurs
371 * @throws MismatchException
372 * if the document is not applicable to the given study step
375 public Publication versionDocument(final Step aStep,
376 final Publication base, final Document.Properties dprop)
377 throws MissedPropertyException, InvalidPropertyException,
378 MultiplyDefinedException, IOException, MismatchException {
379 Document previous = base.value();
381 // RKV: Keep the new file format if it is related to the same document type on this step.
382 String newFormat = dprop.getFormat();
384 dprop.setDocument(previous, getProjectSettings().getStep(
385 base.getStep().getNumber())); // Initializes the Step property
386 if (dprop.getStep().getNumber() != aStep.getNumber()) {
387 throw new MismatchException();
390 if (newFormat != null
392 * && previous.getType().equals( getProjectSettings().getDefaultDocumentType( aStep.getStep(), newFormat))
394 dprop.setFormat(newFormat);
397 if (dprop.getAuthor() == null) {
398 dprop.setAuthor(previous.getAuthor());
400 String summary = dprop.getDescription();
402 // Creation of the document
403 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
404 .setStep(aStep.getStep()));
405 getDocumentService().generateDocumentId(newdoc, dprop);
406 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwner(),
408 getDocumentDAO().create(newdoc);
411 VersionsRelation aRel;
412 aRel = new VersionsRelation(newdoc, previous, summary);
413 // getVersionsRelationDAO().create(aRel);
414 newdoc.addRelation(aRel);
416 // Update of usedby relations, if exist
418 * RKV: Consider the new version as not used by old dependent documents. So these documents must be marked as outdated then. List<Relation>
419 * relist = previous.getRelations(UsedByRelation.class); Study scope = aStep.getOwnerStudy(); for (Iterator<Relation> i =
420 * relist.iterator(); i.hasNext();) { UsedByRelation relation = (UsedByRelation) i.next(); Document relatedoc = relation.getTo(); if
421 * (scope.shares(relatedoc)) { relatedoc.addRelation(new UsesRelation(relatedoc, newdoc)); } else { relation.moveTo(newdoc); } }
423 return new Publication(newdoc, aStep.getOwner());
427 * Get document types which are applicable for the given study step (activity).
431 * @return the list of document types
434 public List<DocumentType> getValidDocumentTypes(final Step aStep) {
435 return getDocumentTypeService().selectTypesOf(aStep.getStep());
439 * Add a document publication to the given step.
442 * the target study step
444 * the document publication to add
445 * @return true if publication succeeded
448 public boolean add(final Step aStep, final Publication newdoc) {
449 boolean res = aStep.getOwner().add(newdoc); // Updates the study in memory
451 aStep.getDocuments().add(0, newdoc); // Updates this step
452 getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
453 // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
454 // database (it will be saved later by cascading the update of owner scenario).
460 * Remove a document publication from the given step.
465 * the document publication to remove
466 * @return true if removing of the publication succeeded
469 public boolean remove(final Step aStep, final Publication oldoc) {
470 aStep.getDocuments().remove(oldoc); // Updates this step
471 aStep.getOwner().remove(oldoc); // remove from the parent project element
472 getProjectElementDAO().merge(aStep.getOwner().getOwnerStudy());
473 getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
474 // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
479 * Remove a document from the given step and from the database if it is no more used.
485 * @return true if removing of the document succeeded
486 * @throws DocumentIsUsedException
487 * if the document is used by other documents
491 public boolean removeDocument(final Step aStep, final long docId)
492 throws DocumentIsUsedException {
493 Publication torem = aStep.getDocument(docId);
494 boolean res = (torem != null);
496 if (!torem.value().getRelations(UsedByRelation.class).isEmpty()) {
497 throw new DocumentIsUsedException(torem.value().getTitle());
499 // Remove the document publication from the step
500 remove(aStep, torem);
501 // Republish the previous version if any to avoid it becoming an orphan
502 Document prevVersion = torem.value().getPreviousVersion();
503 if (prevVersion != null) {
504 add(aStep, new Publication(prevVersion, aStep.getOwner()));
505 getProjectElementDAO().merge(aStep.getOwner());
507 // Delete the document if it is no more used
508 Document value = torem.value();
509 if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
510 List<Document> using = new ArrayList<Document>();
511 List<File> files = new ArrayList<File>();
512 files.add(value.getFile()); // To delete the source file physically at the end
513 for (Relation link : value.getAllRelations()) {
514 if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
515 files.add((File) link.getTo());
516 } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
517 using.add((Document) link.getTo());
520 // Remove relations from depending documents
521 if (LOG.isDebugEnabled()) {
522 LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
524 for (Document doc : using) {
525 if (LOG.isDebugEnabled()) {
526 LOG.debug("Remove UsedByRelation from "
527 + doc.getTitle() + " to " + value.getTitle());
528 LOG.debug("Nb relations of doc " + doc.getTitle()
529 + " before: " + doc.getAllRelations().size());
531 doc.removeRelation(UsedByRelation.class, value);
532 if (LOG.isDebugEnabled()) {
533 LOG.debug("Nb relations of doc " + doc.getTitle()
534 + " after: " + doc.getAllRelations().size());
536 getDocumentDAO().merge(doc);
538 // Synchronize deleted objects with the database to avoid hibernate exception
539 // org.hibernate.PropertyValueException: not-null property references a null or transient value
540 getDocumentDAO().flush();
541 // The corresponding physical file is not removed from the vault
542 getDocumentDAO().delete(getDocumentDAO().merge(torem.value()));
543 // Delete document's files
544 // Delete files from file system
545 for (File file : files) {
546 // getFileDAO().delete(getFileDAO().merge(file)); // The corresponding physical file is not removed from the vault
547 LOG.info("Delete the file "
548 + file.asFile().getAbsolutePath());
549 if (file.asFile().delete()) {
550 LOG.info("File " + file.asFile().getAbsolutePath()
551 + " successfully deleted.");
553 LOG.info("File " + file.asFile().getAbsolutePath()
554 + " can not be deleted.");
565 * @see org.splat.service.StepService#addComment(org.splat.som.Step, org.splat.dal.bo.som.CommentAttribute)
569 public void addStepComment(final StepCommentDTO comment)
570 throws InvalidParameterException {
572 if (comment.getId() != null) {
573 throw new InvalidParameterException("id", String.valueOf(comment
576 User user = getUserDAO().get(comment.getUserId());
578 throw new InvalidParameterException("userId", String
579 .valueOf(comment.getUserId()));
581 ProjectElement projectElement = getProjectElementDAO().get(
582 comment.getProjectElementId());
583 if (projectElement == null) {
584 throw new InvalidParameterException("projectElementId", comment
585 .getProjectElementId().toString());
587 if (comment.getStep() == null || comment.getStep() < 0) {
588 throw new InvalidParameterException("step", String.valueOf(comment
591 if (comment.getDate() == null) {
592 throw new InvalidParameterException("date", String.valueOf(comment
595 if (comment.getTitle() == null) {
596 throw new InvalidParameterException("title", String.valueOf(comment
600 StepCommentAttribute newComment = new StepCommentAttribute(
601 projectElement, comment.getText(), comment.getDate(), comment
602 .getStep(), user, comment.getTitle());
604 Long resultKey = getStepCommentAttributeDAO().create(newComment);
605 comment.setId(resultKey);
611 * @see org.splat.service.StepService#getStepComments(org.splat.som.Step)
614 @Transactional(readOnly = true)
615 public List<StepCommentDTO> getStepComments(final Step step)
616 throws InvalidParameterException {
617 ProjectElement owner = _projectElementDAO.get(step.getOwner().getRid());
619 throw new InvalidParameterException("step owner id", Long.valueOf(
620 step.getOwner().getRid()).toString());
622 List<StepCommentAttribute> comments = _stepCommentAttributeDAO
623 .getFilteredList(Restrictions.and(Restrictions.eq("step",
624 Integer.valueOf(step.getNumber())), Restrictions.eq(
626 List<StepCommentDTO> commentDTOs = new ArrayList<StepCommentDTO>();
627 for (StepCommentAttribute comment : comments) {
628 StepCommentDTO stepCommentDTO = BeanHelper.copyBean(comment,
629 StepCommentDTO.class);
630 stepCommentDTO.setText(comment.getValue());
631 stepCommentDTO.setId(Long.valueOf(comment.getRid()));
632 commentDTOs.add(stepCommentDTO);
640 * @see org.splat.service.StepService#removeStepComment(long)
644 public void removeStepComment(final long commentId)
645 throws InvalidParameterException {
646 StepCommentAttribute stepComment = _stepCommentAttributeDAO.get(Long
647 .valueOf(commentId));
648 if (stepComment == null) {
649 throw new InvalidParameterException("commentId", String
650 .valueOf(commentId));
652 _stepCommentAttributeDAO.delete(stepComment);
658 * @see org.splat.service.StepService#editStepComment(long, java.lang.String, java.lang.String)
662 public void editStepComment(final long commentId, final String newValue,
663 final String newTitle) throws InvalidParameterException {
664 StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long
665 .valueOf(commentId));
666 if (comment == null) {
667 throw new InvalidParameterException("commentId", String
668 .valueOf(commentId));
670 if (newTitle != null) {
671 comment.setTitle(newTitle);
673 if (newValue != null) {
674 comment.setValue(newValue);
676 _stepCommentAttributeDAO.update(comment);
682 * @see org.splat.service.StepService#isCommentMadeByUser(long, long)
685 @Transactional(readOnly = true)
686 public boolean isCommentMadeByUser(final long commentId, final long userId)
687 throws InvalidParameterException {
688 StepCommentAttribute comment = _stepCommentAttributeDAO.get(Long
689 .valueOf(commentId));
690 if (comment == null) {
691 throw new InvalidParameterException("commentId", String
692 .valueOf(commentId));
694 return comment.getUser().getIndex() == userId;
698 * Get the documentService.
700 * @return the documentService
702 public DocumentService getDocumentService() {
703 return _documentService;
707 * Set the documentService.
709 * @param documentService
710 * the documentService to set
712 public void setDocumentService(final DocumentService documentService) {
713 _documentService = documentService;
717 * Get the simulationContextService.
719 * @return the simulationContextService
721 public SimulationContextService getSimulationContextService() {
722 return _simulationContextService;
726 * Set the simulationContextService.
728 * @param simulationContextService
729 * the simulationContextService to set
731 public void setSimulationContextService(
732 final SimulationContextService simulationContextService) {
733 _simulationContextService = simulationContextService;
737 * Get the documentDAO.
739 * @return the documentDAO
741 public DocumentDAO getDocumentDAO() {
746 * Set the documentDAO.
749 * the documentDAO to set
751 public void setDocumentDAO(final DocumentDAO documentDAO) {
752 _documentDAO = documentDAO;
756 * Get the simulationContextDAO.
758 * @return the simulationContextDAO
760 public SimulationContextDAO getSimulationContextDAO() {
761 return _simulationContextDAO;
765 * Set the simulationContextDAO.
767 * @param simulationContextDAO
768 * the simulationContextDAO to set
770 public void setSimulationContextDAO(
771 final SimulationContextDAO simulationContextDAO) {
772 _simulationContextDAO = simulationContextDAO;
776 * Get the projectElementDAO.
778 * @return the projectElementDAO
780 public ProjectElementDAO getProjectElementDAO() {
781 return _projectElementDAO;
785 * Set the projectElementDAO.
787 * @param projectElementDAO
788 * the projectElementDAO to set
790 public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
791 _projectElementDAO = projectElementDAO;
795 * Get the indexService.
797 * @return the indexService
799 public IndexService getIndexService() {
800 return _indexService;
804 * Set the indexService.
806 * @param indexService
807 * the indexService to set
809 public void setIndexService(final IndexService indexService) {
810 _indexService = indexService;
816 * @return the fileDAO
818 public FileDAO getFileDAO() {
828 public void setFileDAO(final FileDAO fileDAO) {
833 * Get the documentTypeService.
835 * @return the documentTypeService
837 public DocumentTypeService getDocumentTypeService() {
838 return _documentTypeService;
842 * Set the documentTypeService.
844 * @param documentTypeService
845 * the documentTypeService to set
847 public void setDocumentTypeService(
848 final DocumentTypeService documentTypeService) {
849 _documentTypeService = documentTypeService;
853 * Get the versionsRelationDAO.
855 * @return the versionsRelationDAO
857 public VersionsRelationDAO getVersionsRelationDAO() {
858 return _versionsRelationDAO;
862 * Set the versionsRelationDAO.
864 * @param versionsRelationDAO
865 * the versionsRelationDAO to set
867 public void setVersionsRelationDAO(
868 final VersionsRelationDAO versionsRelationDAO) {
869 _versionsRelationDAO = versionsRelationDAO;
873 * Get project settings.
875 * @return Project settings service
877 private ProjectSettingsService getProjectSettings() {
878 return _projectSettings;
882 * Set project settings service.
884 * @param projectSettingsService
885 * project settings service
887 public void setProjectSettings(
888 final ProjectSettingsService projectSettingsService) {
889 _projectSettings = projectSettingsService;
893 * Get the stepCommentAttributeDAO.
895 * @return the stepCommentAttributeDAO
897 public StepCommentAttributeDAO getStepCommentAttributeDAO() {
898 return _stepCommentAttributeDAO;
902 * Set the stepCommentAttributeDAO.
904 * @param commentAttributeDAO
905 * the stepCommentAttributeDAO to set
907 public void setStepCommentAttributeDAO(
908 final StepCommentAttributeDAO commentAttributeDAO) {
909 _stepCommentAttributeDAO = commentAttributeDAO;
915 * @return the userDAO
917 public UserDAO getUserDAO() {
927 public void setUserDAO(final UserDAO userDAO) {
932 * Get the publicationDAO.
934 * @return the publicationDAO
936 public PublicationDAO getPublicationDAO() {
937 return _publicationDAO;
941 * Set the publicationDAO.
943 * @param publicationDAO
944 * the publicationDAO to set
946 public void setPublicationDAO(final PublicationDAO publicationDAO) {
947 this._publicationDAO = publicationDAO;
951 * Get the relationDAO.
953 * @return the relationDAO
955 public RelationDAO getRelationDAO() {
960 * Set the relationDAO.
963 * the relationDAO to set
965 public void setRelationDAO(final RelationDAO relationDAO) {
966 _relationDAO = relationDAO;