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