001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.ws.rm.persistence.jdbc;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.File;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.math.BigDecimal;
025: import java.math.BigInteger;
026: import java.sql.Blob;
027: import java.sql.Connection;
028: import java.sql.DriverManager;
029: import java.sql.PreparedStatement;
030: import java.sql.ResultSet;
031: import java.sql.SQLException;
032: import java.sql.Statement;
033: import java.text.MessageFormat;
034: import java.util.ArrayList;
035: import java.util.Collection;
036: import java.util.Date;
037: import java.util.concurrent.locks.Lock;
038: import java.util.concurrent.locks.ReentrantLock;
039: import java.util.logging.Level;
040: import java.util.logging.Logger;
041:
042: import javax.annotation.PostConstruct;
043:
044: import org.apache.cxf.common.i18n.Message;
045: import org.apache.cxf.common.logging.LogUtils;
046: import org.apache.cxf.ws.addressing.v200408.EndpointReferenceType;
047: import org.apache.cxf.ws.rm.DestinationSequence;
048: import org.apache.cxf.ws.rm.Identifier;
049: import org.apache.cxf.ws.rm.RMUtils;
050: import org.apache.cxf.ws.rm.SequenceAcknowledgement;
051: import org.apache.cxf.ws.rm.SourceSequence;
052: import org.apache.cxf.ws.rm.persistence.PersistenceUtils;
053: import org.apache.cxf.ws.rm.persistence.RMMessage;
054: import org.apache.cxf.ws.rm.persistence.RMStore;
055: import org.apache.cxf.ws.rm.persistence.RMStoreException;
056:
057: public class RMTxStore implements RMStore {
058:
059: public static final String DEFAULT_DATABASE_NAME = "rmdb";
060:
061: private static final String CREATE_DEST_SEQUENCES_TABLE_STMT = "CREATE TABLE CXF_RM_DEST_SEQUENCES "
062: + "(SEQ_ID VARCHAR(256) NOT NULL, "
063: + "ACKS_TO VARCHAR(1024) NOT NULL, "
064: + "LAST_MSG_NO DECIMAL(31, 0), "
065: + "ENDPOINT_ID VARCHAR(1024), "
066: + "ACKNOWLEDGED BLOB, "
067: + "PRIMARY KEY (SEQ_ID))";
068: private static final String CREATE_SRC_SEQUENCES_TABLE_STMT = "CREATE TABLE CXF_RM_SRC_SEQUENCES "
069: + "(SEQ_ID VARCHAR(256) NOT NULL, "
070: + "CUR_MSG_NO DECIMAL(31, 0) NOT NULL DEFAULT 1, "
071: + "LAST_MSG CHAR(1), "
072: + "EXPIRY BIGINT, "
073: + "OFFERING_SEQ_ID VARCHAR(256), "
074: + "ENDPOINT_ID VARCHAR(1024), " + "PRIMARY KEY (SEQ_ID))";
075: private static final String CREATE_MESSAGES_TABLE_STMT = "CREATE TABLE {0} "
076: + "(SEQ_ID VARCHAR(256) NOT NULL, "
077: + "MSG_NO DECIMAL(31, 0) NOT NULL, "
078: + "SEND_TO VARCHAR(256), "
079: + "CONTENT BLOB, "
080: + "PRIMARY KEY (SEQ_ID, MSG_NO))";
081: private static final String INBOUND_MSGS_TABLE_NAME = "CXF_RM_INBOUND_MESSAGES";
082: private static final String OUTBOUND_MSGS_TABLE_NAME = "CXF_RM_OUTBOUND_MESSAGES";
083:
084: private static final String CREATE_DEST_SEQUENCE_STMT_STR = "INSERT INTO CXF_RM_DEST_SEQUENCES (SEQ_ID, ACKS_TO, ENDPOINT_ID) VALUES(?, ?, ?)";
085: private static final String CREATE_SRC_SEQUENCE_STMT_STR = "INSERT INTO CXF_RM_SRC_SEQUENCES VALUES(?, 1, '0', ?, ?, ?)";
086: private static final String DELETE_DEST_SEQUENCE_STMT_STR = "DELETE FROM CXF_RM_DEST_SEQUENCES WHERE SEQ_ID = ?";
087: private static final String DELETE_SRC_SEQUENCE_STMT_STR = "DELETE FROM CXF_RM_SRC_SEQUENCES WHERE SEQ_ID = ?";
088: private static final String UPDATE_DEST_SEQUENCE_STMT_STR = "UPDATE CXF_RM_DEST_SEQUENCES SET LAST_MSG_NO = ?, ACKNOWLEDGED = ? WHERE SEQ_ID = ?";
089: private static final String UPDATE_SRC_SEQUENCE_STMT_STR = "UPDATE CXF_RM_SRC_SEQUENCES SET CUR_MSG_NO = ?, LAST_MSG = ? WHERE SEQ_ID = ?";
090: private static final String CREATE_MESSAGE_STMT_STR = "INSERT INTO {0} VALUES(?, ?, ?, ?)";
091: private static final String DELETE_MESSAGE_STMT_STR = "DELETE FROM {0} WHERE SEQ_ID = ? AND MSG_NO = ?";
092: private static final String SELECT_DEST_SEQUENCES_STMT_STR = "SELECT SEQ_ID, ACKS_TO, LAST_MSG_NO, ACKNOWLEDGED FROM CXF_RM_DEST_SEQUENCES "
093: + "WHERE ENDPOINT_ID = ?";
094: private static final String SELECT_SRC_SEQUENCES_STMT_STR = "SELECT SEQ_ID, CUR_MSG_NO, LAST_MSG, EXPIRY, OFFERING_SEQ_ID FROM CXF_RM_SRC_SEQUENCES "
095: + "WHERE ENDPOINT_ID = ?";
096: private static final String SELECT_MESSAGES_STMT_STR = "SELECT MSG_NO, SEND_TO, CONTENT FROM {0} WHERE SEQ_ID = ?";
097:
098: private static final Logger LOG = LogUtils
099: .getL7dLogger(RMTxStore.class);
100:
101: private Connection connection;
102: private Lock writeLock = new ReentrantLock();
103:
104: private PreparedStatement createDestSequenceStmt;
105: private PreparedStatement createSrcSequenceStmt;
106: private PreparedStatement deleteDestSequenceStmt;
107: private PreparedStatement deleteSrcSequenceStmt;
108: private PreparedStatement updateDestSequenceStmt;
109: private PreparedStatement updateSrcSequenceStmt;
110: private PreparedStatement selectDestSequencesStmt;
111: private PreparedStatement selectSrcSequencesStmt;
112: private PreparedStatement createInboundMessageStmt;
113: private PreparedStatement createOutboundMessageStmt;
114: private PreparedStatement deleteInboundMessageStmt;
115: private PreparedStatement deleteOutboundMessageStmt;
116: private PreparedStatement selectInboundMessagesStmt;
117: private PreparedStatement selectOutboundMessagesStmt;
118:
119: private String driverClassName = "org.apache.derby.jdbc.EmbeddedDriver";
120: private String url = MessageFormat.format(
121: "jdbc:derby:{0};create=true", DEFAULT_DATABASE_NAME);
122: private String userName;
123: private String password;
124:
125: // configuration
126:
127: public void setDriverClassName(String dcn) {
128: driverClassName = dcn;
129: }
130:
131: public void setPassword(String p) {
132: password = p;
133: }
134:
135: public void setUrl(String u) {
136: url = u;
137: }
138:
139: public void setUserName(String un) {
140: userName = un;
141: }
142:
143: public void setConnection(Connection c) {
144: connection = c;
145: }
146:
147: // RMStore interface
148:
149: public void createDestinationSequence(DestinationSequence seq) {
150: String sequenceIdentifier = seq.getIdentifier().getValue();
151: String endpointIdentifier = seq.getEndpointIdentifier();
152: if (LOG.isLoggable(Level.FINE)) {
153: LOG.info("Creating destination sequence: "
154: + sequenceIdentifier + ", (endpoint: "
155: + endpointIdentifier + ")");
156: }
157: try {
158: beginTransaction();
159:
160: if (null == createDestSequenceStmt) {
161: createDestSequenceStmt = connection
162: .prepareStatement(CREATE_DEST_SEQUENCE_STMT_STR);
163: }
164: createDestSequenceStmt.setString(1, sequenceIdentifier);
165: String addr = seq.getAcksTo().getAddress().getValue();
166: createDestSequenceStmt.setString(2, addr);
167: createDestSequenceStmt.setString(3, endpointIdentifier);
168:
169: createDestSequenceStmt.execute();
170:
171: commit();
172:
173: } catch (SQLException ex) {
174: abort();
175: throw new RMStoreException(ex);
176: }
177: }
178:
179: public void createSourceSequence(SourceSequence seq) {
180: String sequenceIdentifier = seq.getIdentifier().getValue();
181: String endpointIdentifier = seq.getEndpointIdentifier();
182: if (LOG.isLoggable(Level.FINE)) {
183: LOG.fine("Creating source sequence: " + sequenceIdentifier
184: + ", (endpoint: " + endpointIdentifier + ")");
185: }
186:
187: try {
188: beginTransaction();
189:
190: if (null == createSrcSequenceStmt) {
191: createSrcSequenceStmt = connection
192: .prepareStatement(CREATE_SRC_SEQUENCE_STMT_STR);
193: }
194: assert null != createSrcSequenceStmt;
195: createSrcSequenceStmt.setString(1, sequenceIdentifier);
196: Date expiry = seq.getExpires();
197: createSrcSequenceStmt.setLong(2, expiry == null ? 0
198: : expiry.getTime());
199: Identifier osid = seq.getOfferingSequenceIdentifier();
200: createSrcSequenceStmt.setString(3, osid == null ? null
201: : osid.getValue());
202: createSrcSequenceStmt.setString(4, endpointIdentifier);
203: createSrcSequenceStmt.execute();
204:
205: commit();
206:
207: } catch (SQLException ex) {
208: abort();
209: throw new RMStoreException(ex);
210: }
211: }
212:
213: public void removeDestinationSequence(Identifier sid) {
214: try {
215: beginTransaction();
216:
217: if (null == deleteDestSequenceStmt) {
218: deleteDestSequenceStmt = connection
219: .prepareStatement(DELETE_DEST_SEQUENCE_STMT_STR);
220: }
221: deleteDestSequenceStmt.setString(1, sid.getValue());
222: deleteDestSequenceStmt.execute();
223:
224: commit();
225:
226: } catch (SQLException ex) {
227: abort();
228: throw new RMStoreException(ex);
229: }
230: }
231:
232: public void removeSourceSequence(Identifier sid) {
233: try {
234: beginTransaction();
235:
236: if (null == deleteSrcSequenceStmt) {
237: deleteSrcSequenceStmt = connection
238: .prepareStatement(DELETE_SRC_SEQUENCE_STMT_STR);
239: }
240: deleteSrcSequenceStmt.setString(1, sid.getValue());
241: deleteSrcSequenceStmt.execute();
242:
243: commit();
244:
245: } catch (SQLException ex) {
246: abort();
247: throw new RMStoreException(ex);
248: }
249: }
250:
251: public Collection<DestinationSequence> getDestinationSequences(
252: String endpointIdentifier) {
253: if (LOG.isLoggable(Level.FINE)) {
254: LOG.info("Getting destination sequences for endpoint: "
255: + endpointIdentifier);
256: }
257: Collection<DestinationSequence> seqs = new ArrayList<DestinationSequence>();
258: try {
259: if (null == selectDestSequencesStmt) {
260: selectDestSequencesStmt = connection
261: .prepareStatement(SELECT_DEST_SEQUENCES_STMT_STR);
262: }
263: selectDestSequencesStmt.setString(1, endpointIdentifier);
264:
265: ResultSet res = selectDestSequencesStmt.executeQuery();
266: while (res.next()) {
267: Identifier sid = RMUtils.getWSRMFactory()
268: .createIdentifier();
269: sid.setValue(res.getString(1));
270: EndpointReferenceType acksTo = RMUtils
271: .createReference2004(res.getString(2));
272: BigDecimal lm = res.getBigDecimal(3);
273: InputStream is = res.getBinaryStream(4);
274: SequenceAcknowledgement ack = null;
275: if (null != is) {
276: ack = PersistenceUtils.getInstance()
277: .deserialiseAcknowledgment(is);
278: }
279: DestinationSequence seq = new DestinationSequence(sid,
280: acksTo, lm == null ? null : lm.toBigInteger(),
281: ack);
282: seqs.add(seq);
283: }
284: } catch (SQLException ex) {
285: LOG.log(Level.WARNING, new Message(
286: "SELECT_DEST_SEQ_FAILED_MSG", LOG).toString(), ex);
287: }
288: return seqs;
289: }
290:
291: public Collection<SourceSequence> getSourceSequences(
292: String endpointIdentifier) {
293: if (LOG.isLoggable(Level.FINE)) {
294: LOG.info("Getting source sequences for endpoint: "
295: + endpointIdentifier);
296: }
297: Collection<SourceSequence> seqs = new ArrayList<SourceSequence>();
298: try {
299: if (null == selectSrcSequencesStmt) {
300: selectSrcSequencesStmt = connection
301: .prepareStatement(SELECT_SRC_SEQUENCES_STMT_STR);
302: }
303: selectSrcSequencesStmt.setString(1, endpointIdentifier);
304: ResultSet res = selectSrcSequencesStmt.executeQuery();
305:
306: while (res.next()) {
307: Identifier sid = RMUtils.getWSRMFactory()
308: .createIdentifier();
309: sid.setValue(res.getString(1));
310: BigInteger cmn = res.getBigDecimal(2).toBigInteger();
311: boolean lm = res.getBoolean(3);
312: long lval = res.getLong(4);
313: Date expiry = 0 == lval ? null : new Date(lval);
314: String oidValue = res.getString(5);
315: Identifier oi = null;
316: if (null != oidValue) {
317: oi = RMUtils.getWSRMFactory().createIdentifier();
318: oi.setValue(oidValue);
319: }
320: SourceSequence seq = new SourceSequence(sid, expiry,
321: oi, cmn, lm);
322: seqs.add(seq);
323: }
324: } catch (SQLException ex) {
325: // ignore
326: LOG.log(Level.WARNING, new Message(
327: "SELECT_SRC_SEQ_FAILED_MSG", LOG).toString(), ex);
328: }
329: return seqs;
330: }
331:
332: public Collection<RMMessage> getMessages(Identifier sid,
333: boolean outbound) {
334: Collection<RMMessage> msgs = new ArrayList<RMMessage>();
335: try {
336: PreparedStatement stmt = outbound ? selectOutboundMessagesStmt
337: : selectInboundMessagesStmt;
338: if (null == stmt) {
339: stmt = connection.prepareStatement(MessageFormat
340: .format(SELECT_MESSAGES_STMT_STR,
341: outbound ? OUTBOUND_MSGS_TABLE_NAME
342: : INBOUND_MSGS_TABLE_NAME));
343: if (outbound) {
344: selectOutboundMessagesStmt = stmt;
345: } else {
346: selectInboundMessagesStmt = stmt;
347: }
348: }
349: stmt.setString(1, sid.getValue());
350: ResultSet res = stmt.executeQuery();
351: while (res.next()) {
352: BigInteger mn = res.getBigDecimal(1).toBigInteger();
353: String to = res.getString(2);
354: Blob blob = res.getBlob(3);
355: byte[] bytes = blob.getBytes(1, (int) blob.length());
356: RMMessage msg = new RMMessage();
357: msg.setMessageNumber(mn);
358: msg.setTo(to);
359: msg.setContent(bytes);
360: msgs.add(msg);
361: }
362: } catch (SQLException ex) {
363: LOG.log(Level.WARNING, new Message(
364: outbound ? "SELECT_OUTBOUND_MSGS_FAILED_MSG"
365: : "SELECT_INBOUND_MSGS_FAILED_MSG", LOG)
366: .toString(), ex);
367: }
368: return msgs;
369: }
370:
371: public void persistIncoming(DestinationSequence seq, RMMessage msg) {
372: try {
373: beginTransaction();
374:
375: updateDestinationSequence(seq);
376:
377: storeMessage(seq.getIdentifier(), msg, false);
378:
379: commit();
380:
381: } catch (SQLException ex) {
382: abort();
383: throw new RMStoreException(ex);
384: } catch (IOException ex) {
385: abort();
386: throw new RMStoreException(ex);
387: }
388: }
389:
390: public void persistOutgoing(SourceSequence seq, RMMessage msg) {
391: try {
392: beginTransaction();
393:
394: updateSourceSequence(seq);
395:
396: storeMessage(seq.getIdentifier(), msg, true);
397:
398: commit();
399:
400: } catch (SQLException ex) {
401: abort();
402: throw new RMStoreException(ex);
403: } catch (IOException ex) {
404: abort();
405: throw new RMStoreException(ex);
406: }
407: }
408:
409: public void removeMessages(Identifier sid,
410: Collection<BigInteger> messageNrs, boolean outbound) {
411: try {
412: beginTransaction();
413: PreparedStatement stmt = outbound ? deleteOutboundMessageStmt
414: : deleteInboundMessageStmt;
415: if (null == stmt) {
416: stmt = connection.prepareStatement(MessageFormat
417: .format(DELETE_MESSAGE_STMT_STR,
418: outbound ? OUTBOUND_MSGS_TABLE_NAME
419: : INBOUND_MSGS_TABLE_NAME));
420: if (outbound) {
421: deleteOutboundMessageStmt = stmt;
422: } else {
423: deleteInboundMessageStmt = stmt;
424: }
425: }
426:
427: stmt.setString(1, sid.getValue());
428:
429: for (BigInteger messageNr : messageNrs) {
430: stmt.setBigDecimal(2, new BigDecimal(messageNr));
431: stmt.execute();
432: }
433:
434: commit();
435:
436: } catch (SQLException ex) {
437: abort();
438: throw new RMStoreException(ex);
439: }
440: }
441:
442: // transaction demarcation
443: //
444:
445: protected void beginTransaction() {
446: // avoid sharing of statements and result sets
447: writeLock.lock();
448: }
449:
450: protected void commit() throws SQLException {
451: try {
452: connection.commit();
453: } finally {
454: writeLock.unlock();
455: }
456: }
457:
458: protected void abort() {
459: try {
460: connection.rollback();
461: } catch (SQLException ex) {
462: LogUtils.log(LOG, Level.SEVERE, "ABORT_FAILED_MSG", ex);
463: } finally {
464: writeLock.unlock();
465: }
466: }
467:
468: // helpers
469:
470: protected void storeMessage(Identifier sid, RMMessage msg,
471: boolean outbound) throws IOException, SQLException {
472: String id = sid.getValue();
473: BigInteger nr = msg.getMessageNumber();
474: String to = msg.getTo();
475: LOG
476: .log(
477: Level.FINE,
478: "Storing {0} message number {1} for sequence {2}, to = {3}",
479: new Object[] {
480: outbound ? "outbound" : "inbound", nr,
481: id, to });
482: PreparedStatement stmt = outbound ? createOutboundMessageStmt
483: : createInboundMessageStmt;
484: if (null == stmt) {
485: stmt = connection.prepareStatement(MessageFormat.format(
486: CREATE_MESSAGE_STMT_STR,
487: outbound ? OUTBOUND_MSGS_TABLE_NAME
488: : INBOUND_MSGS_TABLE_NAME));
489: if (outbound) {
490: createOutboundMessageStmt = stmt;
491: } else {
492: createInboundMessageStmt = stmt;
493: }
494: }
495: int i = 1;
496: stmt.setString(i++, id);
497: stmt.setBigDecimal(i++, new BigDecimal(nr));
498: stmt.setString(i++, to);
499: byte[] bytes = msg.getContent();
500: stmt.setBinaryStream(i++, new ByteArrayInputStream(bytes),
501: bytes.length);
502: stmt.execute();
503: LOG
504: .log(
505: Level.FINE,
506: "Successfully stored {0} message number {1} for sequence {2}",
507: new Object[] {
508: outbound ? "outbound" : "inbound", nr,
509: id });
510:
511: }
512:
513: protected void updateSourceSequence(SourceSequence seq)
514: throws SQLException {
515: if (null == updateSrcSequenceStmt) {
516: updateSrcSequenceStmt = connection
517: .prepareStatement(UPDATE_SRC_SEQUENCE_STMT_STR);
518: }
519: updateSrcSequenceStmt.setBigDecimal(1, new BigDecimal(seq
520: .getCurrentMessageNr()));
521: updateSrcSequenceStmt.setBoolean(2, seq.isLastMessage());
522: updateSrcSequenceStmt.setString(3, seq.getIdentifier()
523: .getValue());
524: updateSrcSequenceStmt.execute();
525: }
526:
527: protected void updateDestinationSequence(DestinationSequence seq)
528: throws SQLException, IOException {
529: if (null == updateDestSequenceStmt) {
530: updateDestSequenceStmt = connection
531: .prepareStatement(UPDATE_DEST_SEQUENCE_STMT_STR);
532: }
533: BigInteger lastMessageNr = seq.getLastMessageNumber();
534: updateDestSequenceStmt.setBigDecimal(1,
535: lastMessageNr == null ? null : new BigDecimal(
536: lastMessageNr));
537: InputStream is = PersistenceUtils.getInstance()
538: .serialiseAcknowledgment(seq.getAcknowledgment());
539: updateDestSequenceStmt.setBinaryStream(2, is, is.available());
540: updateDestSequenceStmt.setString(3, seq.getIdentifier()
541: .getValue());
542: updateDestSequenceStmt.execute();
543: }
544:
545: protected void createTables() throws SQLException {
546:
547: Statement stmt = null;
548: stmt = connection.createStatement();
549: try {
550: stmt.executeUpdate(CREATE_SRC_SEQUENCES_TABLE_STMT);
551: } catch (SQLException ex) {
552: if (!"X0Y32".equals(ex.getSQLState())) {
553: throw ex;
554: } else {
555: LOG.fine("Table CXF_RM_SRC_SEQUENCES already exists.");
556: }
557: }
558: stmt.close();
559:
560: stmt = connection.createStatement();
561: try {
562: stmt.executeUpdate(CREATE_DEST_SEQUENCES_TABLE_STMT);
563: } catch (SQLException ex) {
564: if (!"X0Y32".equals(ex.getSQLState())) {
565: throw ex;
566: } else {
567: LOG.fine("Table CXF_RM_DEST_SEQUENCES already exists.");
568: }
569: }
570: stmt.close();
571:
572: for (String tableName : new String[] {
573: OUTBOUND_MSGS_TABLE_NAME, INBOUND_MSGS_TABLE_NAME }) {
574: stmt = connection.createStatement();
575: try {
576: stmt.executeUpdate(MessageFormat.format(
577: CREATE_MESSAGES_TABLE_STMT, tableName));
578: } catch (SQLException ex) {
579: if (!"X0Y32".equals(ex.getSQLState())) {
580: throw ex;
581: } else {
582: if (LOG.isLoggable(Level.FINE)) {
583: LOG.fine("Table " + tableName
584: + " already exists.");
585: }
586: }
587: }
588: stmt.close();
589: }
590: }
591:
592: @PostConstruct
593: synchronized void init() {
594:
595: if (null == connection) {
596: LOG.log(Level.FINE, "Using derby.system.home: {0}", System
597: .getProperty("derby.system.home"));
598: assert null != url;
599: assert null != driverClassName;
600: try {
601: Class.forName(driverClassName);
602: } catch (ClassNotFoundException ex) {
603: LogUtils.log(LOG, Level.SEVERE, "CONNECT_EXC", ex);
604: }
605:
606: try {
607: connection = DriverManager.getConnection(url, userName,
608: password);
609:
610: } catch (SQLException ex) {
611: LogUtils.log(LOG, Level.SEVERE, "CONNECT_EXC", ex);
612: return;
613: }
614: }
615:
616: try {
617: connection.setAutoCommit(false);
618: createTables();
619: } catch (SQLException ex) {
620: LogUtils.log(LOG, Level.SEVERE, "CONNECT_EXC", ex);
621: SQLException se = ex;
622: while (se.getNextException() != null) {
623: se = se.getNextException();
624: LogUtils.log(LOG, Level.SEVERE, "CONNECT_EXC", se);
625: }
626: throw new RMStoreException(ex);
627: }
628: }
629:
630: Connection getConnection() {
631: return connection;
632: }
633:
634: public static void deleteDatabaseFiles() {
635: deleteDatabaseFiles(DEFAULT_DATABASE_NAME, true);
636: }
637:
638: public static void deleteDatabaseFiles(String dbName, boolean now) {
639: String dsh = System.getProperty("derby.system.home");
640:
641: File root = null;
642: File log = null;
643: if (null == dsh) {
644: log = new File("derby.log");
645: root = new File(dbName);
646: } else {
647: log = new File(dsh, "derby.log");
648: root = new File(dsh, dbName);
649: }
650: if (log.exists()) {
651: if (now) {
652: boolean deleted = log.delete();
653: LOG.log(Level.FINE, "Deleted log file {0}: {1}",
654: new Object[] { log, deleted });
655: } else {
656: log.deleteOnExit();
657: }
658: }
659: if (root.exists()) {
660: LOG.log(Level.FINE, "Trying to delete directory {0}", root);
661: recursiveDelete(root, now);
662: }
663:
664: }
665:
666: private static void recursiveDelete(File dir, boolean now) {
667: for (File f : dir.listFiles()) {
668: if (f.isDirectory()) {
669: recursiveDelete(f, now);
670: } else {
671: if (now) {
672: f.delete();
673: } else {
674: f.deleteOnExit();
675: }
676: }
677: }
678: if (now) {
679: dir.delete();
680: } else {
681: dir.deleteOnExit();
682: }
683: }
684:
685: }
|