1    package com.instantbank.component.job.ejb;
2    
3    import java.util.ArrayList;
4    import java.util.Hashtable;
5    import java.util.Collection;
6    
7    import java.rmi.RemoteException;
8    import javax.ejb.EntityBean;
9    import javax.ejb.EntityContext;
10   import javax.ejb.EJBException;
11   import javax.ejb.FinderException;
12   import javax.ejb.CreateException;
13   import javax.ejb.DuplicateKeyException;
14   import javax.ejb.RemoveException;
15   
16   import com.instantbank.component.job.ejb.JobDAO;
17   import com.instantbank.component.job.model.JobModel;
18   import com.instantbank.component.job.model.JobSELECTelement;
19   import com.instantbank.component.job.model.JobWHEREelement;
20   import com.instantbank.component.job.model.JobORDERelement;
21   import com.instantbank.component.job.util.Alias;
22   import com.instantbank.component.job.util.Field;
23   import com.instantbank.component.job.util.ParticipantTable;
24   import com.instantbank.component.job.util.AuxGenerateSQLtext;
25   import com.instantbank.component.job.util.JoinElement;
26   
27   import com.instantbank.common.utilcomponents.DAOException;
28   import com.instantbank.common.utilcomponents.LetterTemplateGlobals;
29   import com.instantbank.common.utilcomponents.LetterTemplateExceptionMessage;
30   import com.instantbank.common.utilcomponents.Debug;
31   
32   /**
33    *  Entity BMP EJB for modeling a job (master-details)
34    *
35    * @author Instant-bank (Consuelo Franky)
36    * @created October 2002
37    */
38   public class JobEJB
39       implements EntityBean {
40   
41     // attributes corresponding to EJB state:
42     private JobModel jobModel;
43   
44     // others attributes:
45   
46     /**
47      *  entity context
48      */
49     private EntityContext context;
50   
51     /**
52      * JobDAO object for interacting with the database
53      */
54     private JobDAO jobDao;
55   
56     /**
57      * supports SQL sentence generation
58      */
59     private AuxGenerateSQLtext auxSQL;
60   
61     /**
62      * for debug
63      */
64     private Debug debug = null;
65   
66   
67     // CONSTRUCTOR :
68     /**
69      *  Constructor
70      */
71     public JobEJB() { }
72   
73   
74     // CONTEXT METHODS:
75     /**
76      *  Set session context
77      *
78      * @param sc The new sessionContext value
79      */
80     public void setEntityContext(EntityContext sc) {
81       debug = new Debug();
82       debug.setDebugginOn(true);
83       debug.setPreMessage("** JobEJB: ");
84       debug.println("setEntityContext");
85       this.context = sc;
86     }
87   
88   
89     public void unsetEntityContext() {
90       debug.println("unsetEntityContext");
91     }
92   
93   
94     /**
95      *  Actions after swapping
96      */
97     public void ejbActivate() {
98       debug.println("ejbActivate");
99       try {
100        getDao();
101      }
102      catch(DAOException se) {
103        throw new RuntimeException(se.getMessage());
104      }
105  
106      // reset primary key:
107      Long jobIDcontext = (Long)context.getPrimaryKey();
108      debug.println("jobIDcontext=" + jobIDcontext);
109      jobModel.setJobId(jobIDcontext);
110    }
111  
112  
113    /**
114     *  Actions before swapping
115     */
116    public void ejbPassivate() {
117      debug.println("ejbPassivate");
118      jobDao = null;
119      debug = null;
120      jobModel.setJobId(null);
121    }
122  
123  
124    // EJB METHODS:
125  
126    /**
127     *  Assigns value to the state of the new ejb instance,
128     *  in main memory and in the database.
129     *
130     * @param companyId current company
131     * @param userId current user
132     * @param name job name
133     * @param ftpPrimaryId a ftp location id of the company
134     *                          (it csn be LetterTemplateGlobals.UNDEF)
135     * @param ftpAlternateId an alternate ftp location id of the company
136     *                          (it csn be LetterTemplateGlobals.UNDEF)
137     * @return reference to the new instance EJB
138     * @exception CreateException
139     */
140    public Long ejbCreate(String companyId, Long userId, String name,
141                          long ftpPrimaryId, long ftpAlternateId)
142       throws CreateException {
143      debug.println("ejbCreate");
144  
145      Long jobId = null;
146  
147      // set the instance data:
148      jobModel = new JobModel
149        (null /* jobId */, companyId, name,
150        LetterTemplateGlobals.DEFAULT_JOB_FREQUENCY,
151        LetterTemplateGlobals.DEFAULT_JOB_STATUS, null /* activationDate */,
152        ftpPrimaryId, ftpAlternateId, userId, null /* version*/,
153        LetterTemplateGlobals.UNDEF /* templateCode */,
154        LetterTemplateGlobals.DEFAULT_QUEUE_TYPE, "" /* description */,
155        "" /* sqlText */, null /* lastExecutionDate */,
156      /* collections SELECT, WHERE, ORDER: */
157        null, null, null);
158  
159      try {
160        getDao();
161        jobDao.ejbCreate(jobModel);
162        jobModel = jobDao.getModel();
163        jobId = jobModel.getJobId();
164      }
165      catch(DAOException se) {
166        context.setRollbackOnly();
167        throw new CreateException(se.getMessage());
168      }
169      return jobId;
170    }
171  
172  
173    /**
174     *  Additional action after ejbCreate() method.
175     *
176     * @param companyId current company
177     * @param userId current user
178     * @param name job name
179     * @param ftpPrimaryId a ftp location id of the company
180     * @param ftpAlternateId an alternate ftp location id of the company
181     * @exception CreateException
182     */
183    public void ejbPostCreate(String companyId, Long userId, String name,
184                              long ftpPrimaryId, long ftpAlternateId)
185       throws CreateException {
186      debug.println("ejbPostCreate");
187    }
188  
189  
190    /**
191     *  Finds an existentf ejb instance in the database
192     *
193     * @param jobId key value of instance
194     * @return key value of ejb instance if it exists in the database
195     * @exception FinderException
196     */
197    public Long ejbFindByPrimaryKey(Long jobId) throws FinderException {
198      debug.println("ejbFindByPrimaryKey");
199      try {
200        getDao();
201        jobModel = new JobModel();
202        debug.println("jobModel instanced with new JobModel()");
203        Long jobIdanswer = jobDao.ejbFindByPrimaryKey(jobId);
204        jobModel.setJobId(jobIdanswer);
205        debug.println("jobModel.setJobId() executed");
206        return jobIdanswer;
207      }
208      catch(DAOException se) {
209        throw new FinderException(se.getMessage());
210      }
211    }
212  
213  
214    /**
215     *  Finds an existent ejb instance in the database
216     *
217     * @param companyId current company
218     * @param name job name
219     * @return reference to the instance EJB
220     * @exception FinderException
221     */
222    public Long ejbFindByName(String companyId, String name) throws FinderException {
223      debug.println("ejbFindByName");
224      try {
225        getDao();
226        jobModel = new JobModel();
227        debug.println("jobModel instanced with new JobModel()");
228        Long jobIdanswer = jobDao.ejbFindByName(companyId, name);
229        jobModel.setJobId(jobIdanswer);
230        debug.println("jobModel.setJobId() executed");
231        return jobIdanswer;
232      }
233      catch(DAOException se) {
234        throw new FinderException(se.getMessage());
235      }
236    }
237  
238  
239    /**
240     *  Removes ejb instance from the database.
241     *
242     * @exception RemoveException
243     */
244    public void ejbRemove() throws RemoveException {
245      debug.println("ejbRemove");
246      boolean jobWasDeleted;
247  
248      try {
249        getDao();
250        jobWasDeleted = jobDao.ejbRemove(jobModel.getJobId());
251        if(!jobWasDeleted) {
252          debug.println("before throw new DAOException");
253          throw new DAOException
254            (LetterTemplateExceptionMessage.PROBLEM_JOB_CANNOT_BE_DELETED);
255        }
256      }
257      catch(DAOException se) {
258        //context.setRollbackOnly();  it fails !
259        throw new RemoveException(se.getMessage());
260      }
261    }
262  
263  
264    /**
265     *  Loads from database state of ejb instance
266     */
267    public void ejbLoad() {
268      debug.println("ejbLoad");
269      try {
270        getDao();
271        jobDao.ejbLoad(jobModel.getJobId());
272        jobModel = jobDao.getModel();
273      }
274      catch(DAOException se) {
275        throw new EJBException(se.getMessage());
276      }
277    }
278  
279  
280    /**
281     *  Stores in database the state of ejb instance
282     */
283    public void ejbStore() {
284      debug.println("ejbStore");
285      try {
286        getDao();
287        jobDao.ejbStore(jobModel);
288        jobModel = jobDao.getModel();
289      }
290      catch(DAOException se) {
291        throw new EJBException(se.getMessage());
292      }
293    }
294  
295  
296    // BUSINESS METHODS :
297  
298    /**
299     *  Gets state value of ejb instance
300     *
301     * @return value of jobModel attribute
302     */
303    public JobModel getState() {
304      debug.println("getState");
305      jobDao.setJobMasterchanged(false);
306      jobDao.setJobSELECTchanged(false);
307      jobDao.setJobWHEREchanged(false);
308      jobDao.setJobORDERchanged(false);
309      return jobModel;
310    }
311  
312  
313    /**
314     *  Sets value to the state of ejb instance
315     *
316     * @param jobModel new value to assign to jobModel attribute
317     */
318    public void setState(JobModel jobModel) {
319      debug.println("setState");
320      this.jobModel = jobModel;
321      jobDao.setJobMasterchanged(true);
322      jobDao.setJobSELECTchanged(true);
323      jobDao.setJobWHEREchanged(true);
324      jobDao.setJobORDERchanged(true);
325    }
326  
327  
328    /**
329     *  Sets value to the templateCode of ejb instance
330     *  (updates state of ejb instance: jobModel.templateCode)
331     *
332     * @param templateCode new value to assign to templateCode
333     */
334    public void setTemplate(long templateCode) {
335      debug.println("setTemplate");
336      jobModel.setTemplateCode(templateCode);
337      jobDao.setJobMasterchanged(true);
338      jobDao.setJobSELECTchanged(false);
339      jobDao.setJobWHEREchanged(false);
340      jobDao.setJobORDERchanged(false);
341    }
342  
343  
344    /**
345     *  Sets value to the description of ejb instance
346     *  (updates state of ejb instance: jobModel.description)
347     *
348     * @param description new value to assign to description
349     */
350    public void setDescription(String description) {
351      debug.println("setDescription");
352      jobModel.setDescription(description);
353      jobDao.setJobMasterchanged(true);
354      jobDao.setJobSELECTchanged(false);
355      jobDao.setJobWHEREchanged(false);
356      jobDao.setJobORDERchanged(false);
357    }
358  
359  
360    /**
361     *  Sets value to the jobSELECT of ejb instance
362     *  (updates state of ejb instance: jobModel.jobSELECT)
363     *
364     * @param jobSELECT new value to assign to jobSELECT
365     */
366    public void setJobSELECT(Collection jobSELECT) {
367      debug.println("setJobSELECT");
368      jobModel.setJobSELECT(jobSELECT);
369      jobDao.setJobMasterchanged(true);  // last date changes
370      jobDao.setJobSELECTchanged(true);
371      jobDao.setJobWHEREchanged(false);
372      jobDao.setJobORDERchanged(false);
373    }
374  
375  
376    /**
377     *  Sets value to the jobWHERE of ejb instance
378     *  (updates state of ejb instance: jobModel.jobWHERE)
379     *
380     * @param jobWHERE new value to assign to jobWHERE
381     */
382    public void setJobWHERE(Collection jobWHERE) {
383      debug.println("setJobWHERE");
384      jobModel.setJobWHERE(jobWHERE);
385      jobDao.setJobMasterchanged(true);  // last date changes
386      jobDao.setJobSELECTchanged(false);
387      jobDao.setJobWHEREchanged(true);
388      jobDao.setJobORDERchanged(false);
389    }
390  
391  
392    /**
393     *  Sets value to the jobORDER of ejb instance
394     *  (updates state of ejb instance: jobModel.jobORDER)
395     *
396     * @param jobORDER new value to assign to jobORDER
397     */
398    public void setJobORDER(Collection jobORDER) {
399      debug.println("setJobORDER");
400      jobModel.setJobORDER(jobORDER);
401      jobDao.setJobMasterchanged(true);  // last date changes
402      jobDao.setJobSELECTchanged(false);
403      jobDao.setJobWHEREchanged(false);
404      jobDao.setJobORDERchanged(true);
405    }
406  
407  
408    /**
409     *  Generate sqlText associated to the job
410     *  (updates state of ejb instance: jobModel.sqlText)
411     *
412     * @param systemFields Hashtable of system Fields for current company
413     *                        key: fieldId (in Long), value: Field object
414     * @param systemAlias Hashtable of system Alias
415     *                        key: String = tableAlias|rootType
416     *                        value: Alias object
417     * @param rootType root type for joins
418     * @return sql text generated
419     */
420    public String generateSQLtext(Hashtable systemFields,
421                                  Hashtable systemAlias, String rootType) {
422      debug.println("generateSQLtext");
423      String answer = "";
424      ArrayList participantTables = new ArrayList();
425  
426      auxSQL = new AuxGenerateSQLtext(systemFields, systemAlias, rootType);
427  
428      String strSELECT = buildSELECT();
429      String strWHERE_JOINS = buildWHERE_JOINS(participantTables);
430      String strWHERE_CONDITIONS = buildWHERE_CONDITIONS();
431      String strFROM = buildFROM(participantTables);
432      String strORDER = buildORDER();
433      String strWHERE = (!strWHERE_JOINS.equals(""))
434        ? " WHERE " + strWHERE_JOINS + " AND " + strWHERE_CONDITIONS
435        : " WHERE " + strWHERE_CONDITIONS;
436  
437      answer = strSELECT
438        + strFROM
439        + strWHERE
440        + strORDER;
441  
442      jobModel.setSqlText(answer);
443      jobDao.setJobMasterchanged(true);
444      jobDao.setJobSELECTchanged(false);
445      jobDao.setJobWHEREchanged(false);
446      jobDao.setJobORDERchanged(false);
447      return answer;
448    }
449  
450  
451    // AUXILIARY METHODS :
452  
453    /**
454     *  Generate job sqlText corresponding to SELECT part
455     *
456     * @return sql text generated for SELECT part
457     */
458    private String buildSELECT() {
459      debug.println("buildSELECT");
460      JobSELECTelement element;
461      String answer = "SELECT UNIQUE " + auxSQL.beginSELECT();
462      ArrayList jobSELECT = (ArrayList)jobModel.getJobSELECT();
463      int sizeSELECT = (jobSELECT != null) ? jobSELECT.size() : 0;
464      answer += (sizeSELECT > 0) ? ", " : "";
465  
466      for(int i = 0; i < sizeSELECT; i++) {
467        element = (JobSELECTelement)(jobSELECT.get(i));
468        long fieldId = element.getFieldId();
469        String alias = auxSQL.alias(fieldId);
470        if(alias.equals(LetterTemplateGlobals.SYSDATE)) {
471          answer += " TRUNC(" + alias + ")";
472        }
473        else {
474          answer += " "
475            + alias
476            + "."
477            + auxSQL.fieldColumn(fieldId)
478            + " "
479            + auxSQL.rename(fieldId)
480            ;
481        }
482        answer += (i != sizeSELECT - 1) ? "," : "";
483      }
484      return answer;
485    }
486  
487  
488    /**
489     *  Generate job sqlText corresponding to WHERE join part
490     *
491     * @param participantTables output ArrayList of tables that participate in
492     *                        the SQL sentence (initially empty for this method);
493     *                        type of each element: ParticipantTable.
494     * @return sql text generated for WHERE join part
495     */
496    private String buildWHERE_JOINS(ArrayList participantTables) {
497      debug.println("buildWHERE_JOINS");
498      ArrayList joinList = new ArrayList();
499      JoinElement joinElement = null;
500      int posInsert;
501      int posLastInsert;
502      ParticipantTable participantTable = null;
503      String alias;
504      boolean joinCheck;
505  
506      String answer = "";
507  
508      // build participantTables from jobWHERE and jobSELECT:
509  
510      String aliasRoot = auxSQL.rootParticipant();
511      participantTables.add(new ParticipantTable(aliasRoot, true));
512      debug.println("participantTables.add with true: " + aliasRoot);
513  
514      ArrayList jobWHERE = (ArrayList)jobModel.getJobWHERE();
515      int sizeWHERE = (jobWHERE != null) ? jobWHERE.size() : 0;
516      for(int i = 0; i < sizeWHERE; i++) {
517        JobWHEREelement element = (JobWHEREelement)(jobWHERE.get(i));
518        long fieldId = element.getFieldId();
519        alias = auxSQL.alias(fieldId);
520        if(auxSQL.findAlias(participantTables, alias) < 0) {
521          participantTables.add(new ParticipantTable(alias, false));
522          debug.println("participantTables.add with false: " + alias);
523        }
524      }
525  
526      ArrayList jobSELECT = (ArrayList)jobModel.getJobSELECT();
527      int sizeSELECT = jobSELECT.size();
528      for(int i = 0; i < sizeSELECT; i++) {
529        JobSELECTelement element = (JobSELECTelement)(jobSELECT.get(i));
530        long fieldId = element.getFieldId();
531        alias = auxSQL.alias(fieldId);
532        if(!alias.equals(LetterTemplateGlobals.SYSDATE)
533          && auxSQL.findAlias(participantTables, alias) < 0) {
534          participantTables.add(new ParticipantTable(alias, false));
535          debug.println("participantTables.add with false: " + alias);
536        }
537      }
538  
539      // build joinList :
540  
541      for(int i = 0; i < participantTables.size(); i++) {
542        participantTable = (ParticipantTable)(participantTables.get(i));
543        alias = participantTable.getAlias();
544        joinCheck = participantTable.getJoinCheck();
545  
546        if(!joinCheck) {
547          participantTable.setJoinCheck(true);
548          joinElement = auxSQL.buildJoinElement(alias);
549          int posFound = auxSQL.findParent(joinList, alias);
550          if(posFound >= 0) {  // ancestors were already inserted in joinList
551            joinList.add(posFound + 1, joinElement);
552          }
553          else {  // ancestors must be inserted in joinList
554            joinList.add(joinElement);
555            posLastInsert = joinList.size() - 1;
556  
557            String aliasParent = auxSQL.parentTableAlias(alias);
558            int k = i;  // k will be the index of aliasParent in participantTables
559            while(!aliasParent.equals(aliasRoot)) {
560              int j = auxSQL.findAlias(participantTables, aliasParent);
561              if(j < 0) {
562                participantTables.add(k + 1, new ParticipantTable(aliasParent, false));
563                debug.println("aliasParent " + aliasParent
564                  + " added to participantTables with false");
565                k = k + 1;
566              }
567              else {
568                k = j;
569              }
570              participantTable = (ParticipantTable)(participantTables.get(k));
571              alias = participantTable.getAlias();
572              participantTable.setJoinCheck(true);
573              joinElement = auxSQL.buildJoinElement(alias);
574              posInsert = (posLastInsert == 0) ? 0 : (posLastInsert - 1);
575              joinList.add(posInsert, joinElement);
576              posLastInsert = posInsert;
577              aliasParent = auxSQL.parentTableAlias(alias);
578            }
579          }
580        }
581      }
582  
583      // build answer string:
584  
585      int sizeJoinList = joinList.size();
586  
587      for(int i = 0; i < sizeJoinList; i++) {
588        joinElement = (JoinElement)(joinList.get(i));
589        String parentAlias = joinElement.getParentAlias();
590        String parentColumn = joinElement.getParentColumn();
591        String sonAlias = joinElement.getSonAlias();
592        String sonColumn = joinElement.getSonColumn();
593        String joinType = joinElement.getJoinType();
594        answer += " ("
595          + parentAlias
596          + "."
597          + parentColumn
598          + " = "
599          + sonAlias
600          + "."
601          + sonColumn
602          + " "
603          + joinType
604          + ")"
605          ;
606        answer += (i != sizeJoinList - 1) ? " AND " : "";
607      }
608      return answer;
609    }
610  
611  
612    /**
613     *  Generate job sqlText corresponding to WHERE conditions part
614     *
615     * @return sql text generated for WHERE conditions part
616     */
617    private String buildWHERE_CONDITIONS() {
618      debug.println("buildWHERE_CONDITIONS");
619      JobWHEREelement element;
620  
621      String answer = "";
622  
623      ArrayList jobWHERE = (ArrayList)jobModel.getJobWHERE();
624      int sizeWHERE = (jobWHERE != null) ? jobWHERE.size() : 0;
625  
626      if(sizeWHERE > 0) {
627        answer += " (((";
628      }
629  
630      for(int i = 0; i < sizeWHERE; i++) {
631        element = (JobWHEREelement)(jobWHERE.get(i));
632        long fieldId = element.getFieldId();
633        String ruleOperator = element.getRuleOperator();
634        String value = element.getValue();
635        String connector = element.getConnector();
636  
637        String condition =
638          auxSQL.alias(fieldId)
639          + "."
640          + auxSQL.fieldColumn(fieldId)
641          + " "
642          + ruleOperator
643          + " "
644          + auxSQL.value(value, ruleOperator, fieldId);
645  
646        if(connector.equals(LetterTemplateGlobals.OR_CONNECTOR)) {
647          answer += condition + " OR ";
648        }
649        else if(connector.equals(LetterTemplateGlobals.AND_CONNECTOR)) {
650          answer += condition + ") AND (";
651        }
652        else if(connector.equals(LetterTemplateGlobals.ORTHE_CONNECTOR)) {
653          answer += condition + ")) OR ((";
654        }
655        else if(connector.equals(LetterTemplateGlobals.EMPTY_CONNECTOR)
656          && (i != sizeWHERE - 1)) {
657          answer += condition + "))) AND (((";
658        }
659        else {  // empty connector && and last condition
660          answer += condition + ")))";
661        }
662      }
663  
664      answer += (answer.equals("")) ? "" : " AND ";
665      answer += auxSQL.endWHERE(jobModel.getCompanyId());
666      return answer;
667    }
668  
669  
670    /**
671     *  Generate job sqlText corresponding to FROM part
672     *
673     * @param participantTables ArrayList of tables that participate in the
674     *                        SQL sentence;
675     *                        type of each element: ParticipantTable.
676     * @return sql text generated for FROM part
677     */
678    private String buildFROM(ArrayList participantTables) {
679      debug.println("buildFROM");
680      ParticipantTable element;
681      String elementFROM;
682      String answer = " FROM ";
683  
684      int sizeParticipants = participantTables.size();
685      for(int i = 0; i < sizeParticipants; i++) {
686        element = (ParticipantTable)(participantTables.get(i));
687        String alias = element.getAlias();
688        if((auxSQL.category(alias))
689          .equals(LetterTemplateGlobals.NORMAL_FIELDS)) {
690          elementFROM = " " + auxSQL.realTable(alias);
691        }
692        else if((auxSQL.category(alias))
693          .equals(LetterTemplateGlobals.TEMPORAL_FIELDS)) {
694          elementFROM = " (" + auxSQL.builtTable(alias) + ") " + alias;
695        }
696        else {  // LetterTemplateGlobals.DERIVED_FIELDS category
697          elementFROM = " " + auxSQL.realTable(alias) + " " + alias;
698        }
699        answer += elementFROM;
700        answer += (i != sizeParticipants - 1) ? "," : "";
701      }
702      return answer;
703    }
704  
705  
706    /**
707     *  Generate job sqlText corresponding to ORDER part.
708     *  It is assumed that the set of jobORDER elements is the same set
709     *  of jobSELECT elements (therefore, jobORDER is not empty and it does not
710     *  add new participant tables with respect to jobSELECT).
711     *
712     * @return sql text generated for ORDER  part
713     */
714    private String buildORDER() {
715      debug.println("buildORDER");
716      JobORDERelement element;
717      String answer = "";
718  
719      ArrayList jobORDER = (ArrayList)jobModel.getJobORDER();
720      int sizeORDER = (jobORDER != null) ? jobORDER.size() : 0;
721      answer += (sizeORDER > 0) ? " ORDER BY " : "";
722  
723      for(int i = 0; i < sizeORDER; i++) {
724        element = (JobORDERelement)(jobORDER.get(i));
725        long fieldId = element.getFieldId();
726        String direction = element.getDirection();
727        String alias = auxSQL.alias(fieldId);
728        if(alias.equals(LetterTemplateGlobals.SYSDATE)) {
729          answer += " " + alias + " " + auxSQL.direction(direction);
730        }
731        else {
732          answer += " "
733            + alias
734            + "."
735            + auxSQL.fieldColumn(fieldId)
736            + " "
737            + auxSQL.direction(direction)
738            ;
739        }
740        answer += (i != sizeORDER - 1) ? "," : "";
741      }
742      return answer;
743    }
744  
745  
746    /**
747     *  Obtains a DAO instance assigning it to jobDao attribute
748     *
749     * @return The dao value
750     * @exception DAOException
751     */
752    private JobDAO getDao()
753       throws DAOException {
754      if(jobDao == null) {
755        jobDao = new JobDAO();
756      }
757      return jobDao;
758    }
759  }
760  
761