KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > store > impl > rdbms > AbstractRDBMSStore


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/AbstractRDBMSStore.java,v 1.10.2.3 2004/11/22 16:35:11 ozeigermann Exp $
3  * $Revision: 1.10.2.3 $
4  * $Date: 2004/11/22 16:35:11 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2003 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.store.impl.rdbms;
25
26 import java.lang.reflect.Constructor JavaDoc;
27 import java.sql.Connection JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.Hashtable JavaDoc;
31
32 import javax.transaction.xa.XAException JavaDoc;
33 import javax.transaction.xa.XAResource JavaDoc;
34 import javax.transaction.xa.Xid JavaDoc;
35
36 import org.apache.commons.transaction.util.xa.AbstractTransactionalResource;
37 import org.apache.commons.transaction.util.xa.TransactionalResource;
38 import org.apache.slide.common.AbstractXAServiceBase;
39 import org.apache.slide.common.Service;
40 import org.apache.slide.common.ServiceAccessException;
41 import org.apache.slide.common.ServiceConnectionFailedException;
42 import org.apache.slide.common.ServiceDisconnectionFailedException;
43 import org.apache.slide.common.ServiceInitializationFailedException;
44 import org.apache.slide.common.ServiceParameterErrorException;
45 import org.apache.slide.common.ServiceParameterMissingException;
46 import org.apache.slide.common.ServiceResetFailedException;
47 import org.apache.slide.common.Uri;
48 import org.apache.slide.content.NodeRevisionContent;
49 import org.apache.slide.content.NodeRevisionDescriptor;
50 import org.apache.slide.content.NodeRevisionDescriptors;
51 import org.apache.slide.content.NodeRevisionNumber;
52 import org.apache.slide.content.RevisionAlreadyExistException;
53 import org.apache.slide.content.RevisionDescriptorNotFoundException;
54 import org.apache.slide.content.RevisionNotFoundException;
55 import org.apache.slide.lock.LockTokenNotFoundException;
56 import org.apache.slide.lock.NodeLock;
57 import org.apache.slide.search.basic.BasicExpressionFactory;
58 import org.apache.slide.search.basic.IBasicExpressionFactory;
59 import org.apache.slide.search.basic.IBasicExpressionFactoryProvider;
60 import org.apache.slide.security.NodePermission;
61 import org.apache.slide.store.ContentStore;
62 import org.apache.slide.store.LockStore;
63 import org.apache.slide.store.NodeStore;
64 import org.apache.slide.store.RevisionDescriptorStore;
65 import org.apache.slide.store.RevisionDescriptorsStore;
66 import org.apache.slide.store.SecurityStore;
67 import org.apache.slide.store.SequenceStore;
68 import org.apache.slide.store.impl.rdbms.expression.RDBMSExpressionFactory;
69 import org.apache.slide.structure.ObjectAlreadyExistsException;
70 import org.apache.slide.structure.ObjectNode;
71 import org.apache.slide.structure.ObjectNotFoundException;
72 import org.apache.slide.util.logger.Logger;
73
74 /**
75  * J2EE store implementation - implements the shared parts of
76  * the two (content, descriptors) J2EE stores for the new Indexed DB Schema.
77  *
78  * @version $Revision: 1.10.2.3 $
79  */

80 public abstract class AbstractRDBMSStore
81     extends AbstractXAServiceBase
82     implements
83         LockStore,
84         NodeStore,
85         RevisionDescriptorsStore,
86         RevisionDescriptorStore,
87         SecurityStore,
88         ContentStore,
89         SequenceStore,
90         IBasicExpressionFactoryProvider {
91
92     protected static final String JavaDoc LOG_CHANNEL = AbstractRDBMSStore.class.getName();
93
94     protected RDBMSAdapter adapter;
95
96     protected boolean alreadyInitialized = false;
97     
98     protected int isSequenceSupported = 0;
99     
100     protected boolean useRdbmsExpressionFactory;
101
102     /**
103      * Indicates whether the transaction manager will commit / rollback
104      * the transaction or the store is in charge of it. Slide's internal
105      * TM does not commit / rollback, but TMs more aligned to the spec (e.g. JBoss' TM) do.
106      */

107     protected boolean tmCommits = false;
108
109     /**
110      * Initializes the data source with a set of parameters.
111      *
112      * @param parameters Hashtable containing the parameters' name
113      * and associated value
114      * @exception ServiceParameterErrorException Incorrect service parameter
115      * @exception ServiceParameterMissingException Service parameter missing
116      */

117     public void setParameters(Hashtable JavaDoc parameters)
118         throws ServiceParameterErrorException, ServiceParameterMissingException {
119
120         // Adapter class
121
String JavaDoc value = (String JavaDoc) parameters.get("adapter");
122         if (value == null) {
123             adapter = new StandardRDBMSAdapter(this, getLogger());
124         } else {
125             try {
126                 Class JavaDoc adapterClass = Class.forName(value);
127                 Constructor JavaDoc ctor = adapterClass.getConstructor(new Class JavaDoc[] { Service.class, Logger.class });
128                 adapter = (RDBMSAdapter) ctor.newInstance(new Object JavaDoc[] { this, getLogger()});
129             } catch (Exception JavaDoc e) {
130                 // reflection exception
131
getLogger().log(
132                     "Error instantiating Adapter '" + value + "' (" + e.getMessage() + ")",
133                     LOG_CHANNEL,
134                     Logger.ERROR);
135             }
136         }
137
138         if (adapter != null) {
139             adapter.setParameters(parameters);
140         }
141
142         // Use RDBMSExpressionFactory?
143
value = (String JavaDoc) parameters.get("use-rdbms-expression-factory");
144         this.useRdbmsExpressionFactory = Boolean.valueOf(value).booleanValue();
145         
146         // XXX need to initialize it here, as some security requests access the store before initialization
147
try {
148             initialize(null);
149         } catch (ServiceInitializationFailedException e) {
150             // XXX this is not very satisfactory...
151
throw new ServiceParameterErrorException(this, e.getMessage());
152         }
153     }
154
155     /**
156      * Establishes the global connection to the data source.
157      *
158      * @exception ServiceConnectionFailedException if the connection failed
159      */

160     public void connect() throws ServiceConnectionFailedException {
161     }
162
163     /**
164      * Returns connection status.
165      */

166     public boolean isConnected() {
167         return true;
168     }
169
170     /**
171      * Closes the global connection to the data source.
172      *
173      * @exception ServiceDisconnectionFailedException if closing the connection
174      * failed
175      */

176     public void disconnect() throws ServiceDisconnectionFailedException {
177     }
178
179     /**
180      * Does nothing.
181      *
182      * @exception ServiceResetFailedException Reset failed
183      */

184     public void reset() throws ServiceResetFailedException {
185
186     }
187
188     
189     // ----------------------------------------------------- XAResource Methods
190

191     /**
192      * Get the transaction timeout value for this XAResource.
193      * Just returns 0, we don't have a way of doing transaction timeouts
194      * with the connection.
195      */

196     public int getTransactionTimeout() throws XAException JavaDoc {
197         return 0;
198     }
199
200     /**
201      * Set transaction timeout, not implemented (returns false).
202      */

203     public boolean setTransactionTimeout(int timeout) throws XAException JavaDoc {
204         return false;
205     }
206
207     public Xid JavaDoc[] recover(int flag) throws XAException JavaDoc {
208
209         getLogger().log("recover() for thread: " + Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
210         TransactionalResource id = getCurrentlyActiveTransactionalResource();
211
212         if (id != null && id.getStatus() == STATUS_PREPARED) {
213             Xid JavaDoc[] xids = new Xid JavaDoc[1];
214             xids[0] = id.getXid();
215             return xids;
216         } else
217             return new Xid JavaDoc[0];
218     }
219
220     public boolean isSameRM(XAResource JavaDoc xares) throws XAException JavaDoc {
221         return (xares == this);
222     }
223     
224     // ----------------------------------------------- IBasicExpressionFactoryProvider Implementation
225

226     public IBasicExpressionFactory getBasicExpressionFactory() {
227         if (this.useRdbmsExpressionFactory) {
228             return new RDBMSExpressionFactory(this);
229         }
230         else {
231             return new BasicExpressionFactory();
232         }
233     }
234
235     // ----------------------------------------------- SequenceStore Implementation
236

237     /**
238      * @see org.apache.slide.store.SequenceStore#createSequence(java.lang.String)
239      */

240     public boolean createSequence(String JavaDoc sequenceName) throws ServiceAccessException {
241         if (!isSequenceSupported()) {
242             throw new ServiceAccessException(this, "Sequences not supported");
243         }
244         Connection JavaDoc connection = null;
245         try {
246             connection = getNewConnection();
247             return ((SequenceAdapter) adapter).createSequence(connection, sequenceName);
248         } catch (SQLException JavaDoc e) {
249             throw new ServiceAccessException(this, e);
250         } finally {
251             if (connection != null) {
252                 try {
253                     if (!tmCommits) {
254                         connection.commit();
255                     }
256                 } catch (SQLException JavaDoc e) {
257                     throw new ServiceAccessException(this, e);
258                 } finally {
259                     try {
260                         connection.close();
261                     } catch (SQLException JavaDoc e) {
262                         getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
263                     }
264                 }
265             }
266         }
267     }
268
269     /**
270      * @see org.apache.slide.store.SequenceStore#isSequenceSupported()
271      */

272     public boolean isSequenceSupported() {
273         // cache it for better performance as support of an adapter will
274
// not change will running, it is either yes or no all the time
275
if (isSequenceSupported > 0)
276             return true;
277         if (isSequenceSupported < 0)
278             return false;
279         Connection JavaDoc connection = null;
280         try {
281             connection = getNewConnection();
282             if (adapter instanceof SequenceAdapter && ((SequenceAdapter) adapter).isSequenceSupported(connection)) {
283                 isSequenceSupported = 1;
284                 return true;
285             } else {
286                 isSequenceSupported = -1;
287                 return false;
288             }
289         } catch (SQLException JavaDoc e) {
290             getLogger().log(
291                 "Error while trying to check for sequence support. Assuming false",
292                 e,
293                 LOG_CHANNEL,
294                 Logger.ERROR);
295             isSequenceSupported = -1;
296             return false;
297         } finally {
298             if (connection != null) {
299                 try {
300                     if (!tmCommits) {
301                         connection.commit();
302                     }
303                 } catch (SQLException JavaDoc e) {
304                     getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
305                 } finally {
306                     try {
307                         connection.close();
308                     } catch (SQLException JavaDoc e) {
309                         getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
310                     }
311                 }
312             }
313         }
314     }
315
316     /**
317      * @see org.apache.slide.store.SequenceStore#nextSequenceValue(java.lang.String)
318      */

319     public long nextSequenceValue(String JavaDoc sequenceName) throws ServiceAccessException {
320         if (!isSequenceSupported()) {
321             throw new ServiceAccessException(this, "Sequences not supported");
322         }
323         Connection JavaDoc connection = null;
324         try {
325             connection = getNewConnection();
326             return ((SequenceAdapter) adapter).nextSequenceValue(connection, sequenceName);
327         } catch (SQLException JavaDoc e) {
328             throw new ServiceAccessException(this, e);
329         } finally {
330             if (connection != null) {
331                 try {
332                     if (!tmCommits) {
333                         connection.commit();
334                     }
335                 } catch (SQLException JavaDoc e) {
336                     throw new ServiceAccessException(this, e);
337                 } finally {
338                     try {
339                         connection.close();
340                     } catch (SQLException JavaDoc e) {
341                         getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
342                     }
343                 }
344             }
345         }
346     }
347
348     /**
349      * @see org.apache.slide.store.SequenceStore#sequenceExists(java.lang.String)
350      */

351     public boolean sequenceExists(String JavaDoc sequenceName) throws ServiceAccessException {
352         if (!isSequenceSupported()) {
353             throw new ServiceAccessException(this, "Sequences not supported");
354         }
355         Connection JavaDoc connection = null;
356         try {
357             connection = getNewConnection();
358             return ((SequenceAdapter) adapter).sequenceExists(connection, sequenceName);
359         } catch (SQLException JavaDoc e) {
360             throw new ServiceAccessException(this, e);
361         } finally {
362             if (connection != null) {
363                 try {
364                     if (!tmCommits) {
365                         connection.commit();
366                     }
367                 } catch (SQLException JavaDoc e) {
368                     throw new ServiceAccessException(this, e);
369                 } finally {
370                     try {
371                         connection.close();
372                     } catch (SQLException JavaDoc e) {
373                         getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
374                     }
375                 }
376             }
377         }
378     }
379
380     // ----------------------------------------------- NodeStore Implementation
381

382     /**
383      * Retrieve an object.
384      *
385      * @param uri Uri of the object we want to retrieve
386      * @exception ServiceAccessException Error accessing the Service
387      * @exception ObjectNotFoundException The object to retrieve was not found
388      */

389     public ObjectNode retrieveObject(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
390
391         if (getCurrentlyActiveTransactionalResource() == null) {
392             Connection JavaDoc connection = null;
393             try {
394                 connection = getNewConnection();
395                 return adapter.retrieveObject(connection, uri);
396             } catch (SQLException JavaDoc e) {
397                 throw new ServiceAccessException(this, e);
398             } finally {
399                 if (connection != null) {
400                     try {
401                         if (!tmCommits) {
402                             connection.commit();
403                         }
404                     } catch (SQLException JavaDoc e) {
405                         throw new ServiceAccessException(this, e);
406                     } finally {
407                         try {
408                             connection.close();
409                         } catch (SQLException JavaDoc e) {
410                             getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
411                         }
412                     }
413                 }
414             }
415         } else {
416             return adapter.retrieveObject(getCurrentConnection(), uri);
417         }
418     }
419
420     /**
421      * Update an object.
422      *
423      * @param object Object to update
424      * @exception ServiceAccessException Error accessing the Service
425      * @exception ObjectNotFoundException The object to update was not found
426      */

427     public void storeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
428
429         adapter.storeObject(getCurrentConnection(), uri, object);
430     }
431
432     /**
433      * Create a new object.
434      *
435      * @param object ObjectNode
436      * @param uri Uri of the object we want to create
437      * @exception ServiceAccessException Error accessing the Service
438      * @exception ObjectAlreadyExistsException An object already exists
439      * at this Uri
440      */

441     public void createObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectAlreadyExistsException {
442
443         adapter.createObject(getCurrentConnection(), uri, object);
444     }
445
446     /**
447      * Remove an object.
448      *
449      * @param object Object to remove
450      * @exception ServiceAccessException Error accessing the Service
451      * @exception ObjectNotFoundException The object to remove was not found
452      */

453     public void removeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
454
455         adapter.removeObject(getCurrentConnection(), uri, object);
456     }
457
458     // ------------------------------------------- SecurityStore Implementation
459

460     /**
461      * Grant a new permission.
462      *
463      * @param permission Permission we want to create
464      * @exception ServiceAccessException Error accessing the Service
465      */

466     public void grantPermission(Uri uri, NodePermission permission) throws ServiceAccessException {
467
468         adapter.grantPermission(getCurrentConnection(), uri, permission);
469     }
470
471     /**
472      * Revoke a permission.
473      *
474      * @param permission Permission we want to create
475      * @exception ServiceAccessException Error accessing the Service
476      */

477     public void revokePermission(Uri uri, NodePermission permission) throws ServiceAccessException {
478
479         adapter.revokePermission(getCurrentConnection(), uri, permission);
480     }
481
482     /**
483      * Revoke all the permissions on an object.
484      *
485      * @param permission Permission we want to create
486      * @exception ServiceAccessException Error accessing the Service
487      */

488     public void revokePermissions(Uri uri) throws ServiceAccessException {
489
490         adapter.revokePermissions(getCurrentConnection(), uri);
491     }
492
493     /**
494      * Enumerate permissions on an object.
495      *
496      * @param permission Permission we want to create
497      * @exception ServiceAccessException Error accessing the Service
498      */

499     public Enumeration JavaDoc enumeratePermissions(Uri uri) throws ServiceAccessException {
500         if (getCurrentlyActiveTransactionalResource() == null) {
501             Connection JavaDoc connection = null;
502             try {
503                 connection = getNewConnection();
504                 return adapter.enumeratePermissions(connection, uri);
505             } catch (SQLException JavaDoc e) {
506                 throw new ServiceAccessException(this, e);
507             } finally {
508                 if (connection != null) {
509                     try {
510                         if (!tmCommits) {
511                             connection.commit();
512                         }
513                     } catch (SQLException JavaDoc e) {
514                         throw new ServiceAccessException(this, e);
515                     } finally {
516                         try {
517                             connection.close();
518                         } catch (SQLException JavaDoc e) {
519                             getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
520                         }
521                     }
522                 }
523             }
524         } else {
525             return adapter.enumeratePermissions(getCurrentConnection(), uri);
526         }
527     }
528
529     // ----------------------------------------------- LockStore Implementation
530

531     /**
532      * Create a new lock.
533      *
534      * @param lock Lock token
535      * @exception ServiceAccessException Service access error
536      */

537     public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
538
539         adapter.putLock(getCurrentConnection(), uri, lock);
540     }
541
542     /**
543      * Refresh a lock.
544      *
545      * @param lock the lock to renew
546      * @exception ServiceAccessException Service access error
547      * @exception LockTokenNotFoundException Lock token was not found
548      */

549     public void renewLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
550
551         adapter.renewLock(getCurrentConnection(), uri, lock);
552     }
553
554     /**
555      * Unlock.
556      *
557      * @param lock Token to remove
558      * @exception ServiceAccessException Service access error
559      * @exception LockTokenNotFoundException Lock token was not found
560      */

561     public void removeLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
562
563         adapter.removeLock(getCurrentConnection(), uri, lock);
564     }
565
566     /**
567      * Kill a lock.
568      *
569      * @param lock Token to remove
570      * @exception ServiceAccessException Service access error
571      * @exception LockTokenNotFoundException Lock token was not found
572      */

573     public void killLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
574
575         adapter.killLock(getCurrentConnection(), uri, lock);
576     }
577
578     /**
579      * Enumerate locks on an object.
580      *
581      * @param subject Subject
582      * @return Enumeration List of locks which have been put on the subject
583      * @exception ServiceAccessException Service access error
584      */

585     public Enumeration JavaDoc enumerateLocks(Uri uri) throws ServiceAccessException {
586         if (getCurrentlyActiveTransactionalResource() == null) {
587             Connection JavaDoc connection = null;
588             try {
589                 connection = getNewConnection();
590                 return adapter.enumerateLocks(connection, uri);
591             } catch (SQLException JavaDoc e) {
592                 throw new ServiceAccessException(this, e);
593             } finally {
594                 if (connection != null) {
595                     try {
596                         if (!tmCommits) {
597                             connection.commit();
598                         }
599                     } catch (SQLException JavaDoc e) {
600                         throw new ServiceAccessException(this, e);
601                     } finally {
602                         try {
603                             connection.close();
604                         } catch (SQLException JavaDoc e) {
605                             getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
606                         }
607                     }
608                 }
609             }
610         } else {
611             return adapter.enumerateLocks(getCurrentConnection(), uri);
612         }
613     }
614
615     // -------------------------------- RevisionDescriptorsStore Implementation
616

617     /**
618      * Retrieve the revisions informations of an object.
619      *
620      * @param uri Uri
621      * @exception ServiceAccessException Service access error
622      * @exception RevisionDescriptorNotFoundException Revision descriptor
623      * was not found
624      */

625     public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
626         throws ServiceAccessException, RevisionDescriptorNotFoundException {
627         if (getCurrentlyActiveTransactionalResource() == null) {
628             Connection JavaDoc connection = null;
629             try {
630                 connection = getNewConnection();
631                 return adapter.retrieveRevisionDescriptors(connection, uri);
632             } catch (SQLException JavaDoc e) {
633                 throw new ServiceAccessException(this, e);
634             } finally {
635                 if (connection != null) {
636                     try {
637                         if (!tmCommits) {
638                             connection.commit();
639                         }
640                     } catch (SQLException JavaDoc e) {
641                         throw new ServiceAccessException(this, e);
642                     } finally {
643                         try {
644                             connection.close();
645                         } catch (SQLException JavaDoc e) {
646                             getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
647                         }
648                     }
649                 }
650             }
651         } else {
652             return adapter.retrieveRevisionDescriptors(getCurrentConnection(), uri);
653         }
654     }
655
656     /**
657      * Create a new revision information object.
658      *
659      * @param uri Uri
660      * @param revisionDescriptors Node revision descriptors
661      * @exception ServiceAccessException Service access error
662      */

663     public void createRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
664         throws ServiceAccessException {
665
666         adapter.createRevisionDescriptors(getCurrentConnection(), uri, revisionDescriptors);
667     }
668
669     /**
670      * Update revision information.
671      *
672      * @param uri Uri
673      * @param revisionDescriptors Node revision descriptors
674      * @exception ServiceAccessException Service access error
675      * @exception RevisionDescriptorNotFoundException Revision descriptor
676      * was not found
677      */

678     public void storeRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
679         throws ServiceAccessException, RevisionDescriptorNotFoundException {
680
681         adapter.storeRevisionDescriptors(getCurrentConnection(), uri, revisionDescriptors);
682     }
683
684     /**
685      * Remove revision information.
686      *
687      * @param uri Uri
688      * @exception ServiceAccessException Service access error
689      */

690     public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException {
691
692         adapter.removeRevisionDescriptors(getCurrentConnection(), uri);
693     }
694
695     // --------------------------------- RevisionDescriptorStore Implementation
696

697     /**
698      * Retrieve an individual object's revision descriptor.
699      *
700      * @param Uri uri
701      * @param revisionNumber Node revision number
702      */

703     public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
704         throws ServiceAccessException, RevisionDescriptorNotFoundException {
705         if (getCurrentlyActiveTransactionalResource() == null) {
706             Connection JavaDoc connection = null;
707             try {
708                 connection = getNewConnection();
709                 return adapter.retrieveRevisionDescriptor(connection, uri, revisionNumber);
710             } catch (SQLException JavaDoc e) {
711                 throw new ServiceAccessException(this, e);
712             } finally {
713                 if (connection != null) {
714                     try {
715                         if (!tmCommits) {
716                             connection.commit();
717                         }
718                     } catch (SQLException JavaDoc e) {
719                         throw new ServiceAccessException(this, e);
720                     } finally {
721                         try {
722                             connection.close();
723                         } catch (SQLException JavaDoc e) {
724                             getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
725                         }
726                     }
727                 }
728             }
729         } else {
730             return adapter.retrieveRevisionDescriptor(getCurrentConnection(), uri, revisionNumber);
731         }
732     }
733
734     /**
735      * Create a new revision descriptor.
736      *
737      * @param uri Uri
738      * @param revisionDescriptor Node revision descriptor
739      * @exception ServiceAccessException Service access error
740      */

741     public void createRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
742         throws ServiceAccessException {
743
744         adapter.createRevisionDescriptor(getCurrentConnection(), uri, revisionDescriptor);
745     }
746
747     /**
748      * Update a revision descriptor.
749      *
750      * @param uri Uri
751      * @param revisionDescriptors Node revision descriptor
752      * @exception ServiceAccessException Service access error
753      * @exception RevisionDescriptorNotFoundException Revision descriptor
754      * was not found
755      */

756     public void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
757         throws ServiceAccessException, RevisionDescriptorNotFoundException {
758
759         adapter.storeRevisionDescriptor(getCurrentConnection(), uri, revisionDescriptor);
760     }
761
762     /**
763      * Remove a revision descriptor.
764      *
765      * @param uri Uri
766      * @param revisionNumber Revision number
767      * @exception ServiceAccessException Service access error
768      */

769     public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber) throws ServiceAccessException {
770
771         adapter.removeRevisionDescriptor(getCurrentConnection(), uri, revisionNumber);
772     }
773
774     // -------------------------------------------- ContentStore Implementation
775

776     /**
777      * Retrieve revision content.
778      *
779      * @param uri Uri
780      * @param revisionNumber Node revision number
781      */

782     public NodeRevisionContent retrieveRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
783         throws ServiceAccessException, RevisionNotFoundException {
784         if (getCurrentlyActiveTransactionalResource() == null) {
785             Connection JavaDoc connection = null;
786             try {
787                 connection = getNewConnection();
788                 return adapter.retrieveRevisionContent(connection, uri, revisionDescriptor, true);
789             } catch (SQLException JavaDoc e) {
790                 // only close connection in case of error as standard closing
791
// will be done in adapter or upon closing of stream
792
if (connection != null) {
793                     try {
794                         if (!tmCommits) {
795                             connection.rollback();
796                         }
797                     } catch (SQLException JavaDoc e2) {
798                         throw new ServiceAccessException(this, e2);
799                     } finally {
800                         try {
801                             connection.close();
802                         } catch (SQLException JavaDoc e2) {
803                             getLogger().log(e2, LOG_CHANNEL, Logger.WARNING);
804                         }
805                     }
806                 }
807                 throw new ServiceAccessException(this, e);
808             }
809         } else {
810             return adapter.retrieveRevisionContent(getCurrentConnection(), uri, revisionDescriptor, false);
811         }
812     }
813
814     /**
815      * Create a new revision
816      *
817      * @param uri Uri
818      * @param revisionDescriptor Node revision descriptor
819      * @param revisionContent Node revision content
820      */

821     public void createRevisionContent(
822         Uri uri,
823         NodeRevisionDescriptor revisionDescriptor,
824         NodeRevisionContent revisionContent)
825         throws ServiceAccessException, RevisionAlreadyExistException {
826
827         adapter.createRevisionContent(getCurrentConnection(), uri, revisionDescriptor, revisionContent);
828     }
829
830     /**
831      * Modify the latest revision of an object.
832      *
833      * @param uri Uri
834      * @param revisionDescriptor Node revision descriptor
835      * @param revisionContent Node revision content
836      */

837     public void storeRevisionContent(
838         Uri uri,
839         NodeRevisionDescriptor revisionDescriptor,
840         NodeRevisionContent revisionContent)
841         throws ServiceAccessException, RevisionNotFoundException {
842
843         adapter.storeRevisionContent(getCurrentConnection(), uri, revisionDescriptor, revisionContent);
844     }
845
846     /**
847      * Remove revision.
848      *
849      * @param uri Uri
850      * @param revisionNumber Node revision number
851      */

852     public void removeRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
853         throws ServiceAccessException {
854
855         adapter.removeRevisionContent(getCurrentConnection(), uri, revisionDescriptor);
856     }
857
858     // ------------------------------------------------------ Protected Methods
859

860     // XXX just for visibility in RDBMSComparableResourcesPool
861
protected TransactionalResource getCurrentlyActiveTransactionalResource() {
862         return super.getCurrentlyActiveTransactionalResource();
863     }
864     
865     /**
866      * Get the Connection object associated with the current transaction.
867      */

868     protected Connection JavaDoc getCurrentConnection() throws ServiceAccessException {
869
870         getLogger().log("Getting current connection for thread " + Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
871         TransactionId id = (TransactionId) getCurrentlyActiveTransactionalResource();
872         if (id == null) {
873             getLogger().log("No id for current thread - called outside transaction?", LOG_CHANNEL, Logger.DEBUG);
874             return null;
875         }
876         return id.connection;
877     }
878
879     abstract protected Connection JavaDoc getNewConnection() throws SQLException JavaDoc;
880
881     protected TransactionalResource createTransactionResource(Xid JavaDoc xid) throws SQLException JavaDoc {
882             return new TransactionId(xid);
883     }
884     
885     private class TransactionId extends AbstractTransactionalResource {
886         Xid JavaDoc xid;
887         int status;
888         Connection JavaDoc connection;
889
890         TransactionId(Xid JavaDoc xid) throws SQLException JavaDoc {
891             super(xid);
892             
893             status = STATUS_ACTIVE;
894             connection = getNewConnection();
895         }
896
897         public void commit() throws XAException JavaDoc {
898             try {
899                 if (!tmCommits) {
900                     connection.commit();
901                 }
902             } catch (SQLException JavaDoc e) {
903                 throw new XAException JavaDoc(XAException.XA_RBCOMMFAIL);
904             } finally {
905                 try {
906                     connection.close();
907                 } catch (SQLException JavaDoc e) {
908                     getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
909                 }
910             }
911         }
912         
913         public void rollback() throws XAException JavaDoc {
914             try {
915                 if (!tmCommits) {
916                     connection.rollback();
917                 }
918             } catch (SQLException JavaDoc e) {
919                 throw new XAException JavaDoc(XAException.XA_RBCOMMFAIL);
920             } finally {
921                 try {
922                     connection.close();
923                 } catch (SQLException JavaDoc e) {
924                     getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
925                 }
926             }
927         }
928
929         public int prepare() throws XAException JavaDoc {
930             // no check possible
931
return XA_OK;
932         }
933
934         public void begin() throws XAException JavaDoc {
935         }
936
937         public void suspend() throws XAException JavaDoc {
938         }
939
940         public void resume() throws XAException JavaDoc {
941         }
942
943     }
944
945 }
946
Popular Tags