Salome HOME
d120b69444d1675dd5fd47b31d17216fb495dfd8
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StudyServiceImpl.java
1 /*****************************************************************************
2  * Company         EURIWARE
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.io.IOException;
13 import java.text.SimpleDateFormat;
14 import java.util.Calendar;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import org.hibernate.criterion.Restrictions;
21 import org.splat.dal.bo.kernel.Relation;
22 import org.splat.dal.bo.kernel.User;
23 import org.splat.dal.bo.som.ActorRelation;
24 import org.splat.dal.bo.som.ContributorRelation;
25 import org.splat.dal.bo.som.DescriptionAttribute;
26 import org.splat.dal.bo.som.Document;
27 import org.splat.dal.bo.som.DocumentType;
28 import org.splat.dal.bo.som.IDBuilder;
29 import org.splat.dal.bo.som.KnowledgeElement;
30 import org.splat.dal.bo.som.KnowledgeElementType;
31 import org.splat.dal.bo.som.ProgressState;
32 import org.splat.dal.bo.som.Publication;
33 import org.splat.dal.bo.som.Scenario;
34 import org.splat.dal.bo.som.SimulationContext;
35 import org.splat.dal.bo.som.Study;
36 import org.splat.dal.bo.som.ValidationCycle;
37 import org.splat.dal.bo.som.ValidationCycleRelation;
38 import org.splat.dal.bo.som.Visibility;
39 import org.splat.dal.bo.som.Study.Properties;
40 import org.splat.dal.dao.som.IDBuilderDAO;
41 import org.splat.dal.dao.som.ScenarioDAO;
42 import org.splat.dal.dao.som.StudyDAO;
43 import org.splat.dal.dao.som.ValidationCycleDAO;
44 import org.splat.kernel.InvalidPropertyException;
45 import org.splat.kernel.MissedPropertyException;
46 import org.splat.kernel.MultiplyDefinedException;
47 import org.splat.kernel.UserDirectory;
48 import org.splat.log.AppLogger;
49 import org.splat.service.technical.IndexService;
50 import org.splat.service.technical.ProjectSettingsService;
51 import org.splat.som.Revision;
52 import org.springframework.transaction.annotation.Transactional;
53
54 /**
55  * This class defines all methods for creation, modification the study.
56  * 
57  * @author Maria KRUCHININA
58  * 
59  */
60 public class StudyServiceImpl implements StudyService {
61
62         /**
63          * logger for the service.
64          */
65         public final static AppLogger logger = AppLogger
66                         .getLogger(StudyServiceImpl.class);
67
68         /**
69          * Injected index service.
70          */
71         private IndexService _indexService;
72
73         /**
74          * Injected step service.
75          */
76         private StepService _stepService;
77
78         /**
79          * Injected scenario service.
80          */
81         private ScenarioService _scenarioService;
82
83         /**
84          * Injected project service.
85          */
86         private ProjectSettingsService _projectSettingsService;
87
88         /**
89          * Injected project element service.
90          */
91         private ProjectElementService _projectElementService;
92
93         /**
94          * Injected study DAO.
95          */
96         private StudyDAO _studyDAO;
97
98         /**
99          * Injected scenario DAO.
100          */
101         private ScenarioDAO _scenarioDAO;
102
103         /**
104          * Injected validation cycle DAO.
105          */
106         private ValidationCycleDAO _validationCycleDAO;
107
108         /**
109          * Injected IDBuilder DAO.
110          */
111         private IDBuilderDAO _iDBuilderDAO;
112
113         /**
114          * {@inheritDoc}
115          * 
116          * @see org.splat.service.StudyService#selectStudy(long)
117          */
118         @Transactional
119         public Study selectStudy(long index) {
120                 Study result = getStudyDAO().get(index);
121                 result.loadWorkflow();
122                 return result;
123         }
124
125         /**
126          * Get study by its reference.
127          * 
128          * @param refid
129          *            the study reference
130          * @return found study or null
131          */
132         @Transactional(readOnly = true)
133         public Study selectStudy(String refid) {
134                 Study result = getStudyDAO().findByCriteria(
135                                 Restrictions.eq("sid", refid));
136                 result.loadWorkflow();
137                 return result;
138         }
139
140         /**
141          * {@inheritDoc}
142          * 
143          * @see org.splat.service.StudyService#createStudy(org.splat.dal.bo.som.Study.Properties)
144          */
145         @Transactional
146         public Study createStudy(Study.Properties sprop)
147                         throws MissedPropertyException, InvalidPropertyException,
148                         MultiplyDefinedException {
149                 sprop.setReference(getProjectSettings().getReferencePattern());
150                 Study study = new Study(sprop);
151
152                 buildReference(study);
153                 getStudyDAO().create(study);
154                 try {
155                         IndexService lucin = getIndex();
156                         lucin.add(study);
157                 } catch (IOException error) {
158                         logger.error("Unable to index the study '" + study.getIndex()
159                                         + "', reason:", error);
160                         // Continue and try to index later
161                 }
162                 return study;
163         }
164
165         /**
166          * {@inheritDoc}
167          * 
168          * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext.Properties)
169          */
170         public SimulationContext addProjectContext(Study aStudy,
171                         SimulationContext.Properties cprop) throws MissedPropertyException,
172                         InvalidPropertyException, MultiplyDefinedException {
173                 SimulationContext added = getStepService().addSimulationContext(
174                                 getProjectElementService().getFirstStep(aStudy), cprop);
175                 update(aStudy);
176                 return added;
177         }
178
179         /**
180          * {@inheritDoc}
181          * 
182          * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext)
183          */
184         public SimulationContext addProjectContext(Study aStudy,
185                         SimulationContext context) {
186                 SimulationContext added = getStepService().addSimulationContext(
187                                 getProjectElementService().getFirstStep(aStudy), context);
188                 update(aStudy);
189                 return added;
190         }
191
192         /**
193          * {@inheritDoc}
194          * 
195          * @see org.splat.service.StudyService#addContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User)
196          */
197         public boolean addContributor(Study aStudy, User user) {
198                 List<User> contributor = aStudy.getModifiableContributors(); // Initializes contributor
199                 for (Iterator<User> i = contributor.iterator(); i.hasNext();) {
200                         User present = i.next();
201                         if (present.equals(user))
202                                 return false;
203                 }
204                 boolean absent = aStudy.getModifiableActors().add(user); // User may already be a reviewer or an approver
205
206                 aStudy.addRelation(new ContributorRelation(aStudy, user));
207                 if (absent)
208                         update(aStudy); // Else, useless to re-index the study
209                 contributor.add(user);
210                 return true;
211         }
212
213         /**
214          * Moves this study from the Public to the Reference area of the repository. For being moved to the Reference area, the study must
215          * previously be approved.
216          * 
217          * @param aStudy
218          *            the study to move
219          * @return true if the move succeeded.
220          * @see #moveToPublic()
221          * @see #isPublic()
222          * @see Publication#approve(Date)
223          */
224         public boolean moveToReference(Study aStudy) {
225                 if (aStudy.getProgressState() != ProgressState.APPROVED)
226                         return false;
227                 if (aStudy.getVisibility() != Visibility.PUBLIC)
228                         return false;
229
230                 aStudy.setVisibility(Visibility.REFERENCE);
231                 if (update(aStudy)) {
232                         return updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
233                 }
234                 return false;
235         }
236
237         /**
238          * {@inheritDoc}
239          * 
240          * @see org.splat.service.StudyService#update(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Study.Properties)
241          */
242         public boolean update(Study aStudy, Properties sprop)
243                         throws InvalidPropertyException {
244                 if (sprop.getTitle() != null)
245                         aStudy.setTitle(sprop.getTitle());
246                 if (sprop.getSummary() != null)
247                         aStudy.setAttribute(new DescriptionAttribute(aStudy, sprop
248                                         .getSummary()));
249                 // TODO: To be completed
250                 return update(aStudy);
251         }
252
253         /**
254          * Check if the document is published in the study.
255          * 
256          * @param aStudy
257          *            the study
258          * @param doc
259          *            the document
260          * @return true if the document is published in the study
261          */
262         private boolean publishes(Study aStudy, Document doc) {
263                 if (!aStudy.publishes(doc)) {
264                         Scenario[] scene = aStudy.getScenarii();
265                         for (int i = 0; i < scene.length; i++) {
266                                 if (scene[i].publishes(doc))
267                                         return true;
268                         }
269                 }
270                 return false;
271         }
272
273         /**
274          * {@inheritDoc}
275          * 
276          * @see org.splat.service.StudyService#removeContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User[])
277          */
278         public boolean removeContributor(Study aStudy, User... users) {
279                 List<User> contributor = aStudy.getModifiableContributors(); // Initializes contributor
280                 Boolean done = false;
281                 for (int i = 0; i < users.length; i++) {
282                         User user = users[i];
283                         for (Iterator<User> j = contributor.iterator(); j.hasNext();) {
284                                 User present = j.next();
285                                 if (!present.equals(user))
286                                         continue;
287
288                                 aStudy.removeRelation(ContributorRelation.class, user);
289                                 j.remove(); // Updates the contributor shortcut
290                                 done = true;
291                                 break;
292                         }
293                 }
294                 if (done)
295                         update(aStudy);
296                 return done;
297         }
298
299         /**
300          * {@inheritDoc}
301          * 
302          * @see org.splat.service.StudyService#removeProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext)
303          */
304         public boolean removeProjectContext(Study aStudy, SimulationContext context) {
305                 boolean done = getStepService().removeSimulationContext(
306                                 getProjectElementService().getFirstStep(aStudy), context);
307                 update(aStudy);
308                 return done;
309         }
310
311         /**
312          * {@inheritDoc}
313          * 
314          * @see org.splat.service.StudyService#setValidationCycle(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.DocumentType,
315          *      org.splat.dal.bo.som.ValidationCycle.Properties)
316          */
317         @Transactional
318         public void setValidationCycle(Study aStudy, DocumentType type,
319                         ValidationCycle.Properties vprop) {
320                 HashMap<String, ValidationCycle> validactor = aStudy
321                                 .getValidationCycles();
322                 if (validactor == null)
323                         aStudy.setShortCuts(); // Initializes validactor and actor
324
325                 String cname = type.getName();
326                 ValidationCycle cycle = validactor.get(cname);
327
328                 if (cycle != null && cycle.isAssigned()) {
329                         cycle.resetActors(vprop);
330                 } else
331                         try {
332                                 cycle = new ValidationCycle(aStudy, vprop.setDocumentType(type));
333
334                                 getValidationCycleDAO().create(cycle); //RKV
335                                 
336                                 ValidationCycleRelation link = cycle.getContext();
337 //RKV:                          aStudy.addRelation(link);
338                                 aStudy.getAllRelations().add(link); //RKV
339                                 
340                                 validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
341                         } catch (Exception error) {
342                                 logger.error("Unable to re-index Knowledge Elements, reason:",
343                                                 error);
344                                 return;
345                         }
346                 resetActorsShortCut(aStudy);
347                 update(aStudy); // Re-index the study, just in case
348         }
349
350         /**
351          * Demotes this study from In-Check to In-Draft then In-Work states. This function is called internally when demoting the final result
352          * document of the study.
353          * 
354          * @param aStudy
355          *            a study to demote
356          * @return true if the demotion succeeded.
357          */
358         public boolean demote(Study aStudy) {
359                 if (aStudy.getProgressState() == ProgressState.inCHECK)
360                         aStudy.setProgressState(ProgressState.inDRAFT);
361                 else if (aStudy.getProgressState() == ProgressState.inDRAFT)
362                         aStudy.setProgressState(ProgressState.inWORK);
363                 else
364                         return false;
365                 return update(aStudy);
366         }
367
368         /**
369          * {@inheritDoc}
370          * 
371          * @see org.splat.service.StudyService#generateLocalIndex(org.splat.dal.bo.som.Study)
372          */
373         @Transactional
374         public int generateLocalIndex(Study aStudy) {
375                 aStudy.setLastLocalIndex(aStudy.getLastLocalIndex() + 1);
376                 getStudyDAO().update(aStudy);
377                 return aStudy.getLastLocalIndex();
378         }
379
380         /**
381          * {@inheritDoc}
382          * 
383          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
384          */
385         @Transactional
386         public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
387                         throws MissedPropertyException, InvalidPropertyException,
388                         MultiplyDefinedException {
389                 if (sprop.getManager() == null)
390                         sprop.setManager(aStudy.getAuthor());
391
392                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
393                 if (sprop.getBaseStep() != null)
394                         getScenarioService()
395                                         .copyContentsUpTo(scenario, sprop.getBaseStep());
396                 Scenario previous = sprop.getInsertAfter();
397
398                 if (previous == null) {
399                         aStudy.getScenariiList().add(scenario);
400                 } else {
401                         aStudy.getScenariiList().add(
402                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
403                 }
404                 getStudyDAO().update(aStudy); // No need to update the Lucene index
405                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
406                 if (sprop.getBaseStep() != null) {
407                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
408                         scenario.refresh(); // Because saving the scenario changes the hashcode of copied Publications
409                 }
410                 KnowledgeElementType ucase = KnowledgeElement.selectType("usecase");
411                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
412                 User admin = UserDirectory.selectUser(1); // First user created when creating the database
413                 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
414                                 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
415                 // knowledges
416                 getScenarioService().addKnowledgeElement(scenario, kprop);
417                 return scenario;
418         }
419
420         /**
421          * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states. This function is called internally when promoting the
422          * final result document of the study.
423          * 
424          * @param aStudy
425          *            a study to promote
426          * @return true if the demotion succeeded.
427          */
428         public boolean promote(Study aStudy) {
429                 if (aStudy.getProgressState() == ProgressState.inWORK) {
430                         aStudy.setProgressState(ProgressState.inDRAFT);
431                 } else if (aStudy.getProgressState() == ProgressState.inDRAFT) {
432                         aStudy.setProgressState(ProgressState.inCHECK);
433                         Revision myvers = new Revision(aStudy.getVersion());
434                         if (myvers.isMinor()) {
435                                 aStudy.setVersion(myvers.incrementAs(aStudy.getProgressState())
436                                                 .toString());
437                         }
438                 } else if (aStudy.getProgressState() == ProgressState.inCHECK) {
439                         aStudy.setProgressState(ProgressState.APPROVED);
440                 } else
441                         return false;
442
443                 return update(aStudy);
444         }
445
446         /**
447          * Moves this study from the Private to the Public area of the repository.
448          * 
449          * @param aStudy
450          *            a study to move
451          * @return true if the move succeeded.
452          * @see #isPublic()
453          */
454         public boolean moveToPublic(Study aStudy) {
455                 boolean isOk = false;
456                 if (aStudy.getVisibility() == Visibility.PRIVATE) {
457                         aStudy.setVisibility(Visibility.PUBLIC);
458                         if (update(aStudy)) {
459                                 isOk = updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
460                         }
461                 }
462                 return isOk;
463         }
464
465         /**
466          * Update a study in the database.
467          * 
468          * @param aStudy
469          *            the study to update
470          * @return true if the study is updated successfully
471          */
472         @Transactional
473         private boolean update(Study aStudy) {
474                 boolean isOk = false;
475                 try {
476                         getStudyDAO().update(aStudy); // Update of relational base
477                         getIndex().update(aStudy); // Update of Lucene index
478                         isOk = true;
479                 } catch (Exception error) {
480                         logger.error("Unable to re-index the study '" + aStudy.getIndex()
481                                         + "', reason:", error);
482                 }
483                 return isOk;
484         }
485
486         /**
487          * Build reference for the study. The reference of the study is stored as a new reference pattern (IDBuilder).
488          * 
489          * @param aStudy
490          *            the study
491          * @return true if reference building is succeded
492          */
493         @Transactional
494         private boolean buildReference(Study aStudy) {
495                 String pattern = aStudy.getReference(); // The study being supposed just created, its reference is the reference pattern
496                 IDBuilder tool = selectIDBuilder(aStudy.getDate());
497                 if (tool == null) {
498                         tool = new IDBuilder(aStudy.getDate());
499                         getIDBuilderDAO().create(tool);
500                 }
501                 aStudy.setReference(tool.buildReference(pattern, aStudy));
502                 return true;
503         }
504
505         /**
506          * Find an id builder by date.
507          * 
508          * @param date
509          *            the date
510          * @return found id builder
511          */
512         private IDBuilder selectIDBuilder(Date date) {
513                 Calendar aDate = Calendar.getInstance();
514                 aDate.setTime(date);
515                 return getIDBuilderDAO().findByCriteria(
516                                 Restrictions.eq("cycle", aDate.get(Calendar.YEAR)));
517         }
518
519         /**
520          * Fill transient collection ModifiableActors of the study.
521          * 
522          * @param aStudy
523          *            the study
524          */
525         private void resetActorsShortCut(Study aStudy) {
526                 aStudy.getModifiableActors().clear();
527                 // Get all actors involved in validation cycles
528                 for (Iterator<ValidationCycle> i = aStudy.getValidationCycles()
529                                 .values().iterator(); i.hasNext();) {
530                         ValidationCycle cycle = i.next();
531                         User[] user = cycle.getAllActors();
532                         for (int j = 0; j < user.length; j++)
533                                 aStudy.getModifiableActors().add(user[j]);
534                 }
535                 // Get all other actors
536                 for (Iterator<Relation> i = aStudy.getAllRelations().iterator(); i
537                                 .hasNext();) {
538                         Relation link = i.next();
539                         Class<?> kindof = link.getClass().getSuperclass();
540                         if (!kindof.equals(ActorRelation.class))
541                                 continue;
542                         aStudy.getModifiableActors().add(((ActorRelation) link).getTo());
543                 }
544         }
545
546         /**
547          * Update lucene index for the study knowledge elements.
548          * 
549          * @param aStudy
550          *            the study
551          * @return true if reindexing succeeded
552          */
553         private boolean updateKnowledgeElementsIndex(Study aStudy) {
554                 boolean isOk = false;
555                 try {
556                         IndexService lucin = getIndex();
557
558                         for (Iterator<Scenario> i = aStudy.getScenariiList().iterator(); i
559                                         .hasNext();) {
560                                 Scenario scene = i.next();
561                                 for (Iterator<KnowledgeElement> j = scene
562                                                 .getAllKnowledgeElements().iterator(); j.hasNext();) {
563                                         KnowledgeElement kelm = j.next();
564                                         lucin.update(kelm);
565                                 }
566                         }
567                         isOk = true;
568                 } catch (Exception error) {
569                         logger.error("Unable to re-index Knowledge Elements, reason:",
570                                         error);
571                 }
572                 return isOk;
573         }
574
575         /**
576          * Get lucene index service. Create a lucene index if it does not exist.
577          * 
578          * @return index service
579          * @throws IOException
580          *             if error occurs during lucene index creation
581          */
582         private IndexService getIndex() throws IOException {
583                 IndexService lucin = getIndexService();
584                 if (!lucin.exists())
585                         lucin.create(); // Happens when re-indexing all studies
586                 return lucin;
587         }
588
589         /**
590          * Get project settings.
591          * 
592          * @return Project settings service
593          */
594         private ProjectSettingsService getProjectSettings() {
595                 return _projectSettingsService;
596         }
597
598         /**
599          * Set project settings service.
600          * 
601          * @param projectSettingsService
602          *            project settings service
603          */
604         public void setProjectSettings(ProjectSettingsService projectSettingsService) {
605                 _projectSettingsService = projectSettingsService;
606         }
607
608         /**
609          * Get the projectElementService.
610          * 
611          * @return the projectElementService
612          */
613         public ProjectElementService getProjectElementService() {
614                 return _projectElementService;
615         }
616
617         /**
618          * Set the projectElementService.
619          * 
620          * @param projectElementService
621          *            the projectElementService to set
622          */
623         public void setProjectElementService(
624                         ProjectElementService projectElementService) {
625                 _projectElementService = projectElementService;
626         }
627
628         /**
629          * Get the stepService.
630          * 
631          * @return the stepService
632          */
633         public StepService getStepService() {
634                 return _stepService;
635         }
636
637         /**
638          * Set the stepService.
639          * 
640          * @param stepService
641          *            the stepService to set
642          */
643         public void setStepService(StepService stepService) {
644                 _stepService = stepService;
645         }
646
647         /**
648          * Get the indexService.
649          * 
650          * @return the indexService
651          */
652         public IndexService getIndexService() {
653                 return _indexService;
654         }
655
656         /**
657          * Set the indexService.
658          * 
659          * @param indexService
660          *            the indexService to set
661          */
662         public void setIndexService(IndexService indexService) {
663                 _indexService = indexService;
664         }
665
666         /**
667          * Get the studyDAO.
668          * 
669          * @return the studyDAO
670          */
671         public StudyDAO getStudyDAO() {
672                 return _studyDAO;
673         }
674
675         /**
676          * Set the studyDAO.
677          * 
678          * @param studyDAO
679          *            the studyDAO to set
680          */
681         public void setStudyDAO(StudyDAO studyDAO) {
682                 _studyDAO = studyDAO;
683         }
684
685         /**
686          * Get the iDBuilderDAO.
687          * 
688          * @return the iDBuilderDAO
689          */
690         public IDBuilderDAO getIDBuilderDAO() {
691                 return _iDBuilderDAO;
692         }
693
694         /**
695          * Set the iDBuilderDAO.
696          * 
697          * @param builderDAO
698          *            the iDBuilderDAO to set
699          */
700         public void setIDBuilderDAO(IDBuilderDAO builderDAO) {
701                 _iDBuilderDAO = builderDAO;
702         }
703
704         /**
705          * Get the scenarioService.
706          * 
707          * @return the scenarioService
708          */
709         public ScenarioService getScenarioService() {
710                 return _scenarioService;
711         }
712
713         /**
714          * Set the scenarioService.
715          * 
716          * @param scenarioService
717          *            the scenarioService to set
718          */
719         public void setScenarioService(ScenarioService scenarioService) {
720                 _scenarioService = scenarioService;
721         }
722
723         /**
724          * Get the scenarioDAO.
725          * 
726          * @return the scenarioDAO
727          */
728         public ScenarioDAO getScenarioDAO() {
729                 return _scenarioDAO;
730         }
731
732         /**
733          * Set the scenarioDAO.
734          * 
735          * @param scenarioDAO
736          *            the scenarioDAO to set
737          */
738         public void setScenarioDAO(ScenarioDAO scenarioDAO) {
739                 _scenarioDAO = scenarioDAO;
740         }
741
742         /**
743          * Get the validationCycleDAO.
744          * @return the validationCycleDAO
745          */
746         public ValidationCycleDAO getValidationCycleDAO() {
747                 return _validationCycleDAO;
748         }
749
750         /**
751          * Set the validationCycleDAO.
752          * @param validationCycleDAO the validationCycleDAO to set
753          */
754         public void setValidationCycleDAO(ValidationCycleDAO validationCycleDAO) {
755                 _validationCycleDAO = validationCycleDAO;
756         }
757 }