Salome HOME
Search knowledge is implemented. Unit tests are improved. Lucene index is not used...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StudyServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            Id: 
5  * Creation date   02.10.2012
6  * @author         Author: Maria KRUCHININA
7  * @version        Revision: 
8  *****************************************************************************/
9
10 package org.splat.service;
11
12 import java.awt.Graphics2D;
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.text.DecimalFormat;
18 import java.text.SimpleDateFormat;
19 import java.util.Calendar;
20 import java.util.Collections;
21 import java.util.Date;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Scanner;
26 import java.util.Set;
27
28 import org.apache.lucene.index.IndexWriter;
29 import org.apache.lucene.store.FSDirectory;
30 import org.hibernate.criterion.Restrictions;
31 import org.jfree.chart.ChartFactory;
32 import org.jfree.chart.JFreeChart;
33 import org.jfree.chart.plot.PlotOrientation;
34 import org.jfree.data.xy.XYSeries;
35 import org.jfree.data.xy.XYSeriesCollection;
36 import org.splat.common.properties.MessageKeyEnum;
37 import org.splat.dal.bo.kernel.Relation;
38 import org.splat.dal.bo.kernel.User;
39 import org.splat.dal.bo.som.ActorRelation;
40 import org.splat.dal.bo.som.ContributorRelation;
41 import org.splat.dal.bo.som.DescriptionAttribute;
42 import org.splat.dal.bo.som.DocumentType;
43 import org.splat.dal.bo.som.IDBuilder;
44 import org.splat.dal.bo.som.ProgressState;
45 import org.splat.dal.bo.som.Publication;
46 import org.splat.dal.bo.som.SimulationContext;
47 import org.splat.dal.bo.som.Study;
48 import org.splat.dal.bo.som.ValidationCycle;
49 import org.splat.dal.bo.som.ValidationCycleRelation;
50 import org.splat.dal.bo.som.ValidationStep;
51 import org.splat.dal.bo.som.Visibility;
52 import org.splat.dal.bo.som.Study.Properties;
53 import org.splat.dal.bo.som.ValidationCycle.Actor;
54 import org.splat.dal.dao.som.DescriptionAttributeDAO;
55 import org.splat.dal.dao.som.DocumentDAO;
56 import org.splat.dal.dao.som.IDBuilderDAO;
57 import org.splat.dal.dao.som.PublicationDAO;
58 import org.splat.dal.dao.som.ScenarioDAO;
59 import org.splat.dal.dao.som.StudyDAO;
60 import org.splat.dal.dao.som.ValidationCycleDAO;
61 import org.splat.exception.IncompatibleDataException;
62 import org.splat.exception.InvalidParameterException;
63 import org.splat.kernel.InvalidPropertyException;
64 import org.splat.kernel.MissedPropertyException;
65 import org.splat.kernel.MultiplyDefinedException;
66 import org.splat.log.AppLogger;
67 import org.splat.service.dto.DocToCompareDTO;
68 import org.splat.service.technical.IndexService;
69 import org.splat.service.technical.ProjectSettingsService;
70 import org.splat.service.technical.ProjectSettingsServiceImpl;
71 import org.splat.service.technical.RepositoryService;
72 import org.splat.som.Revision;
73 import org.springframework.transaction.annotation.Transactional;
74
75 import com.lowagie.text.Document;
76 import com.lowagie.text.DocumentException;
77 import com.lowagie.text.Rectangle;
78 import com.lowagie.text.pdf.DefaultFontMapper;
79 import com.lowagie.text.pdf.PdfContentByte;
80 import com.lowagie.text.pdf.PdfTemplate;
81 import com.lowagie.text.pdf.PdfWriter;
82
83
84 /**
85  * This class defines all methods for creation, modification the study.
86  * 
87  * @author Maria KRUCHININA
88  * 
89  */
90 public class StudyServiceImpl implements StudyService {
91
92         /**
93          * logger for the service.
94          */
95         public final static AppLogger LOG = AppLogger
96                         .getLogger(StudyServiceImpl.class);
97
98         /**
99          * Injected index service.
100          */
101         private IndexService _indexService;
102
103         /**
104          * Injected step service.
105          */
106         private StepService _stepService;
107
108         /**
109          * Injected project service.
110          */
111         private ProjectSettingsService _projectSettings;
112
113         /**
114          * Injected project element service.
115          */
116         private ProjectElementService _projectElementService;
117
118         /**
119          * Injected study DAO.
120          */
121         private StudyDAO _studyDAO;
122
123         /**
124          * Injected scenario DAO.
125          */
126         private ScenarioDAO _scenarioDAO;
127
128         /**
129          * Injected validation cycle DAO.
130          */
131         private ValidationCycleDAO _validationCycleDAO;
132
133         /**
134          * Injected IDBuilder DAO.
135          */
136         private IDBuilderDAO _iDBuilderDAO;
137
138         /**
139          * Injected document type service.
140          */
141         private DocumentTypeService _documentTypeService;
142
143         /**
144          * Injected user service.
145          */
146         private UserService _userService;
147         
148         /**
149          * Injected publication DAO.
150          */
151         private PublicationDAO _publicationDAO;
152
153         /**
154          * Injected repository service.
155          */
156         private RepositoryService _repositoryService;
157
158         /**
159          * Injected document DAO.
160          */
161         private DocumentDAO _documentDAO;
162
163         /**
164          * Injected description attribute DAO.
165          */
166         private DescriptionAttributeDAO _descriptionAttributeDAO;
167
168         /**
169          * {@inheritDoc}
170          * 
171          * @see org.splat.service.StudyService#selectStudy(long)
172          */
173         @Transactional
174         public Study selectStudy(final long index) {
175                 Study result = getStudyDAO().get(index);
176                 loadWorkflow(result);
177                 return result;
178         }
179
180         /**
181          * Get study by its reference.
182          * 
183          * @param refid
184          *            the study reference
185          * @return found study or null
186          */
187         @Transactional(readOnly = true)
188         public Study selectStudy(final String refid) {
189                 Study result = getStudyDAO().findByCriteria(
190                                 Restrictions.eq("sid", refid));
191                 loadWorkflow(result);
192                 return result;
193         }
194
195         /**
196          * {@inheritDoc}
197          * 
198          * @see org.splat.service.StudyService#createStudy(org.splat.dal.bo.som.Study.Properties)
199          */
200         @Transactional
201         public Study createStudy(final Study.Properties sprop)
202                         throws MissedPropertyException, InvalidPropertyException,
203                         MultiplyDefinedException {
204                 sprop.setReference(getProjectSettings().getReferencePattern());
205                 Study study = new Study(sprop);
206
207                 buildReference(study);
208                 getStudyDAO().create(study);
209 //              try {
210 //                      IndexService lucin = getIndex();
211 //                      lucin.add(study);
212 //              } catch (IOException error) {
213 //                      LOG.error("Unable to index the study '" + study.getIndex()
214 //                                      + "', reason:", error);
215 //                      // Continue and try to index later
216 //              }
217                 return study;
218         }
219
220         /**
221          * {@inheritDoc}
222          * 
223          * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext.Properties)
224          */
225         @Transactional
226         public SimulationContext addProjectContext(final Study aStudy,
227                         final SimulationContext.Properties cprop)
228                         throws MissedPropertyException, InvalidPropertyException,
229                         MultiplyDefinedException {
230                 SimulationContext added = getStepService().addSimulationContext(
231                                 getProjectElementService().getFirstStep(aStudy), cprop);
232                 update(aStudy);
233                 return added;
234         }
235
236         /**
237          * {@inheritDoc}
238          * 
239          * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext)
240          */
241         @Transactional
242         public SimulationContext addProjectContext(final Study aStudy,
243                         final SimulationContext context) {
244                 SimulationContext added = getStepService().addSimulationContext(
245                                 getProjectElementService().getFirstStep(aStudy), context);
246                 update(aStudy);
247                 return added;
248         }
249
250         /**
251          * {@inheritDoc}
252          * 
253          * @see org.splat.service.StudyService#addContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User)
254          */
255         public boolean addContributor(final Study aStudy, final User user) {
256                 List<User> contributor = getModifiableContributors(aStudy); // Initializes contributor
257                 for (Iterator<User> i = contributor.iterator(); i.hasNext();) {
258                         User present = i.next();
259                         if (present.equals(user)) {
260                                 return false;
261                         }
262                 }
263                 boolean absent = getModifiableActors(aStudy).add(user); // User may already be a reviewer or an approver
264
265                 aStudy.addRelation(new ContributorRelation(aStudy, user));
266                 if (absent) {
267                         update(aStudy); // Else, useless to re-index the study
268                 }
269                 contributor.add(user);
270                 return true;
271         }
272
273         /**
274          * Moves this study from the Public to the Reference area of the repository. For being moved to the Reference area, the study must
275          * previously be approved.
276          * 
277          * @param aStudy
278          *            the study to move
279          * @return true if the move succeeded.
280          * @see #moveToPublic()
281          * @see #isPublic()
282          * @see Publication#approve(Date)
283          */
284         public boolean moveToReference(final Study aStudy) {
285                 if (aStudy.getProgressState() != ProgressState.APPROVED) {
286                         return false;
287                 }
288                 if (aStudy.getVisibility() != Visibility.PUBLIC) {
289                         return false;
290                 }
291
292                 aStudy.setVisibility(Visibility.REFERENCE);
293                 if (update(aStudy)) {
294                         return updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
295                 }
296                 return false;
297         }
298
299         /**
300          * {@inheritDoc}
301          * 
302          * @see org.splat.service.StudyService#update(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Study.Properties)
303          */
304         public boolean update(final Study aStudy, final Properties sprop)
305                         throws InvalidPropertyException {
306                 if (sprop.getTitle() != null) {
307                         aStudy.setTitle(sprop.getTitle());
308                 }
309                 if (sprop.getSummary() != null) {
310                         aStudy.setAttribute(new DescriptionAttribute(aStudy, sprop
311                                         .getSummary()));
312                 }
313                 // TODO: To be completed
314                 return update(aStudy);
315         }
316
317         /**
318          * Check if the document is published in the study.
319          * 
320          * @param aStudy
321          *            the study
322          * @param doc
323          *            the document
324          * @return true if the document is published in the study
325          */
326 /*      private boolean publishes(final Study aStudy, final Document doc) {
327                 if (!aStudy.publishes(doc)) {
328                         Scenario[] scene = aStudy.getScenarii();
329                         for (int i = 0; i < scene.length; i++) {
330                                 if (scene[i].publishes(doc)) {
331                                         return true;
332                                 }
333                         }
334                 }
335                 return false;
336         }
337 */
338         /**
339          * {@inheritDoc}
340          * 
341          * @see org.splat.service.StudyService#removeContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User[])
342          */
343         public boolean removeContributor(final Study aStudy, final User... users) {
344                 List<User> contributor = getModifiableContributors(aStudy); // Initializes contributor
345                 Boolean done = false;
346                 for (int i = 0; i < users.length; i++) {
347                         User user = users[i];
348                         for (Iterator<User> j = contributor.iterator(); j.hasNext();) {
349                                 User present = j.next();
350                                 if (!present.equals(user)) {
351                                         continue;
352                                 }
353
354                                 aStudy.removeRelation(ContributorRelation.class, user);
355                                 j.remove(); // Updates the contributor shortcut
356                                 done = true;
357                                 break;
358                         }
359                 }
360                 if (done) {
361                         update(aStudy);
362                 }
363                 return done;
364         }
365
366         /**
367          * {@inheritDoc}
368          * 
369          * @see org.splat.service.StudyService#removeProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext)
370          */
371         public boolean removeProjectContext(final Study aStudy,
372                         final SimulationContext context) {
373                 boolean done = getStepService().removeSimulationContext(
374                                 getProjectElementService().getFirstStep(aStudy), context);
375                 update(aStudy);
376                 return done;
377         }
378
379         /**
380          * {@inheritDoc}
381          * 
382          * @see org.splat.service.StudyService#setValidationCycle(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.DocumentType,
383          *      org.splat.dal.bo.som.ValidationCycle.Properties)
384          */
385         @Transactional
386         public void setValidationCycle(final Study aStudyDTO, final DocumentType type,
387                         final ValidationCycle.Properties vprop) {
388                 Map<String, ValidationCycle> validactor = aStudyDTO.getValidationCycles();
389                 if (validactor == null) {
390                         setShortCuts(aStudyDTO); // Initializes validactor and actor
391                 }
392
393                 Study aStudy = selectStudy(aStudyDTO.getIndex());
394                 
395                 String cname = type.getName();
396                 ValidationCycle cycle = validactor.get(cname);
397
398                 if (cycle != null && cycle.isAssigned()) {
399                         resetActors(cycle, vprop);
400                 } else {
401                         try {
402                                 cycle = new ValidationCycle(aStudy, vprop.setDocumentType(type));
403
404                                 getValidationCycleDAO().create(cycle); // RKV
405
406                                 ValidationCycleRelation link = cycle.getContext();
407                                 aStudy.addRelation(link);
408                                 aStudyDTO.getAllRelations().add(link); // RKV
409
410                                 validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
411                         } catch (Exception error) {
412                                 LOG.error("Unable to re-index Knowledge Elements, reason:",
413                                                 error);
414                                 return;
415                         }
416                 }
417                 resetActorsShortCut(aStudyDTO);
418                 update(aStudy); // Re-index the study, just in case
419         }
420
421         /**
422          * Demotes this study from In-Check to In-Draft then In-Work states. This function is called internally when demoting the final result
423          * document of the study.
424          * 
425          * @param aStudy
426          *            a study to demote
427          * @return true if the demotion succeeded.
428          */
429         public boolean demote(final Study aStudy) {
430                 if (aStudy.getProgressState() == ProgressState.inCHECK) {
431                         aStudy.setProgressState(ProgressState.inDRAFT);
432                 } else if (aStudy.getProgressState() == ProgressState.inDRAFT) {
433                         aStudy.setProgressState(ProgressState.inWORK);
434                 } else {
435                         return false;
436                 }
437                 return update(aStudy);
438         }
439
440         /**
441          * {@inheritDoc}
442          * 
443          * @see org.splat.service.StudyService#generateLocalIndex(org.splat.dal.bo.som.Study)
444          */
445         @Transactional
446         public int generateLocalIndex(final Study aStudy) {
447                 aStudy.setLastLocalIndex(aStudy.getLastLocalIndex() + 1);
448                 return aStudy.getLastLocalIndex();
449         }
450
451         /**
452          * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states. This function is called internally when promoting the
453          * final result document of the study.
454          * 
455          * @param aStudy
456          *            a study to promote
457          * @return true if the demotion succeeded.
458          */
459         @Transactional
460         public boolean promote(final Study aStudy) {
461                 if (aStudy.getProgressState() == ProgressState.inWORK) {
462                         aStudy.setProgressState(ProgressState.inDRAFT);
463                 } else if (aStudy.getProgressState() == ProgressState.inDRAFT) {
464                         aStudy.setProgressState(ProgressState.inCHECK);
465                         Revision myvers = new Revision(aStudy.getVersion());
466                         if (myvers.isMinor()) {
467                                 aStudy.setVersion(myvers.incrementAs(aStudy.getProgressState())
468                                                 .toString());
469                         }
470                 } else if (aStudy.getProgressState() == ProgressState.inCHECK) {
471                         aStudy.setProgressState(ProgressState.APPROVED);
472                 } else {
473                         return false;
474                 }
475
476                 return update(aStudy);
477         }
478
479         /**
480          * Moves this study from the Private to the Public area of the repository.
481          * 
482          * @param aStudy
483          *            a study to move
484          * @return true if the move succeeded.
485          * @see #isPublic()
486          */
487         @Transactional
488         public boolean moveToPublic(final Study aStudy) {
489                 boolean isOk = false;
490                 if (aStudy.getVisibility() == Visibility.PRIVATE) {
491                         aStudy.setVisibility(Visibility.PUBLIC);
492                         if (update(aStudy)) {
493                                 isOk = updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
494                         }
495                 }
496                 return isOk;
497         }
498         
499         /**
500          * Moves this study from the Public to the Private area of the repository.
501          * 
502          * @param aStudy
503          *            a study to move
504          * @return true if the move succeeded.
505          */
506         @Transactional
507         public boolean moveToPrivate(final Study aStudy) {
508                 boolean isOk = false;
509                 if (aStudy.getVisibility() == Visibility.PUBLIC) {
510                         aStudy.setVisibility(Visibility.PRIVATE);
511                         if (update(aStudy)) {
512                                 isOk = updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
513                         }
514                 }
515                 return isOk;
516         }
517
518         /**
519          * Update a study in the database.
520          * 
521          * @param aStudy
522          *            the study to update
523          * @return true if the study is updated successfully
524          */
525         @Transactional
526         private boolean update(final Study aStudy) {
527                 boolean isOk = false;
528                 try {
529                         getStudyDAO().merge(aStudy); // Update of relational base
530                         setShortCuts(aStudy); // RKV: initialize transient actors set
531                         //RKV: getIndex().update(aStudy); // Update of Lucene index
532                         isOk = true;
533                 } catch (Exception e) {
534                         LOG.error("STD-000001", e, aStudy.getIndex(), e.getMessage());
535                 }
536                 return isOk;
537         }
538
539         /**
540          * Build reference for the study. The reference of the study is stored as a new reference pattern (IDBuilder).
541          * 
542          * @param aStudy
543          *            the study
544          * @return true if reference building is succeded
545          */
546         @Transactional
547         private boolean buildReference(final Study aStudy) {
548                 String pattern = aStudy.getReference(); // The study being supposed just created, its reference is the reference pattern
549                 IDBuilder tool = selectIDBuilder(aStudy.getDate());
550                 if (tool == null) {
551                         tool = new IDBuilder(aStudy.getDate());
552                         getIDBuilderDAO().create(tool);
553                 }
554                 aStudy.setReference(buildReference(tool, pattern, aStudy));
555                 return true;
556         }
557
558         /**
559          * Build reference for the study. The reference of the study is stored as a new reference pattern (IDBuilder).
560          * 
561          * @param aBuilder
562          *            the id builder
563          * @param study
564          *            the study
565          * @param pattern
566          *            the reference pattern
567          * @return true if reference building is succeded
568          */
569         @Transactional
570         public String buildReference(final IDBuilder aBuilder,
571                         final String pattern, final Study study) {
572                 char[] format = pattern.toCharArray();
573                 char[] ref = new char[80]; // Better evaluate the length of the generated string
574                 int next = aBuilder.getBase() + 1;
575
576                 int count = 0;
577                 for (int i = 0; i < format.length; i++) {
578
579                         // Insertion of attribute values
580                         if (format[i] == '%') {
581                                 i += 1;
582
583                                 if (format[i] == 'y') { // Insertion of year in format 2 (e.g. 09) or 4 (e.g. 2009) digits
584                                         int n = i;
585                                         while (format[i] == 'y') {
586                                                 i += 1;
587                                                 if (i == format.length) {
588                                                         break;
589                                                 }
590                                         }
591                                         SimpleDateFormat tostring = new SimpleDateFormat("yyyy"); //RKV: NOPMD: TODO: Use locale here?
592                                         String year = tostring.format(study.getDate());
593                                         year = year.substring(4 - (i - n), 4); // 4-(i-n) must be equal to either 0 or 2
594                                         for (int j = 0; j < year.length(); j++) {
595                                                 ref[count] = year.charAt(j);
596                                                 count += 1;
597                                         }
598                                         i -= 1; // Back to the last 'y' character
599                                 } else if (format[i] == '0') { // Insertion of the index
600                                         int n = i;
601                                         while (format[i] == '0') {
602                                                 i += 1;
603                                                 if (i == format.length) {
604                                                         break;
605                                                 }
606                                         }
607                                         DecimalFormat tostring = new DecimalFormat(pattern
608                                                         .substring(n, i));
609                                         String number = tostring.format(next);
610                                         for (int j = 0; j < number.length(); j++) {
611                                                 ref[count] = number.charAt(j);
612                                                 count += 1;
613                                         }
614                                         i -= 1; // Back to the last '0' character
615                                 }
616                                 // Keep the character
617                         } else {
618                                 ref[count] = format[i];
619                                 count += 1;
620                         }
621                 }
622                 // Incrementation of the number of study
623                 aBuilder.setBase(next);
624                 getIDBuilderDAO().update(aBuilder);
625                 return String.copyValueOf(ref, 0, count);
626         }
627
628         /**
629          * Find an id builder by date.
630          * 
631          * @param date
632          *            the date
633          * @return found id builder
634          */
635         private IDBuilder selectIDBuilder(final Date date) {
636                 Calendar aDate = Calendar.getInstance();
637                 aDate.setTime(date);
638                 return getIDBuilderDAO().findByCriteria(
639                                 Restrictions.eq("cycle", aDate.get(Calendar.YEAR)));
640         }
641
642         /**
643          * Fill transient collection ModifiableActors of the study.
644          * 
645          * @param aStudy
646          *            the study
647          */
648         private void resetActorsShortCut(final Study aStudy) {
649                 getModifiableActors(aStudy).clear();
650                 // Get all actors involved in validation cycles
651                 for (Iterator<ValidationCycle> i = aStudy.getValidationCycles()
652                                 .values().iterator(); i.hasNext();) {
653                         ValidationCycle cycle = i.next();
654                         User[] user = cycle.getAllActors();
655                         for (int j = 0; j < user.length; j++) {
656                                 getModifiableActors(aStudy).add(user[j]);
657                         }
658                 }
659                 // Get all other actors
660                 for (Iterator<Relation> i = aStudy.getAllRelations().iterator(); i
661                                 .hasNext();) {
662                         Relation link = i.next();
663                         Class<?> kindof = link.getClass().getSuperclass();
664                         if (!kindof.equals(ActorRelation.class)) {
665                                 continue;
666                         }
667                         getModifiableActors(aStudy).add(((ActorRelation) link).getTo());
668                 }
669         }
670
671         /**
672          * Update lucene index for the study knowledge elements.
673          * 
674          * @param aStudy
675          *            the study
676          * @return true if reindexing succeeded
677          */
678         private boolean updateKnowledgeElementsIndex(final Study aStudy) {
679 //              boolean isOk = false;
680 //              try {
681 //                      IndexService lucin = getIndex();
682 //
683 //                      for (Iterator<Scenario> i = aStudy.getScenariiList().iterator(); i
684 //                                      .hasNext();) {
685 //                              Scenario scene = i.next();
686 //                              for (Iterator<KnowledgeElement> j = scene
687 //                                              .getAllKnowledgeElements().iterator(); j.hasNext();) {
688 //                                      KnowledgeElement kelm = j.next();
689 //                                      lucin.update(kelm);
690 //                              }
691 //                      }
692 //                      isOk = true;
693 //              } catch (Exception error) {
694 //                      LOG.error("Unable to re-index Knowledge Elements, reason:",
695 //                                      error);
696 //              }
697 //              return isOk;
698                 return true;
699         }
700
701         /**
702          * Get lucene index service. Create a lucene index if it does not exist.
703          * 
704          * @return index service
705          * @throws IOException
706          *             if error occurs during lucene index creation
707          */
708         private IndexService getIndex() throws IOException {
709                 IndexService lucin = getIndexService();
710                 if (IndexWriter.isLocked(FSDirectory.open(getRepositoryService()
711                                 .getRepositoryIndexDirectory()))) {
712                         IndexWriter.unlock(FSDirectory.open(getRepositoryService()
713                                         .getRepositoryIndexDirectory()));
714                 }
715                 if (!lucin.exists()) {
716                         lucin.create(); // Happens when re-indexing all studies
717                 }
718                 return lucin;
719         }
720
721         /**
722          * Create a new validation cycle for documents of the given study.
723          * 
724          * @param from
725          *            the study
726          * @param cycle
727          *            the cycle description
728          * @return the new validation cycle
729          */
730         protected ValidationCycle createValidationCycle(
731                         final Study from,
732                         final ProjectSettingsServiceImpl.ProjectSettingsValidationCycle cycle) {
733                 Actor[] actype = cycle.getActorTypes();
734                 User.Properties uprop = new User.Properties();
735
736                 ValidationCycle aValidationCycle = new ValidationCycle();
737                 aValidationCycle.setDocumentType(getDocumentTypeService().selectType(
738                                 cycle.getName())); // Null in case of default validation cycle
739                 // context = new ValidationCycleRelation(from, vprop);
740                 // RKV aValidationCycle.context = null; // Validation cycle defined in the workflow
741                 for (int i = 0; i < actype.length; i++) {
742                         User actor = null;
743                         if (actype[i] != null) {
744                                 try {
745                                         if (actype[i] == Actor.manager) {
746                                                 actor = from.getAuthor();
747                                         } else if (actype[i] == Actor.Nx1) {
748                                                 List<User> manager = getUserService().selectUsersWhere(
749                                                                 uprop.setOrganizationName("Nx1"));
750                                                 if (manager.size() == 1) {
751                                                         actor = manager.get(0);
752                                                 }
753                                         } else if (actype[i] == Actor.Nx2) {
754                                                 List<User> manager = getUserService().selectUsersWhere(
755                                                                 uprop.setOrganizationName("Nx2"));
756                                                 if (manager.size() == 1) {
757                                                         actor = manager.get(0);
758                                                 }
759                                         } else { /* Actor.customer */
760                                                 actor = from.getAuthor();
761                                                 // TODO: Get the customer of the study, if exists
762                                         }
763                                 } catch (Exception e) { // Should not happen
764                                         actor = null;
765                                 }
766                         }
767                         if (i == 0) {
768                                 aValidationCycle.setReviewer(actor);
769                         } else if (i == 1) {
770                                 aValidationCycle.setApprover(actor);
771                         } else if (i == 2) {
772                                 aValidationCycle.setSignatory(actor);
773                         }
774                 }
775                 return aValidationCycle;
776         }
777
778         /**
779          * Remove a validation step from the validation cycle.
780          * 
781          * @param aValidationCycle
782          *            the validation cycle
783          * @param step
784          *            the validation step to remove
785          */
786         @Transactional
787         protected void remove(final ValidationCycle aValidationCycle,
788                         final ValidationStep step) {
789                 if (step == ValidationStep.REVIEW) {
790                         aValidationCycle.setReviewer(null);
791                 } else if (step == ValidationStep.APPROVAL) {
792                         aValidationCycle.setApprover(null);
793                 } else if (step == ValidationStep.ACCEPTANCE
794                                 || step == ValidationStep.REFUSAL) {
795                         aValidationCycle.setSignatory(null);
796                 }
797                 if (aValidationCycle.isSaved()) {
798                         getValidationCycleDAO().update(aValidationCycle);
799                 }
800         }
801
802         /**
803          * Reset actors for the validation cycle.
804          * 
805          * @param aValidationCycle
806          *            the validation cycle to update
807          * @param vprop
808          *            new validation cycle properties containing new actors
809          */
810         @Transactional
811         public void resetActors(final ValidationCycle aValidationCycle,
812                         final ValidationCycle.Properties vprop) {
813                 aValidationCycle.setPublisher(vprop.getPublisher()); // May be null
814                 aValidationCycle.setReviewer(vprop.getReviewer()); // May be null
815                 aValidationCycle.setApprover(vprop.getApprover()); // May be null
816                 aValidationCycle.setSignatory(vprop.getSignatory()); // May be null
817                 if (aValidationCycle.isSaved()) {
818                         getValidationCycleDAO().merge(aValidationCycle);
819                 }
820         }
821
822         /**
823          * Set actor for the given validation cycle and validation step.
824          * 
825          * @param aValidationCycle
826          *            the validation cycle
827          * @param step
828          *            the validation step
829          * @param actor
830          *            the actor to set
831          */
832         @Transactional
833         protected void setActor(final ValidationCycle aValidationCycle,
834                         final ValidationStep step, final User actor) {
835                 if (step == ValidationStep.PROMOTION) {
836                         aValidationCycle.setPublisher(actor);
837                 } else if (step == ValidationStep.REVIEW) {
838                         aValidationCycle.setReviewer(actor);
839                 } else if (step == ValidationStep.APPROVAL) {
840                         aValidationCycle.setApprover(actor);
841                 } else if (step == ValidationStep.ACCEPTANCE
842                                 || step == ValidationStep.REFUSAL) {
843                         aValidationCycle.setSignatory(actor);
844                 }
845                 if (aValidationCycle.isSaved()) {
846                         getValidationCycleDAO().update(aValidationCycle);
847                 }
848         }
849
850         /**
851          * Returns all actors of this study other than the author, including contributors, reviewers and approvers.
852          * 
853          * @param aStudy
854          *            the study
855          * @return the actors of this study
856          * @see #hasActor(User)
857          */
858         public Set<User> getActors(final Study aStudy) {
859                 if (aStudy.getActor() == null) {
860                         setShortCuts(aStudy);
861                 }
862                 return Collections.unmodifiableSet(aStudy.getActor());
863         }
864
865         /**
866          * Returns all actors of this study other than the author, including contributors, reviewers and approvers.
867          * 
868          * @param aStudy
869          *            the study
870          * @return the modifiable set of actors of this study
871          * @see #hasActor(User)
872          */
873         public Set<User> getModifiableActors(final Study aStudy) {
874                 if (aStudy.getActor() == null) {
875                         setShortCuts(aStudy);
876                 }
877                 return aStudy.getActor();
878         }
879
880         /**
881          * Returns unmodifiable initialized transient list of contributors of this study.
882          * 
883          * @param aStudy
884          *            the study
885          * @return the unmodifiable not null transient list of contributors of this study
886          */
887         public List<User> getContributors(final Study aStudy) {
888                 if (aStudy.getContributor() == null) {
889                         setShortCuts(aStudy);
890                 }
891                 return Collections.unmodifiableList(aStudy.getContributor()); // May be empty
892         }
893
894         /**
895          * Returns modifiable initialized transient list of contributors of this study.
896          * 
897          * @param aStudy
898          *            the study
899          * @return the modifiable not null transient list of contributors of this study
900          */
901         public List<User> getModifiableContributors(final Study aStudy) {
902                 if (aStudy.getContributor() == null) {
903                         setShortCuts(aStudy);
904                 }
905                 return aStudy.getContributor(); // May be empty
906         }
907
908         /**
909          * Returns the validation cycle of the given document type.
910          * 
911          * @param aStudy
912          *            the study
913          * @param type
914          *            the document type being subject of validation
915          * @return the validation cycle of the document, or null if not defined.
916          */
917         public ValidationCycle getValidationCycleOf(final Study aStudy,
918                         final DocumentType type) {
919                 if (aStudy.getValidationCycles() == null || aStudy.getValidationCycles().isEmpty()) {
920                         setShortCuts(aStudy);
921                 }
922                 ValidationCycle result = aStudy.getValidationCycles().get(
923                                 type.getName());
924                 if (result == null) {
925                         if (type.isStepResult()) {
926                                 result = aStudy.getValidationCycles().get("default"); // "default" validation cycle defined in the configuration, if exist
927                         }
928                         if (result == null) {
929                                 result = aStudy.getValidationCycles().get("built-in");
930                         }
931                 }
932                 return result;
933         }
934
935         /**
936          * Checks if the given user is actor of this study. Actors include contributors, reviewers and approvers.
937          * 
938          * @param aStudy
939          *            the study
940          * @param user
941          *            the user to look for
942          * @return true if the given user is actor of this study.
943          * @see #getActors()
944          */
945         public boolean hasActor(final Study aStudy, final User user) {
946                 if (user == null) {
947                         return false;
948                 }
949                 for (Iterator<User> i = getActors(aStudy).iterator(); i.hasNext();) {
950                         User involved = i.next();
951                         if (involved.equals(user)) {
952                                 return true;
953                         }
954                 }
955                 return false;
956         }
957
958         /**
959          * Checks if the given user participates to this study. The Study staff includes the author and contributors.
960          * 
961          * @param aStudy
962          *            the study
963          * @param user
964          *            the user to look for
965          * @return true if the given user is actor of this study.
966          * @see #getContributors()
967          */
968         public boolean isStaffedBy(final Study aStudy, final User user) {
969                 if (user == null) {
970                         return false;
971                 }
972                 if (aStudy == null) {
973                         return false;
974                 }
975                 if (aStudy.getAuthor() == null) {
976                         return false;
977                 }
978                 if (aStudy.getAuthor().equals(user)) {
979                         return true;
980                 }
981                 for (Iterator<User> i = getContributors(aStudy).iterator(); i.hasNext();) {
982                         if (i.next().equals(user)) {
983                                 return true;
984                         }
985                 }
986                 return false;
987         }
988
989         /**
990          * Initialize shortcuts of the study as its transient collections.
991          * 
992          * @param aStudy
993          *            the study
994          */
995         public void loadWorkflow(final Study aStudy) {
996                 setShortCuts(aStudy);
997         }
998
999         /**
1000          * Initialize shortcuts of the study as its transient collections.
1001          * 
1002          * @param aStudy
1003          *            the study
1004          */
1005         public void setShortCuts(final Study aStudy) {
1006                 aStudy.getContributor().clear();
1007                 aStudy.getValidationCycles().clear();
1008                 aStudy.getActor().clear();
1009
1010                 // Get the contributors
1011                 for (Iterator<Relation> i = aStudy.getRelations(
1012                                 ContributorRelation.class).iterator(); i.hasNext();) {
1013                         ContributorRelation link = (ContributorRelation) i.next();
1014                         aStudy.getContributor().add(link.getTo());
1015                 }
1016                 // Get the validation cycles specific to this study
1017                 for (Iterator<Relation> i = aStudy.getRelations(
1018                                 ValidationCycleRelation.class).iterator(); i.hasNext();) {
1019                         ValidationCycleRelation link = (ValidationCycleRelation) i.next();
1020                         aStudy.getValidationCycles().put(link.getDocumentType().getName(),
1021                                         link.getTo()); // The associated document type is necessarily not null in this
1022                         // context
1023                 }
1024                 // Get the validation cycles coming from the configured workflow and not overridden in this study
1025                 for (Iterator<ProjectSettingsServiceImpl.ProjectSettingsValidationCycle> i = getProjectSettings()
1026                                 .getAllValidationCycles().iterator(); i.hasNext();) {
1027                         ProjectSettingsServiceImpl.ProjectSettingsValidationCycle cycle = i
1028                                         .next();
1029                         String type = cycle.getName();
1030                         if (!aStudy.getValidationCycles().containsKey(type)) {
1031                                 aStudy.getValidationCycles().put(type,
1032                                                 createValidationCycle(aStudy, cycle));
1033                         }
1034                 }
1035                 // Get all corresponding actors
1036                 for (Iterator<ValidationCycle> i = aStudy.getValidationCycles()
1037                                 .values().iterator(); i.hasNext();) {
1038                         ValidationCycle cycle = i.next();
1039                         User[] user = cycle.getAllActors();
1040                         for (int j = 0; j < user.length; j++) {
1041                                 aStudy.getActor().add(user[j]);
1042                         }
1043                 }
1044                 // Get all other actors
1045                 for (Iterator<Relation> i = aStudy.getAllRelations().iterator(); i
1046                                 .hasNext();) {
1047                         Relation link = i.next();
1048                         Class<?> kindof = link.getClass().getSuperclass();
1049                         if (!kindof.equals(ActorRelation.class)) {
1050                                 continue;
1051                         }
1052                         aStudy.getActor().add(((ActorRelation) link).getTo());
1053                 }
1054         }
1055         
1056         /**
1057          * 
1058          * {@inheritDoc}
1059          * @see org.splat.service.StudyService#markStudyAsReference(org.splat.dal.bo.som.Study)
1060          */
1061         @Override
1062         @Transactional
1063         public void markStudyAsReference (final Study aStudy) {
1064                 
1065                 aStudy.setMarkreference(1);
1066                 aStudy.setProgressState(ProgressState.TEMPLATE);
1067                 getStudyDAO().merge(aStudy);
1068         }
1069         
1070         /**
1071          * 
1072          * {@inheritDoc}
1073          * @see org.splat.service.StudyService#removeStudyAsReference(org.splat.dal.bo.som.Study)
1074          */
1075         @Override
1076         @Transactional
1077         public void removeStudyAsReference(final Study aStudy) {
1078                 
1079                 aStudy.setMarkreference(0);
1080                 aStudy.setProgressState(ProgressState.APPROVED);
1081                 getStudyDAO().merge(aStudy);
1082         }
1083         
1084         /** 
1085          * {@inheritDoc}
1086          * @see org.splat.service.StudyService#getDescription(java.lang.Long)
1087          */
1088         @Override
1089         @Transactional(readOnly = true)
1090         public String getDescription(final Long studyId) throws InvalidParameterException {
1091                 if(studyId == null) {
1092                         throw new InvalidParameterException("studyId", "null");
1093                 }
1094                 Study study = _studyDAO.get(studyId);
1095                 if(study == null) {
1096                         throw new InvalidParameterException("studyId", studyId.toString());
1097                 }
1098                 return study.getDescription();
1099         }
1100         
1101         
1102         /** 
1103          * {@inheritDoc}
1104          * @see org.splat.service.StudyService#setDescription(java.lang.Long, java.lang.String)
1105          */
1106         @Override
1107         @Transactional
1108         public void setDescription(final Long studyId, final String descriptionText) 
1109                         throws InvalidParameterException {
1110                 if(studyId == null) {
1111                         throw new InvalidParameterException("studyId", "null");
1112                 }
1113                 Study study = _studyDAO.get(studyId);
1114                 if(study == null) {
1115                         throw new InvalidParameterException("studyId", studyId.toString());
1116                 }
1117                 study.setAttribute(new DescriptionAttribute(study, descriptionText));
1118         }
1119
1120         /**
1121          * {@inheritDoc}
1122          * @see org.splat.service.StudyService#removeStudyDescription(java.lang.Long)
1123          */
1124         @Override
1125         @Transactional
1126         public boolean removeDescription(final Long studyId) throws InvalidParameterException {
1127                 if(studyId == null) {
1128                         throw new InvalidParameterException("studyId", String.valueOf(studyId));
1129                 }
1130                 Study study = _studyDAO.get(studyId);
1131                 if(study == null) {
1132                         throw new InvalidParameterException("studyId", String.valueOf(studyId));
1133                 }
1134                 return study.removeAttribute(study.getAttribute(DescriptionAttribute.class));
1135         }
1136         
1137         /**
1138          * 
1139          * {@inheritDoc}
1140          * @see org.splat.service.StudyService#compare(java.util.List)
1141          */
1142         @Override
1143         public String compare (final List<DocToCompareDTO> docsList, final String userName) throws IncompatibleDataException{
1144                 
1145                 String axis1Name = "";
1146                 String axis2Name = "";
1147                 String resultPath = "";
1148                 
1149                 XYSeriesCollection dataset = new XYSeriesCollection();
1150                 
1151                 Iterator<DocToCompareDTO> docListIter = docsList.iterator();
1152                 
1153                 for (; docListIter.hasNext();) {
1154                         
1155                         DocToCompareDTO docDTO = docListIter.next();
1156                         String pathToFile = docDTO.getPathToFile();
1157                         File compDocFile = new File(pathToFile);
1158                         
1159                         resultPath = pathToFile.substring(0, pathToFile.indexOf("vault")) + "downloads" + File.separator + userName + File.separator + "ComparisonResult.pdf";
1160                         
1161                         XYSeries series = new XYSeries("Study: " + docDTO.getStudyTitle() + " Scenario: " + docDTO.getScenarioTitle());
1162                         
1163                         //read the file and get points information.
1164                         try {
1165                                 Scanner input = new Scanner(compDocFile);
1166                                 
1167                                 //get the name of the axis.
1168                                 if (input.hasNext()) {
1169                                         String[] tokens = input.nextLine().split(",");
1170                                         if ("".equals(axis1Name)) {
1171                                                 axis1Name = tokens[0];
1172                                         } else if (!axis1Name.equals(tokens[0])) {
1173                                                 LOG.debug("Axis must be the same for all documents");
1174                                                 throw new IncompatibleDataException(MessageKeyEnum.IDT_000001.toString());
1175                                         }
1176                                         
1177                                         if ("".equals(axis2Name)) {
1178                                                 axis2Name = tokens[1];
1179                                         } else if (!axis2Name.equals(tokens[1])) {
1180                                                 LOG.debug("Axis must be the same for all documents");
1181                                                 throw new IncompatibleDataException(MessageKeyEnum.IDT_000001.toString());
1182                                         }
1183                                 }
1184                                 
1185                                 //Get the XY points series.
1186                                 while(input.hasNext()) {
1187                                         
1188                                         String currentString = input.nextLine();
1189                                         
1190                                         if ("".equals(currentString)) {
1191                                                 continue;
1192                                         }
1193                                         else {
1194                                                 String[] tokens = currentString.split(" ");
1195                                                 series.add(Double.valueOf(tokens[0]), Double.valueOf(tokens[1]));
1196                                         }                   
1197                                   
1198                                 } //while
1199                                 
1200                                 dataset.addSeries(series);
1201                                 
1202                         } catch (FileNotFoundException e) {
1203                                 // TODO Auto-generated catch block
1204                                 e.printStackTrace();
1205                                 return "ERROR";
1206                         }
1207                 } //for
1208                 
1209                 JFreeChart chart = ChartFactory.createXYLineChart(
1210                                 "Comparision of Studies Results", // Title
1211                                 axis1Name, // x-axis Label
1212                                 axis2Name, // y-axis Label
1213                                 dataset, // Dataset
1214                                 PlotOrientation.VERTICAL, // Plot Orientation
1215                                 true, // Show Legend
1216                                 true, // Use tooltips
1217                                 false // Configure chart to generate URLs?
1218                                 );
1219                 
1220                 //export to PDF - file.                 
1221                 int x = 500;
1222                 int y = 300;
1223                 Rectangle pagesize = new Rectangle(x, y);
1224                 Document document = new Document(pagesize, 50, 50, 50, 50);
1225         PdfWriter writer;
1226                 try {
1227                         File resFile = new File(resultPath);
1228                         File resFolder = new File(resultPath.substring(0, resultPath.lastIndexOf(File.separator)));
1229                         resFolder.mkdirs();
1230                         writer = PdfWriter.getInstance(document, new FileOutputStream(resFile));
1231                 
1232                 document.open();
1233                 PdfContentByte cb = writer.getDirectContent();
1234                 PdfTemplate tp = cb.createTemplate(x, y);
1235                 Graphics2D g2 = tp.createGraphics(x, y, new DefaultFontMapper());
1236                 chart.draw(g2, new java.awt.Rectangle(x,y));
1237                 g2.dispose();
1238                 cb.addTemplate(tp, 0, 0);
1239                 document.close(); 
1240         
1241                 } catch (FileNotFoundException e) {
1242                         // TODO Auto-generated catch block
1243                         e.printStackTrace();
1244                 } catch (DocumentException e) {
1245                         // TODO Auto-generated catch block
1246                         e.printStackTrace();
1247                 }
1248                 
1249                 return resultPath;
1250         }
1251
1252         /**
1253          * Get project settings.
1254          * 
1255          * @return Project settings service
1256          */
1257         private ProjectSettingsService getProjectSettings() {
1258                 return _projectSettings;
1259         }
1260
1261         /**
1262          * Set project settings service.
1263          * 
1264          * @param projectSettingsService
1265          *            project settings service
1266          */
1267         public void setProjectSettings(
1268                         final ProjectSettingsService projectSettingsService) {
1269                 _projectSettings = projectSettingsService;
1270         }
1271
1272         /**
1273          * Get the projectElementService.
1274          * 
1275          * @return the projectElementService
1276          */
1277         public ProjectElementService getProjectElementService() {
1278                 return _projectElementService;
1279         }
1280
1281         /**
1282          * Set the projectElementService.
1283          * 
1284          * @param projectElementService
1285          *            the projectElementService to set
1286          */
1287         public void setProjectElementService(
1288                         final ProjectElementService projectElementService) {
1289                 _projectElementService = projectElementService;
1290         }
1291
1292         /**
1293          * Get the stepService.
1294          * 
1295          * @return the stepService
1296          */
1297         public StepService getStepService() {
1298                 return _stepService;
1299         }
1300
1301         /**
1302          * Set the stepService.
1303          * 
1304          * @param stepService
1305          *            the stepService to set
1306          */
1307         public void setStepService(final StepService stepService) {
1308                 _stepService = stepService;
1309         }
1310
1311         /**
1312          * Get the indexService.
1313          * 
1314          * @return the indexService
1315          */
1316         public IndexService getIndexService() {
1317                 return _indexService;
1318         }
1319
1320         /**
1321          * Set the indexService.
1322          * 
1323          * @param indexService
1324          *            the indexService to set
1325          */
1326         public void setIndexService(final IndexService indexService) {
1327                 _indexService = indexService;
1328         }
1329
1330         /**
1331          * Get the studyDAO.
1332          * 
1333          * @return the studyDAO
1334          */
1335         public StudyDAO getStudyDAO() {
1336                 return _studyDAO;
1337         }
1338
1339         /**
1340          * Set the studyDAO.
1341          * 
1342          * @param studyDAO
1343          *            the studyDAO to set
1344          */
1345         public void setStudyDAO(final StudyDAO studyDAO) {
1346                 _studyDAO = studyDAO;
1347         }
1348
1349         /**
1350          * Get the iDBuilderDAO.
1351          * 
1352          * @return the iDBuilderDAO
1353          */
1354         public IDBuilderDAO getIDBuilderDAO() {
1355                 return _iDBuilderDAO;
1356         }
1357
1358         /**
1359          * Set the iDBuilderDAO.
1360          * 
1361          * @param builderDAO
1362          *            the iDBuilderDAO to set
1363          */
1364         public void setIDBuilderDAO(final IDBuilderDAO builderDAO) {
1365                 _iDBuilderDAO = builderDAO;
1366         }
1367
1368         /**
1369          * Get the scenarioDAO.
1370          * 
1371          * @return the scenarioDAO
1372          */
1373         public ScenarioDAO getScenarioDAO() {
1374                 return _scenarioDAO;
1375         }
1376
1377         /**
1378          * Set the scenarioDAO.
1379          * 
1380          * @param scenarioDAO
1381          *            the scenarioDAO to set
1382          */
1383         public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
1384                 _scenarioDAO = scenarioDAO;
1385         }
1386
1387         /**
1388          * Get the validationCycleDAO.
1389          * 
1390          * @return the validationCycleDAO
1391          */
1392         public ValidationCycleDAO getValidationCycleDAO() {
1393                 return _validationCycleDAO;
1394         }
1395
1396         /**
1397          * Set the validationCycleDAO.
1398          * 
1399          * @param validationCycleDAO
1400          *            the validationCycleDAO to set
1401          */
1402         public void setValidationCycleDAO(
1403                         final ValidationCycleDAO validationCycleDAO) {
1404                 _validationCycleDAO = validationCycleDAO;
1405         }
1406
1407         /**
1408          * Get the documentTypeService.
1409          * 
1410          * @return the documentTypeService
1411          */
1412         public DocumentTypeService getDocumentTypeService() {
1413                 return _documentTypeService;
1414         }
1415
1416         /**
1417          * Set the documentTypeService.
1418          * 
1419          * @param documentTypeService
1420          *            the documentTypeService to set
1421          */
1422         public void setDocumentTypeService(
1423                         final DocumentTypeService documentTypeService) {
1424                 _documentTypeService = documentTypeService;
1425         }
1426
1427         /**
1428          * Get the userService.
1429          * 
1430          * @return the userService
1431          */
1432         public UserService getUserService() {
1433                 return _userService;
1434         }
1435
1436         /**
1437          * Set the userService.
1438          * 
1439          * @param userService
1440          *            the userService to set
1441          */
1442         public void setUserService(final UserService userService) {
1443                 _userService = userService;
1444         }
1445
1446         /**
1447          * Get the publicationDAO.
1448          * @return the publicationDAO
1449          */
1450         public PublicationDAO getPublicationDAO() {
1451                 return _publicationDAO;
1452         }
1453
1454         /**
1455          * Set the publicationDAO.
1456          * @param publicationDAO the publicationDAO to set
1457          */
1458         public void setPublicationDAO(final PublicationDAO publicationDAO) {
1459                 _publicationDAO = publicationDAO;
1460         }
1461
1462         /**
1463          * Get the repositoryService.
1464          * @return the repositoryService
1465          */
1466         public RepositoryService getRepositoryService() {
1467                 return _repositoryService;
1468         }
1469
1470         /**
1471          * Set the repositoryService.
1472          * @param repositoryService the repositoryService to set
1473          */
1474         public void setRepositoryService(final RepositoryService repositoryService) {
1475                 _repositoryService = repositoryService;
1476         }
1477
1478         /**
1479          * Get the documentDAO.
1480          * @return the documentDAO
1481          */
1482         public DocumentDAO getDocumentDAO() {
1483                 return _documentDAO;
1484         }
1485
1486         /**
1487          * Set the documentDAO.
1488          * @param documentDAO the documentDAO to set
1489          */
1490         public void setDocumentDAO(final DocumentDAO documentDAO) {
1491                 _documentDAO = documentDAO;
1492         }
1493
1494         /**
1495          * Get the descriptionAttributeDAO.
1496          * @return the descriptionAttributeDAO
1497          */
1498         public DescriptionAttributeDAO getDescriptionAttributeDAO() {
1499                 return _descriptionAttributeDAO;
1500         }
1501
1502         /**
1503          * Set the descriptionAttributeDAO.
1504          * @param descriptionAttributeDAO the descriptionAttributeDAO to set
1505          */
1506         public void setDescriptionAttributeDAO(
1507                         final DescriptionAttributeDAO descriptionAttributeDAO) {
1508                 _descriptionAttributeDAO = descriptionAttributeDAO;
1509         }
1510
1511 }