001: /*
002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
003: C/Oņa, 107 1š2 28050 Madrid (Spain)
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions
007: are met:
008:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011:
012: 2. The end-user documentation included with the redistribution,
013: if any, must include the following acknowledgment:
014: "This product includes software parts from hipergate
015: (http://www.hipergate.org/)."
016: Alternately, this acknowledgment may appear in the software itself,
017: if and wherever such third-party acknowledgments normally appear.
018:
019: 3. The name hipergate must not be used to endorse or promote products
020: derived from this software without prior written permission.
021: Products derived from this software may not be called hipergate,
022: nor may hipergate appear in their name, without prior written
023: permission.
024:
025: This library is distributed in the hope that it will be useful,
026: but WITHOUT ANY WARRANTY; without even the implied warranty of
027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
028:
029: You should have received a copy of hipergate License with this code;
030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
031: */
032:
033: package com.knowgate.scheduler;
034:
035: import java.lang.ref.SoftReference;
036:
037: import java.util.Date;
038: import java.util.Properties;
039:
040: import java.sql.Connection;
041: import java.sql.CallableStatement;
042: import java.sql.PreparedStatement;
043: import java.sql.Statement;
044: import java.sql.ResultSet;
045: import java.sql.SQLException;
046: import java.sql.Types;
047: import java.sql.Timestamp;
048:
049: import java.io.IOException;
050: import java.io.FileNotFoundException;
051: import java.io.File;
052: import java.io.FileWriter;
053:
054: import java.util.Properties;
055:
056: import javax.mail.MessagingException;
057:
058: import com.knowgate.debug.DebugFile;
059: import com.knowgate.jdc.JDCConnection;
060: import com.knowgate.misc.Environment;
061: import com.knowgate.misc.Gadgets;
062:
063: import com.knowgate.dataobjs.DB;
064: import com.knowgate.dataobjs.DBBind;
065: import com.knowgate.dataobjs.DBPersist;
066:
067: /**
068: * <p>Abstract base class for Job Commands Implementations</p>
069: * @author Sergio Montoro Ten
070: * @version 2.2
071: */
072: public abstract class Job extends DBPersist {
073: private Properties oParams;
074: private Properties oEnvProps;
075: private File oLogFile;
076: private DBBind oDataBind;
077:
078: protected int iPendingAtoms;
079:
080: public Job() {
081: super (DB.k_jobs, "Job");
082: oParams = null;
083: oEnvProps = null;
084: iPendingAtoms = 0;
085: oLogFile = null;
086: oDataBind = null;
087: }
088:
089: // ----------------------------------------------------------
090:
091: /**
092: * <p>Process an atom</p>
093: * Concrete atom processing implementation must be provided by each derived subclass.
094: * @param oAtm Atom to be processed
095: * @return Custom subclass defined Object
096: * @throws SQLException
097: * @throws FileNotFoundException
098: * @throws IOException
099: * @throws MessagingException
100: * @throws NullPointerException
101: */
102: public abstract Object process(Atom oAtm) throws SQLException,
103: FileNotFoundException, IOException, MessagingException,
104: NullPointerException;
105:
106: // ----------------------------------------------------------
107:
108: /**
109: * <p>This method must free all the resource allocated by a Job</p>
110: */
111: public abstract void free();
112:
113: // ----------------------------------------------------------
114:
115: /**
116: * <p>Count of atoms pending of processing for this Job</p>
117: * This count is decremented upon each successfull call to process() method
118: */
119: public int pending() {
120: return iPendingAtoms;
121: }
122:
123: // ----------------------------------------------------------
124:
125: public void abort(JDCConnection oConn) throws SQLException,
126: IllegalStateException {
127: if (DebugFile.trace) {
128: DebugFile.writeln("Begin Job.abort()");
129: DebugFile.incIdent();
130: DebugFile.writeln("gu_job="
131: + getStringNull(DB.gu_job, "null"));
132: }
133: short iStatus;
134: String sSQL;
135: PreparedStatement oUpdt;
136: PreparedStatement oStmt = oConn.prepareStatement("SELECT "
137: + DB.id_status + " FROM " + DB.k_jobs + " WHERE "
138: + DB.gu_job + "=?", ResultSet.TYPE_FORWARD_ONLY,
139: ResultSet.CONCUR_READ_ONLY);
140: oStmt.setString(1, getStringNull(DB.gu_job, null));
141: ResultSet oRSet = oStmt.executeQuery();
142: if (oRSet.next())
143: iStatus = oRSet.getShort(1);
144: else
145: iStatus = 100;
146: oRSet.close();
147: oStmt.close();
148: if (100 == iStatus)
149: throw new SQLException("Job "
150: + getStringNull(DB.gu_job, "null") + " not found");
151: if (Atom.STATUS_ABORTED == iStatus)
152: throw new IllegalStateException("Job "
153: + getStringNull(DB.gu_job, "null")
154: + " was already aborted");
155: else if (Atom.STATUS_FINISHED == iStatus)
156: throw new IllegalStateException("Job "
157: + getStringNull(DB.gu_job, "null")
158: + " was already finished");
159: sSQL = "UPDATE " + DB.k_job_atoms + " SET " + DB.id_status
160: + "=" + String.valueOf(Atom.STATUS_ABORTED) + ","
161: + DB.dt_execution + "=NULL WHERE " + DB.gu_job
162: + "=? AND " + DB.id_status + "<>"
163: + String.valueOf(Atom.STATUS_FINISHED);
164: if (DebugFile.trace)
165: DebugFile.writeln("Connection.prepareStatement(" + sSQL
166: + ")");
167: oUpdt = oConn.prepareStatement(sSQL);
168: oUpdt.setString(1, getStringNull(DB.gu_job, null));
169: oUpdt.executeUpdate();
170: oUpdt.close();
171: sSQL = "UPDATE " + DB.k_jobs + " SET " + DB.id_status + "="
172: + String.valueOf(Atom.STATUS_ABORTED) + ","
173: + DB.dt_finished + "=" + DBBind.Functions.GETDATE
174: + " WHERE " + DB.gu_job + "=?";
175: oUpdt = oConn.prepareStatement(sSQL);
176: oUpdt.setString(1, getStringNull(DB.gu_job, null));
177: oUpdt.executeUpdate();
178: oUpdt.close();
179: if (DebugFile.trace) {
180: DebugFile.decIdent();
181: DebugFile.writeln("End Job.abort()");
182: }
183: } // abort
184:
185: // ----------------------------------------------------------
186:
187: /**
188: * <p>Load Job</p>
189: * @param oConn Database Connection
190: * @param PKVals An Array with a single element containing the Job GUID
191: * @throws SQLException
192: */
193: public boolean load(JDCConnection oConn, Object[] PKVals)
194: throws SQLException {
195: boolean bRetVal;
196: String sList;
197: String sPageSet;
198: String sAttachImages;
199: Statement oStmt;
200: ResultSet oRSet;
201:
202: if (DebugFile.trace) {
203: DebugFile.writeln("Begin Job.load([Connection], Object[])");
204: DebugFile.incIdent();
205: }
206:
207: oParams = null;
208:
209: bRetVal = super .load(oConn, PKVals);
210:
211: if (bRetVal) {
212:
213: oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
214: ResultSet.CONCUR_READ_ONLY);
215:
216: try {
217: oStmt.setQueryTimeout(60);
218: } catch (SQLException sqle) {
219: }
220:
221: if (DebugFile.trace)
222: DebugFile
223: .writeln("Statement.executeQuery(SELECT COUNT(*) FROM "
224: + DB.k_job_atoms
225: + " WHERE "
226: + DB.gu_job
227: + "='"
228: + getStringNull(DB.gu_job, "null")
229: + "' AND ("
230: + DB.id_status
231: + "="
232: + String.valueOf(Atom.STATUS_PENDING)
233: + " OR "
234: + DB.id_status
235: + "="
236: + String.valueOf(Atom.STATUS_SUSPENDED)
237: + "))");
238:
239: oRSet = oStmt.executeQuery("SELECT COUNT(*) FROM "
240: + DB.k_job_atoms + " WHERE " + DB.gu_job + "='"
241: + getString(DB.gu_job) + "' AND (" + DB.id_status
242: + "=" + String.valueOf(Atom.STATUS_PENDING)
243: + " OR " + DB.id_status + "="
244: + String.valueOf(Atom.STATUS_SUSPENDED) + " OR "
245: + DB.id_status + "="
246: + String.valueOf(Atom.STATUS_RUNNING) + ")");
247: oRSet.next();
248: iPendingAtoms = oRSet.getInt(1);
249: oRSet.close();
250:
251: oStmt.close();
252:
253: if (DebugFile.trace)
254: DebugFile.writeln("pending atoms = "
255: + String.valueOf(iPendingAtoms));
256:
257: sPageSet = getParameter("gu_pageset");
258:
259: if (null != sPageSet) {
260:
261: oStmt = oConn.createStatement(
262: ResultSet.TYPE_FORWARD_ONLY,
263: ResultSet.CONCUR_READ_ONLY);
264:
265: oRSet = oStmt.executeQuery("SELECT " + DB.gu_workarea
266: + "," + DB.nm_pageset + " FROM "
267: + DB.k_pagesets + " WHERE " + DB.gu_pageset
268: + "='" + sPageSet + "'");
269:
270: if (oRSet.next()) {
271: oParams.put("gu_workarea", oRSet.getString(1));
272: oParams.put("nm_pageset", oRSet.getString(2));
273: } else {
274: bRetVal = false;
275: if (DebugFile.trace)
276: DebugFile.writeln("ERROR: PageSet " + sPageSet
277: + " referenced by job "
278: + getString(DB.gu_job)
279: + " was not found");
280: }
281: oRSet.close();
282: oStmt.close();
283:
284: } // fi (sPageSet)
285:
286: sList = getParameter("gu_list");
287:
288: if (null != sList) {
289:
290: oStmt = oConn.createStatement(
291: ResultSet.TYPE_FORWARD_ONLY,
292: ResultSet.CONCUR_READ_ONLY);
293:
294: oRSet = oStmt.executeQuery("SELECT " + DB.tx_sender
295: + "," + DB.tx_from + "," + DB.tx_reply + ","
296: + DB.tx_subject + " FROM " + DB.k_lists
297: + " WHERE " + DB.gu_list + "='" + sList + "'");
298:
299: if (oRSet.next()) {
300: oParams.put("tx_sender", oRSet.getString(1));
301: oParams.put("tx_from", oRSet.getString(2));
302: oParams.put("tx_reply", oRSet.getString(2));
303: oParams.put("tx_subject", oRSet.getString(2));
304: } else {
305: bRetVal = false;
306: if (DebugFile.trace)
307: DebugFile.writeln("ERROR: List " + sList
308: + " referenced by job "
309: + getString(DB.gu_job)
310: + " was not found");
311: }
312: oRSet.close();
313: oStmt.close();
314:
315: } // fi (sList)
316:
317: sAttachImages = getParameter("bo_attachimages");
318:
319: if (null == sAttachImages)
320: oParams.put("bo_attachimages", "1");
321: else
322: oParams.put("bo_attachimages", sAttachImages);
323:
324: } // fi (load(oConn, PKVals))
325:
326: if (DebugFile.trace) {
327: DebugFile.decIdent();
328: DebugFile.writeln("End Job.load() : "
329: + String.valueOf(bRetVal));
330: }
331:
332: return bRetVal;
333: } // load
334:
335: // ----------------------------------------------------------
336:
337: /**
338: * <p>Delete Job</p>
339: * @param oConn Database Connection
340: * @throws SQLException
341: */
342: public boolean delete(JDCConnection oConn) throws SQLException {
343: return Job.delete(oConn, getString(DB.gu_job));
344: }
345:
346: // ----------------------------------------------------------
347:
348: /**
349: * <p>Store Job</p>
350: * By default jobs are created with id_status=STATUS_PENDING
351: * @param oConn Database Connection
352: * @throws SQLException
353: */
354: public boolean store(JDCConnection oConn) throws SQLException {
355:
356: if (!AllVals.containsKey(DB.gu_job))
357: put(DB.gu_job, Gadgets.generateUUID());
358: else
359: put(DB.dt_modified, new Timestamp(new Date().getTime()));
360:
361: if (!AllVals.containsKey(DB.id_status))
362: put(DB.id_status, STATUS_PENDING);
363:
364: return super .store(oConn);
365: }
366:
367: // ----------------------------------------------------------
368:
369: /**
370: * <p>Get parameters extracted from tx_parameter field</p>
371: * @return Parameters as a java.util.Properties object
372: */
373:
374: public Properties getParameters() {
375: String aParams[];
376: int iParams;
377: int iDot;
378:
379: if (null == oParams) {
380: oParams = new Properties();
381: if (!isNull(DB.tx_parameters)) {
382: aParams = Gadgets.split(getString(DB.tx_parameters),
383: ",");
384: iParams = aParams.length;
385: for (int p = 0; p < iParams; p++) {
386: iDot = aParams[p].indexOf(':');
387: if (iDot <= 0)
388: oParams.put(aParams[p], "");
389: else
390: oParams.put(aParams[p].substring(0, iDot),
391: aParams[p].substring(iDot + 1));
392: } // next (p)
393: } // fi (!isNull(DB.tx_parameters))
394: } // fi (oParams)
395:
396: return oParams;
397: } // getParameters
398:
399: // ----------------------------------------------------------
400:
401: /**
402: * <p>Get parameter extracted from tx_parameter field</p>
403: * @param sParamName Parameter Name
404: * @return Parameter Value or <b>null</b> if not found
405: */
406: public String getParameter(String sParamName) {
407: return getParameters().getProperty(sParamName);
408: }
409:
410: /**
411: * <p>Get Environment Property</p>
412: * Environment properties are readed from hipergate.cnf.
413: * @param sPropertyName
414: * @return
415: */
416: public String getProperty(String sPropertyName) {
417: return oEnvProps.getProperty(sPropertyName);
418: }
419:
420: // ----------------------------------------------------------
421:
422: /**
423: * Get Environment Properties Collection
424: */
425: public Properties getProperties() {
426: return oEnvProps;
427: }
428:
429: // ----------------------------------------------------------
430:
431: /**
432: * <p>Get reference to Job log file</p>
433: * Job log file is placed at /storage/jobs/gu_workarea/
434: * @return Reference to Job Log File Object
435: */
436: public File logFile() {
437: return oLogFile;
438: }
439:
440: // ----------------------------------------------------------
441:
442: /**
443: * <p>Write Line to Job Log File</p>
444: * @param sStr Line to be written
445: */
446: public void log(String sStr) {
447: FileWriter oWriter;
448:
449: if (oLogFile != null) {
450: oWriter = null;
451: try {
452: oWriter = new FileWriter(oLogFile, true);
453: oWriter.write(sStr);
454: oWriter.close();
455: oWriter = null;
456: } catch (IOException ioe) {
457: if (null != oWriter) {
458: try {
459: oWriter.close();
460: } catch (IOException e) {
461: }
462: }
463: }
464: } // fi (oLogFile)
465: } // log
466:
467: // ----------------------------------------------------------
468:
469: /**
470: * Get database binding for this Job
471: * @return DBBind
472: */
473: public DBBind getDataBaseBind() {
474: return oDataBind;
475: }
476:
477: // ----------------------------------------------------------
478:
479: /**
480: * Assign a database binding to the Job
481: * @param oDbb DBBind
482: */
483: public void setDataBaseBind(DBBind oDbb) {
484: oDataBind = oDbb;
485: }
486:
487: // ----------------------------------------------------------
488:
489: /**
490: * <p>Set Job Status</p>
491: * If Status if set to Job.STATUS_FINISHED then dt_finished is set to current
492: * system date.
493: * @param oConn Database Connection
494: * @param iStatus Job Status
495: * <table border=1 cellpaddng=4>
496: * <tr><td>Status</td></tr>
497: * <tr><td align=middle>STATUS_ABORTED (-1)</td></tr>
498: * <tr><td align=middle>STATUS_FINISHED (0)</td></tr>
499: * <tr><td align=middle>STATUS_PENDING (1)</td></tr>
500: * <tr><td align=middle>STATUS_SUSPENDED (2)</td></tr>
501: * <tr><td align=middle>STATUS_RUNNING (3)</td></tr>
502: * </table>
503: * @throws SQLException
504: */
505: public void setStatus(JDCConnection oConn, int iStatus)
506: throws SQLException {
507:
508: PreparedStatement oStmt;
509:
510: if (DebugFile.trace) {
511: DebugFile.writeln("Begin Job.setStatus([Connection], "
512: + String.valueOf(iStatus) + ")");
513: DebugFile.incIdent();
514: }
515:
516: if (Job.STATUS_FINISHED == iStatus) {
517:
518: oStmt = oConn.prepareStatement("UPDATE " + DB.k_jobs
519: + " SET " + DB.id_status + "="
520: + String.valueOf(iStatus) + "," + DB.dt_finished
521: + "=? WHERE " + DB.gu_job + "='"
522: + getString(DB.gu_job) + "'");
523:
524: try {
525: oStmt.setQueryTimeout(10);
526: } catch (SQLException sqle) {
527: }
528:
529: oStmt.setTimestamp(1, new Timestamp(new java.util.Date()
530: .getTime()));
531: oStmt.executeUpdate();
532: oStmt.close();
533:
534: }
535:
536: else {
537:
538: oStmt = oConn.prepareStatement("UPDATE " + DB.k_jobs
539: + " SET " + DB.id_status + "="
540: + String.valueOf(iStatus) + " WHERE " + DB.gu_job
541: + "='" + getString(DB.gu_job) + "'");
542:
543: try {
544: oStmt.setQueryTimeout(10);
545: } catch (SQLException sqle) {
546: }
547:
548: oStmt.executeUpdate();
549: oStmt.close();
550:
551: }
552:
553: if (DebugFile.trace) {
554: DebugFile.decIdent();
555: DebugFile.writeln("End Job.setStatus()");
556: }
557: } // setStatus
558:
559: /**
560: * <p>Fills atoms data from their e-mails</p>
561: * This method call k_sp_resolve_atoms stored procedure which takes each atom
562: * mail address and looks it up at k_member_address table for completing name
563: * surname and other personalization data embedded into each atom's record
564: * @param oConn JDCConnection
565: * @throws SQLException
566: */
567: public void resolveAtomsEMails(JDCConnection oConn)
568: throws SQLException {
569: Statement oStmt;
570: CallableStatement oCall;
571: if (DebugFile.trace) {
572: DebugFile.writeln("Begin Job.resolveAtomsEMails()");
573: DebugFile.incIdent();
574: }
575: switch (oConn.getDataBaseProduct()) {
576: case JDCConnection.DBMS_POSTGRESQL:
577: oStmt = oConn.createStatement();
578: oStmt.executeQuery("SELECT k_sp_resolve_atoms('"
579: + getStringNull(DB.gu_job, null) + "')");
580: oStmt.close();
581: break;
582: default:
583: oCall = oConn.prepareCall("{ call k_sp_resolve_atoms('"
584: + getStringNull(DB.gu_job, null) + "') }");
585: oCall.execute();
586: oCall.close();
587: }
588: if (DebugFile.trace) {
589: DebugFile.decIdent();
590: DebugFile.writeln("End Job.resolveAtomsEMails()");
591: }
592: }
593:
594: // **********************************************************
595: // Static Methods
596:
597: /**
598: * <p>Delete Job</p>
599: * Call k_sp_del_job stored procedure
600: * @param oConn Database Connection
601: * @param sJobId GUID of Job to be deleted
602: * @throws SQLException
603: */
604: public static boolean delete(JDCConnection oConn, String sJobId)
605: throws SQLException {
606: Statement oStmt;
607: CallableStatement oCall;
608: boolean bRetVal;
609: if (DebugFile.trace) {
610: DebugFile.writeln("Begin Job.delete([Connection]," + sJobId
611: + ")");
612: DebugFile.incIdent();
613: }
614:
615: switch (oConn.getDataBaseProduct()) {
616: case JDCConnection.DBMS_POSTGRESQL:
617: oStmt = oConn.createStatement();
618: if (DebugFile.trace)
619: DebugFile
620: .writeln("Connection.executeQuery(SELECT k_sp_del_job ('"
621: + sJobId + "')");
622: oStmt
623: .executeQuery("SELECT k_sp_del_job ('" + sJobId
624: + "')");
625: oStmt.close();
626: bRetVal = true;
627: break;
628: default:
629: if (DebugFile.trace)
630: DebugFile
631: .writeln("Connection.prepareCall({ call k_sp_del_job ('"
632: + sJobId + "') }");
633: oCall = oConn.prepareCall("{ call k_sp_del_job ('" + sJobId
634: + "') }");
635: bRetVal = oCall.execute();
636: oCall.close();
637: }
638: if (DebugFile.trace) {
639: DebugFile.decIdent();
640: DebugFile.writeln("End Job.delete() : "
641: + String.valueOf(bRetVal));
642: }
643: return bRetVal;
644: } // delete
645:
646: // ----------------------------------------------------------
647:
648: /**
649: * <p>Create an instance of a Job subclass</p>
650: * <p>The new object class name will be readed form k_jobs.nm_class field.</p>
651: * @param oConn Database Connection
652: * @param sJobId GUID of Job to be deleted
653: * @param oEnvironmentProps Environment properties taken from hipergate.cnf
654: * @return Reference to Instantiated Object
655: * @throws FileNotFoundException If any directory for Job log file could not be created
656: * @throws ClassNotFoundException If no class with name k_jobs.nm_class was found
657: * @throws IllegalAccessException
658: * @throws InstantiationException
659: * @throws SQLException
660: */
661: public static synchronized Job instantiate(JDCConnection oConn,
662: String sJobId, Properties oEnvironmentProps)
663:
664: throws ClassNotFoundException, IllegalAccessException,
665: SQLException, InstantiationException, FileNotFoundException {
666:
667: Class oJobImplementation;
668: PreparedStatement oStmt;
669: ResultSet oRSet;
670: String sStorage;
671: String sCmmdId, sClassNm;
672: Job oRetObj;
673:
674: if (DebugFile.trace) {
675: DebugFile.writeln("Begin Job.instantiate([Connection],"
676: + sJobId + ")");
677: DebugFile.incIdent();
678: DebugFile
679: .writeln("Connection.prepareStatement(SELECT id_command,tx_command,nm_class FROM k_lu_job_commands WHERE id_command=(SELECT id_command FROM k_jobs WHERE gu_job='"
680: + sJobId + "'))");
681: }
682:
683: oStmt = oConn
684: .prepareStatement(
685: "SELECT id_command,tx_command,nm_class FROM k_lu_job_commands WHERE id_command=(SELECT id_command FROM k_jobs WHERE gu_job=?)",
686: ResultSet.TYPE_FORWARD_ONLY,
687: ResultSet.CONCUR_READ_ONLY);
688: oStmt.setString(1, sJobId);
689:
690: if (DebugFile.trace)
691: DebugFile
692: .writeln("PreparedStatementStatement.executeQuery()");
693:
694: oRSet = oStmt.executeQuery();
695:
696: if (oRSet.next()) {
697:
698: sCmmdId = oRSet.getString(1);
699:
700: if (DebugFile.trace)
701: DebugFile.writeln("Class Id =" + sCmmdId);
702:
703: sClassNm = oRSet.getString(3);
704:
705: if (DebugFile.trace)
706: DebugFile.writeln("Class Name =" + sClassNm);
707: } // fi (next())
708:
709: else {
710: sCmmdId = null;
711: sClassNm = "null";
712:
713: if (DebugFile.trace)
714: DebugFile.writeln("ERROR: job command id. not found");
715: }
716:
717: oRSet.close();
718: oStmt.close();
719:
720: if (null == sCmmdId)
721: oRetObj = null;
722: else {
723: if (DebugFile.trace)
724: DebugFile.writeln("Class.forName(" + sClassNm + ");");
725:
726: oJobImplementation = Class.forName(sClassNm);
727: oRetObj = (Job) oJobImplementation.newInstance();
728:
729: if (oRetObj.load(oConn, new Object[] { sJobId })) {
730: if (null != oConn.getPool()) {
731: if (DebugFile.trace)
732: DebugFile
733: .writeln("setting Job database binding");
734: oRetObj.setDataBaseBind((DBBind) oConn.getPool()
735: .getDatabaseBinding());
736: } else {
737: if (DebugFile.trace)
738: DebugFile
739: .writeln("Job has no database binding");
740: }
741: oRetObj.oEnvProps = oEnvironmentProps;
742: } else {
743: oRetObj = null;
744: }
745: } // fi (sCmmdId)
746:
747: if (null != oRetObj) {
748: sStorage = oEnvironmentProps.getProperty("storage");
749:
750: if (null != sStorage) {
751: if (!sStorage.endsWith(System
752: .getProperty("file.separator")))
753: sStorage += System.getProperty("file.separator");
754:
755: sStorage += "jobs";
756:
757: // Create directory storage/jobs
758:
759: oRetObj.oLogFile = new File(sStorage);
760: if (!oRetObj.oLogFile.exists())
761: oRetObj.oLogFile.mkdir();
762: if (!oRetObj.oLogFile.exists())
763: throw new FileNotFoundException(sStorage);
764:
765: // Create directory storage/jobs/gu_workarea
766:
767: sStorage += System.getProperty("file.separator")
768: + oRetObj.getString(DB.gu_workarea);
769: oRetObj.oLogFile = new File(sStorage);
770: if (!oRetObj.oLogFile.exists())
771: oRetObj.oLogFile.mkdir();
772: if (!oRetObj.oLogFile.exists())
773: throw new FileNotFoundException(sStorage);
774:
775: // Create directory storage/jobs/gu_workarea/gu_job
776: oRetObj.oLogFile = new File(sStorage
777: + System.getProperty("file.separator") + sJobId);
778: if (!oRetObj.oLogFile.exists())
779: oRetObj.oLogFile.mkdir();
780: if (!oRetObj.oLogFile.exists())
781: throw new FileNotFoundException(sStorage);
782:
783: // Set File Object to storage/jobs/gu_workarea/gu_job.txt
784: oRetObj.oLogFile = new File(sStorage
785: + System.getProperty("file.separator") + sJobId
786: + ".txt");
787:
788: } // fi (sStorage)
789: } // fi(oRetObj)
790:
791: if (DebugFile.trace) {
792: DebugFile.decIdent();
793: DebugFile.writeln("End Job.instantiate()");
794: }
795:
796: return oRetObj;
797: } // instantiate
798:
799: /**
800: * <p>Create an instance of a Job subclass</p>
801: * <p>The new object class name will be readed form k_jobs.nm_class field.</p>
802: * @param oConn Database Connection
803: * @param sJobId GUID of Job to be deleted
804: * @param sProfileName Name without .cnf extension of the properties file to use
805: * @return Reference to Instantiated Object
806: * @throws FileNotFoundException If any directory for Job log file could not be created
807: * @throws ClassNotFoundException If no class with name k_jobs.nm_class was found
808: * @throws IllegalAccessException
809: * @throws InstantiationException
810: * @throws SQLException
811: */
812: public static synchronized Job instantiate(JDCConnection oConn,
813: String sJobId, String sProfileName)
814: throws ClassNotFoundException, IllegalAccessException,
815: SQLException, InstantiationException, FileNotFoundException {
816: return instantiate(oConn, sJobId, Environment
817: .getProfile(sProfileName));
818: }
819:
820: // **********************************************************
821: // Static Methods
822:
823: private static void printUsage() {
824: System.out.println("");
825: System.out.println("Usage:");
826: System.out
827: .println("Job create job_type cnf_file_path xml_file_path [gu_job]");
828: System.out
829: .println("job_type is one of {MAIL | MIME | FAX | SAVE | FTP}");
830: }
831:
832: public static void main(String[] argv) throws SQLException,
833: org.xml.sax.SAXException, java.io.IOException,
834: ClassNotFoundException, IllegalAccessException,
835: InstantiationException {
836:
837: DBPersist oJob;
838: DBBind oDBB;
839: JDCConnection oCon;
840:
841: if (argv.length != 4 && argv.length != 5)
842: printUsage();
843: else if (!argv[0].equals("create"))
844: printUsage();
845:
846: else if (!argv[1].equalsIgnoreCase("MAIL")
847: && !argv[1].equalsIgnoreCase("FAX")
848: && !argv[1].equalsIgnoreCase("SAVE")
849: && !argv[1].equalsIgnoreCase("FTP")
850: && !argv[1].equalsIgnoreCase("MIME"))
851: printUsage();
852:
853: else {
854: oDBB = new DBBind(argv[2]);
855:
856: oCon = oDBB.getConnection("job_main");
857:
858: oJob = new DBPersist(DB.k_jobs, argv[1]);
859:
860: oJob.parseXML(argv[3]);
861:
862: if (argv.length == 5)
863: oJob.replace(DB.gu_job, argv[4]);
864:
865: else if (!oJob.getItemMap().containsKey(DB.gu_job))
866: oJob.put(DB.gu_job, com.knowgate.misc.Gadgets
867: .generateUUID());
868:
869: oJob.store(oCon);
870:
871: oCon.close();
872:
873: oDBB.close();
874:
875: System.out.println("gu_job:" + oJob.getString(DB.gu_job));
876: } // fi
877:
878: } // main
879:
880: // **********************************************************
881: // Public Constants
882:
883: public static final short STATUS_ABORTED = -1;
884: public static final short STATUS_FINISHED = 0;
885: public static final short STATUS_PENDING = 1;
886: public static final short STATUS_SUSPENDED = 2;
887: public static final short STATUS_RUNNING = 3;
888: public static final short STATUS_INTERRUPTED = 4;
889:
890: }
|