001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.servlets;
021:
022: import java.io.ByteArrayOutputStream;
023: import java.io.IOException;
024: import java.io.ObjectInputStream;
025: import java.io.ObjectOutputStream;
026: import java.io.OutputStream;
027: import java.util.Enumeration;
028: import java.util.Hashtable;
029: import java.util.Properties;
030: import java.util.StringTokenizer;
031: import java.util.Vector;
032: import java.util.zip.DeflaterOutputStream;
033:
034: import javax.servlet.ServletConfig;
035: import javax.servlet.ServletException;
036: import javax.servlet.http.HttpServlet;
037: import javax.servlet.http.HttpServletRequest;
038: import javax.servlet.http.HttpServletResponse;
039: import javax.servlet.http.HttpSession;
040:
041: import com.salmonllc.jsp.JspServlet;
042: import com.salmonllc.properties.Props;
043: import com.salmonllc.sql.ColumnDefinition;
044: import com.salmonllc.sql.DBConnection;
045: import com.salmonllc.sql.DSDataRow;
046: import com.salmonllc.sql.DataStore;
047: import com.salmonllc.sql.DataStoreBuffer;
048: import com.salmonllc.sql.DataStoreException;
049: import com.salmonllc.sql.DataStoreProxy;
050: import com.salmonllc.sql.DataStoreRow;
051: import com.salmonllc.sql.ProxyBeanDataStoreAdaptor;
052: import com.salmonllc.sql.ValidationRule;
053: import com.salmonllc.util.MessageLog;
054: import com.salmonllc.util.URLGenerator;
055:
056: /**
057: * This servlet works in conjunction with the ProxyDatastore and RemoteDataStore to provide database access to applets.
058: */
059: public class DataServer extends HttpServlet {
060:
061: private static final int OP_COMMIT = 0;
062: private static final int OP_ROLLBACK = 1;
063: private static final int OP_FREE = 2;
064:
065: public DataServer() {
066: super ();
067: }
068:
069: private boolean checkRequest(DataStoreBuffer rem, String op,
070: HttpServletRequest req, boolean sessValid, String userID,
071: String pw, String criteria) throws DataStoreException {
072: if (!(rem instanceof com.salmonllc.sql.Remotable))
073: return false;
074:
075: boolean retVal = ((com.salmonllc.sql.Remotable) rem).request(
076: op, req, sessValid, userID, pw, criteria);
077: if (!retVal) {
078: Props p = Props.getSystemProps();
079: if (!p.getBooleanProperty(Props.SYS_DATASERVER_SECURITY))
080: retVal = true;
081: }
082: return retVal;
083: }
084:
085: private void doUpdate(HttpServletRequest req,
086: HttpServletResponse res, boolean sessValid, String userID,
087: String pw, String criteria, HttpSession sess,
088: ObjectInputStream in, ObjectOutputStream out,
089: boolean keepDataOnServer) {
090: Vector v = new Vector();
091: DataStore ds = null;
092: try {
093: boolean eof = false;
094: while (!eof) {
095: Object o = in.readObject();
096: if (o instanceof Character) {
097: char c = ((Character) o).charValue();
098: if (c == 'N') {
099: o = in.readObject();
100: ds = getDataStore(sess, o.toString());
101: if (ds == null) {
102: setStatus(
103: res,
104: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
105: out.writeObject(new DataStoreException(
106: "DataStore Not Found:" + o));
107: return;
108: } else if (!checkRequest(ds,
109: DataStoreProxy.OPERATION_UPDATE, req,
110: sessValid, userID, pw, criteria)) {
111: setStatus(
112: res,
113: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
114: out.writeObject(new DataStoreException(
115: "Access Denied:" + o));
116: return;
117: }
118: ds.reset();
119: v.addElement(ds);
120: } else if (c == 'I') {
121: //insert
122: int localRow = ds.insertRow();
123: Integer proxyRow = (Integer) in.readObject();
124: DataStoreRow row = ds.getDataStoreRow(localRow,
125: DataStoreBuffer.BUFFER_STANDARD);
126: row.getDSDataRow().setProxyRow(
127: proxyRow.intValue());
128: for (int i = 0; i < ds.getColumnCount(); i++) {
129: Integer status = (Integer) in.readObject();
130: ds.setAny(i, in.readObject());
131: ds
132: .setTempValue(i, (String) in
133: .readObject());
134: row.getDSDataRow().setColumnStatus(i,
135: status.intValue());
136: }
137: } else if (c == 'U') {
138: //update
139: ds.insertRow();
140: Integer proxyRow = (Integer) in.readObject();
141: int rNo = ds.getRowCount() - 1;
142: for (int i = 0; i < ds.getColumnCount(); i++) {
143: if (ds.isPrimaryKey(i)
144: || (ds.getConcurrencyCheckColumn(i) && ds
145: .getCheckConcurrency()))
146: ds.setAny(i, in.readObject());
147: }
148: DataStoreRow row = ds.getDataStoreRow(rNo,
149: DataStoreBuffer.BUFFER_STANDARD);
150: DSDataRow dsRow = row.getDSDataRow();
151: row.getDSDataRow().setProxyRow(
152: proxyRow.intValue());
153: row.resetStatus();
154:
155: for (int i = 0; i < ds.getColumnCount(); i++) {
156: Integer status = (Integer) in.readObject();
157: Object data = in.readObject();
158: ds.setAny(i, data);
159: ds
160: .setTempValue(i, (String) in
161: .readObject());
162: dsRow.setColumnStatus(i, status.intValue());
163: }
164: } else if (c == 'D') {
165: //delete
166: ds.insertRow();
167: Integer proxyRow = (Integer) in.readObject();
168: int rNo = ds.getRowCount() - 1;
169: for (int i = 0; i < ds.getColumnCount(); i++) {
170: if (ds.isPrimaryKey(i)
171: || (ds.getConcurrencyCheckColumn(i) && ds
172: .getCheckConcurrency()))
173: ds.setAny(i, in.readObject());
174: }
175: DataStoreRow row = ds.getDataStoreRow(rNo,
176: DataStoreBuffer.BUFFER_STANDARD);
177: row.getDSDataRow().setProxyRow(
178: proxyRow.intValue());
179: row.resetStatus();
180: ds.deleteRow();
181: } else if (c == 'Z') {
182: //commit changes
183: Hashtable connections = new Hashtable();
184: int i = 0;
185: try {
186: DBConnection conn = null;
187: for (i = 0; i < v.size(); i++) {
188: ds = (DataStore) v.elementAt(i);
189: if (ds instanceof ProxyBeanDataStoreAdaptor)
190: ds.update();
191: else {
192: String key = ds.getAppName()
193: + ds.getDbProfile();
194: if (connections.containsKey(key))
195: conn = (DBConnection) connections
196: .get(key);
197: else {
198: conn = DBConnection
199: .getConnection(
200: ds.getAppName(),
201: ds
202: .getDbProfile());
203: connections.put(key, conn);
204: conn.beginTransaction();
205: }
206: ds.update(conn);
207: }
208: }
209: updateConnections(connections, OP_COMMIT);
210: setStatus(res,
211: DataStoreProxy.REMOTE_STATUS_OK);
212: for (i = 0; i < v.size(); i++) {
213: ds = (DataStore) v.elementAt(i);
214: String retVal = ds
215: .getRemoteUpdateReturnValue();
216: if (retVal == null)
217: retVal = "OK";
218: out.writeObject(new Character('S'));
219: out.writeObject(retVal);
220: if (ds.gotoFirst()) {
221: do {
222: if (ds.getRowStatus() == DataStore.STATUS_MODIFIED
223: || ds.getRowStatus() == DataStore.STATUS_NEW_MODIFIED) {
224: out
225: .writeObject(new Character(
226: 'R'));
227: DSDataRow row = ds
228: .getDataStoreRow(
229: ds.getRow(),
230: DataStore.BUFFER_STANDARD)
231: .getDSDataRow();
232: out
233: .writeObject(new Integer(
234: row
235: .getProxyRow()));
236: for (int j = 0; j < ds
237: .getColumnCount(); j++) {
238: if (row
239: .getColumnStatus(j) == DataStore.STATUS_MODIFIED) {
240: out
241: .writeObject(new Integer(
242: j));
243: out
244: .writeObject(row
245: .getData(j));
246: }
247: }
248: out
249: .writeObject(new Character(
250: 'T'));
251: }
252: } while (ds.gotoNext());
253: }
254: out.writeObject(new Character('E'));
255: }
256: out.writeObject(new Character('X'));
257: } catch (DataStoreException e) {
258: updateConnections(connections, OP_ROLLBACK);
259: setStatus(
260: res,
261: DataStoreProxy.REMOTE_STATUS_SQL_ERROR);
262: e.setDataStoreNo(i);
263: if (e.getRow() > -1) {
264: DSDataRow row = ds.getDataStoreRow(
265: e.getRow(),
266: DataStore.BUFFER_STANDARD)
267: .getDSDataRow();
268: e.setRowNo(row.getProxyRow());
269: }
270: out.writeObject(e);
271: //MessageLog.writeErrorMessage("doUpdate:" + ds.getRemoteID(), e, this);
272: return;
273: } catch (Exception e) {
274: updateConnections(connections, OP_ROLLBACK);
275: setStatus(
276: res,
277: DataStoreProxy.REMOTE_STATUS_SQL_ERROR);
278: DataStoreException ex = new DataStoreException(
279: e.getMessage(), e, i);
280: out.writeObject(ex);
281: MessageLog.writeErrorMessage("doUpdate:"
282: + ds.getRemoteID(), e, this );
283: return;
284: } finally {
285: updateConnections(connections, OP_FREE);
286: for (i = 0; i < v.size(); i++) {
287: ds = (DataStore) v.elementAt(i);
288: if (!keepDataOnServer)
289: ds.reset();
290: }
291:
292: }
293: eof = true;
294: }
295: }
296: }
297: } catch (Exception e) {
298: MessageLog.writeErrorMessage(
299: "doUpdate:" + ds.getRemoteID(), e, this );
300: if (!keepDataOnServer)
301: ds.reset();
302: setStatus(res, DataStoreProxy.REMOTE_STATUS_SQL_ERROR);
303: }
304:
305: }
306:
307: private DataStore getDataStore(HttpSession sess, String id)
308: throws Exception {
309: if (id == null)
310: return null;
311:
312: return (DataStore) sess.getAttribute("$datastore$" + id);
313:
314: }
315:
316: /**
317: * Initializes the servlet
318: */
319: public void init(ServletConfig s) throws ServletException {
320: Properties p = System.getProperties();
321: if (p.getProperty("serveds.root") == null) {
322: String serverRoot = s.getInitParameter("serveds.root");
323: if (serverRoot != null)
324: p.put("serveds.root", serverRoot);
325: }
326: super .init(s);
327: }
328:
329: private DataStoreBuffer newDataStore(HttpServletRequest req,
330: HttpSession sess) throws Exception {
331: String app = URLGenerator.generateServletBaseURL(req);
332: int pos = app.indexOf("/");
333: if (pos > -1)
334: app = app.substring(0, pos);
335:
336: String ds = null;
337:
338: String path = req.getPathInfo();
339:
340: try {
341: StringTokenizer t = new StringTokenizer(path, "/");
342: ds = t.nextToken();
343: } catch (Exception e) {
344: return null;
345: }
346:
347: DataStoreBuffer ret = null;
348: String sesName = null;
349:
350: String dsID = ds + System.currentTimeMillis() + "-"
351: + sess.getId();
352: sesName = "$datastore$" + dsID;
353:
354: try {
355: ret = DataStore.constructDataStore(ds, app);
356: } catch (Exception e) {
357: MessageLog.writeErrorMessage("Exception getting datastore:"
358: + ds, e, this );
359: throw (e);
360: }
361:
362: if (ret != null) {
363: sess.setAttribute(sesName, ret);
364: ret.setRemoteID(dsID);
365: }
366:
367: return ret;
368:
369: }
370:
371: private DataStore removeDataStore(HttpServletRequest req,
372: String idNo) throws Exception {
373: HttpSession sess = req.getSession(false);
374:
375: if (idNo == null)
376: return null;
377:
378: DataStore ret = (DataStore) sess.getAttribute("$datastore$"
379: + idNo);
380: if (ret != null)
381: sess.removeAttribute("$datastore$" + idNo);
382:
383: return ret;
384:
385: }
386:
387: /**
388: * This method handles events from the applet.
389: */
390: public void service(HttpServletRequest req, HttpServletResponse res)
391: throws ServletException, IOException {
392: JspServlet.setUpApplicationContext(getServletContext(), req);
393: OutputStream out = null;
394: ObjectInputStream in = null;
395: boolean keepDataOnServer = (req
396: .getHeader(DataStoreProxy.KEEP_DATA_ON_SERVER) != null);
397:
398: try {
399: boolean useCompression = (req
400: .getHeader(DataStoreProxy.USE_COMPRESSION) != null);
401: in = new ObjectInputStream(req.getInputStream());
402: if (!useCompression)
403: out = res.getOutputStream();
404: else
405: out = new DeflaterOutputStream(res.getOutputStream());
406:
407: String operation = (String) in.readObject();
408: String idNo = (String) in.readObject();
409: String criteria = (String) in.readObject();
410: String userID = (String) in.readObject();
411: String pw = (String) in.readObject();
412:
413: if (operation == null) {
414: setStatus(res, DataStoreProxy.REMOTE_STATUS_BAD_REQUEST);
415: operation = "Create";
416: in.close();
417: out.close();
418: return;
419: }
420:
421: MessageLog.writeInfoMessage("Operation:" + operation
422: + " ID:" + idNo, this );
423:
424: //System.erds.println("Cookies***********************");
425: //Cookie c[] = req.getCookies();
426: //for (int i = 0; i < c.length; i++) {
427: // System.erds.println(c[i].getName() + " = " + c[i].getValue());
428: //}
429: //System.erds.println("********************************");
430:
431: boolean sessValid = true;
432: HttpSession sess = req.getSession(false);
433: if (sess == null) {
434: sess = req.getSession(true);
435: sessValid = false;
436: }
437: //System.erds.println("Session Valid=" + sessValid);
438:
439: if (operation.equals(DataStoreProxy.OPERATION_CREATE)) {
440: DataStoreBuffer ds = newDataStore(req, sess);
441: if (ds == null)
442: setStatus(res,
443: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
444: else if (!checkRequest(ds, operation, req, sessValid,
445: userID, pw, criteria))
446: setStatus(res,
447: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
448: else {
449: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
450: Properties p = ds.getProperties();
451: ByteArrayOutputStream bout = new ByteArrayOutputStream();
452: p.store(bout, "");
453: bout.close();
454: ObjectOutputStream o = new ObjectOutputStream(out);
455: o.writeObject(bout.toByteArray());
456: for (int i = 0; i < ds.getColumnCount(); i++) {
457: ValidationRule r[] = ds
458: .getValidationRulesForColumn(i);
459: if (r != null) {
460: for (int j = 0; j < r.length; j++) {
461: if (r[j].isExecuteOnServer())
462: r[j] = new ValidationRule();
463: }
464: o.writeObject(new Integer(i));
465: o.writeObject(r);
466: }
467: }
468: o.writeObject(new Integer(-1));
469: o.close();
470: }
471: } else if (operation
472: .equals(DataStoreProxy.OPERATION_RETRIEVE)) {
473: DataStore ds = getDataStore(sess, idNo);
474: if (ds == null)
475: setStatus(res,
476: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
477: else if (!checkRequest(ds, operation, req, sessValid,
478: userID, pw, criteria))
479: setStatus(res,
480: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
481: else {
482: boolean enableThreads = ds.getEnableThreads();
483: ds.setEnableThreads(true);
484:
485: if (criteria != null && !criteria.equals(""))
486: ds.retrieve(criteria);
487: else
488: ds.retrieve();
489: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
490: ObjectOutputStream o = new ObjectOutputStream(out);
491: if (ds.gotoFirst()) {
492: do {
493: for (int i = 0; i < ds.getColumnCount(); i++) {
494: o.writeObject(ds.getAny(i));
495: }
496: } while (ds.gotoNext());
497: }
498: ds.setEnableThreads(enableThreads);
499: MessageLog.writeInfoMessage("Operation:"
500: + operation + " ID:" + idNo
501: + " complete. Sent " + ds.getRowCount()
502: + " rows to client.", this );
503: o.close();
504: if (!keepDataOnServer)
505: ds.reset();
506: }
507: } else if (operation
508: .equals(DataStoreProxy.OPERATION_VALIDATE)) {
509: DataStore ds = getDataStore(sess, idNo);
510: if (ds == null)
511: setStatus(res,
512: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
513: else if (!checkRequest(ds, operation, req, sessValid,
514: userID, pw, criteria))
515: setStatus(res,
516: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
517: else {
518: ds.reset();
519: int colNo = ((Integer) in.readObject()).intValue();
520: int rowNo = ((Integer) in.readObject()).intValue();
521: ds.insertRow();
522: for (int i = 0; i < ds.getColumnCount(); i++) {
523: DataStoreRow r = ds.getDataStoreRow(0,
524: DataStoreBuffer.BUFFER_STANDARD);
525: r.setData(i, in.readObject());
526: r.getDSDataRow().setColumnStatus(i,
527: DataStoreBuffer.STATUS_NOT_MODIFIED);
528: }
529: ds.resetStatus();
530: DBConnection conn = null;
531: ObjectOutputStream o = new ObjectOutputStream(out);
532: try {
533: conn = DBConnection.getConnection(ds
534: .getAppName(), ds.getDbProfile());
535: DataStoreException[] ex = ds.validateColumn(0,
536: colNo, conn);
537: for (int i = 0; i < ex.length; i++) {
538: ex[i].setRowNo(rowNo);
539: o.writeObject(ex[i]);
540: }
541: for (int i = 0; i < ds.getColumnCount(); i++) {
542: if (ds.isColumnModified(0, i)) {
543: o.writeObject(new Integer(i));
544: o.writeObject(ds.getAny(0, i));
545: }
546: }
547: } catch (Exception ex) {
548: MessageLog.writeErrorMessage("doGet", ex, this );
549: } finally {
550: if (conn != null)
551: conn.freeConnection();
552: if (!keepDataOnServer)
553: ds.reset();
554: }
555: o.writeObject(new Character('X'));
556: o.close();
557: }
558: } else if (operation.equals(DataStoreProxy.OPERATION_COUNT)) {
559: DataStore ds = getDataStore(sess, idNo);
560: if (ds == null)
561: setStatus(res,
562: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
563: else if (!checkRequest(ds, operation, req, sessValid,
564: userID, pw, criteria))
565: setStatus(res,
566: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
567: else {
568: int rows = 0;
569: if (criteria != null && !criteria.equals(""))
570: rows = ds.estimateRowsRetrieved(criteria);
571: else
572: rows = ds.estimateRowsRetrieved();
573: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
574: ObjectOutputStream o = new ObjectOutputStream(out);
575: o.writeObject(new Integer(rows));
576: o.close();
577: }
578: } else if (operation
579: .equals(DataStoreProxy.OPERATION_GET_TABLE_COLUMNS)) {
580: DataStore ds = getDataStore(sess, idNo);
581: if (ds == null)
582: setStatus(res,
583: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
584: else if (!checkRequest(ds, operation, req, sessValid,
585: userID, pw, criteria))
586: setStatus(res,
587: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
588: else {
589: ColumnDefinition def[] = ds
590: .getColumnsForTable(criteria);
591: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
592: ObjectOutputStream o = new ObjectOutputStream(out);
593: o.writeObject(def);
594: o.close();
595: }
596: } else if (operation
597: .equals(DataStoreProxy.OPERATION_CANCEL)) {
598: DataStore ds = getDataStore(sess, idNo);
599: if (ds == null)
600: setStatus(res,
601: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
602: else if (!checkRequest(ds, operation, req, sessValid,
603: userID, pw, criteria))
604: setStatus(res,
605: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
606: else {
607: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
608: ds.cancelRetrieve();
609: }
610: } else if (operation.equals(DataStoreProxy.OPERATION_PING)) {
611: DataStore ds = getDataStore(sess, idNo);
612: if (ds == null)
613: setStatus(res,
614: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
615: else if (!checkRequest(ds, operation, req, sessValid,
616: userID, pw, criteria))
617: setStatus(res,
618: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
619: else
620: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
621: } else if (operation
622: .equals(DataStoreProxy.OPERATION_DESTROY)) {
623: DataStore ds = removeDataStore(req, idNo);
624: if (ds == null)
625: setStatus(res,
626: DataStoreProxy.REMOTE_STATUS_NOT_FOUND);
627: else if (!checkRequest(ds, operation, req, sessValid,
628: userID, pw, criteria))
629: setStatus(res,
630: DataStoreProxy.REMOTE_STATUS_ACCESS_DENIED);
631: else
632: setStatus(res, DataStoreProxy.REMOTE_STATUS_OK);
633: } else if (operation
634: .equals(DataStoreProxy.OPERATION_UPDATE)) {
635: ObjectOutputStream o = new ObjectOutputStream(out);
636: doUpdate(req, res, sessValid, userID, pw, criteria,
637: sess, in, o, keepDataOnServer);
638: out.close();
639: } else {
640: setStatus(res, DataStoreProxy.REMOTE_STATUS_BAD_REQUEST);
641: }
642:
643: in.close();
644: } catch (DataStoreException e) {
645: setStatus(res, DataStoreProxy.REMOTE_STATUS_BAD_REQUEST);
646: ObjectOutputStream o = new ObjectOutputStream(out);
647: o.writeObject(e);
648: MessageLog.writeErrorMessage("doGet", e, this );
649: out.close();
650: } catch (java.sql.SQLException e) {
651: setStatus(res, DataStoreProxy.REMOTE_STATUS_SQL_ERROR);
652: ObjectOutputStream o = new ObjectOutputStream(out);
653: o.writeObject(e);
654: MessageLog.writeErrorMessage("doGet", e, this );
655: out.close();
656: } catch (Exception e) {
657: MessageLog.writeErrorMessage("doGet", e, this );
658: setStatus(res, DataStoreProxy.REMOTE_STATUS_BAD_REQUEST);
659: }
660:
661: }
662:
663: /**
664: * This method was created in VisualAge.
665: * @param res javax.servlet.http.HttpServletResponse
666: */
667: private void setStatus(HttpServletResponse res, int stat) {
668: res.setIntHeader("DataServerResponse", stat);
669: }
670:
671: private void updateConnections(Hashtable connections, int op) {
672: Enumeration e = connections.elements();
673: while (e.hasMoreElements()) {
674: DBConnection conn = (DBConnection) e.nextElement();
675: if (op == OP_COMMIT)
676: conn.commit();
677: else if (op == OP_ROLLBACK)
678: conn.rollback();
679: else if (op == OP_FREE)
680: conn.freeConnection();
681: }
682: }
683:
684: }
|