KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > orm > ojb > OjbFactoryUtils


1 /*
2  * Copyright 2002-2005 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.orm.ojb;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.ojb.broker.OJBRuntimeException;
22 import org.apache.ojb.broker.PBKey;
23 import org.apache.ojb.broker.PersistenceBroker;
24 import org.apache.ojb.broker.PersistenceBrokerFactory;
25
26 import org.springframework.dao.DataAccessResourceFailureException;
27 import org.springframework.jdbc.datasource.DataSourceUtils;
28 import org.springframework.transaction.support.TransactionSynchronizationAdapter;
29 import org.springframework.transaction.support.TransactionSynchronizationManager;
30
31 /**
32  * Helper class featuring methods for OJB PersistenceBroker handling,
33  * allowing for reuse of PersistenceBroker instances within transactions.
34  *
35  * <p>Used by PersistenceBrokerTemplate and PersistenceBrokerTransactionManager.
36  * Can also be used directly in application code.
37  *
38  * @author Juergen Hoeller
39  * @since 1.1
40  * @see PersistenceBrokerTemplate
41  * @see PersistenceBrokerTransactionManager
42  * @see org.springframework.transaction.jta.JtaTransactionManager
43  */

44 public abstract class OjbFactoryUtils {
45
46     /**
47      * Order value for TransactionSynchronization objects that clean up OJB
48      * PersistenceBrokers. Return DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100
49      * to execute PersistenceBroker cleanup before JDBC Connection cleanup, if any.
50      * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER
51      */

52     public static final int PERSISTENCE_BROKER_SYNCHRONIZATION_ORDER =
53             DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100;
54
55     private static final Log logger = LogFactory.getLog(OjbFactoryUtils.class);
56
57
58     /**
59      * Get an OJB PersistenceBroker for the given PBKey. Is aware of a
60      * corresponding PersistenceBroker bound to the current thread, for
61      * example when using PersistenceBrokerTransactionManager. Will
62      * create a new PersistenceBroker else, if allowCreate is true.
63      * @param pbKey PBKey to create the PersistenceBroker for
64      * @param allowCreate if a non-transactional PersistenceBroker should be created
65      * when no transactional PersistenceBroker can be found for the current thread
66      * @return the PersistenceBroker
67      * @throws DataAccessResourceFailureException if the PersistenceBroker couldn't be created
68      * @throws IllegalStateException if no thread-bound PersistenceBroker found and allowCreate false
69      */

70     public static PersistenceBroker getPersistenceBroker(PBKey pbKey, boolean allowCreate)
71         throws DataAccessResourceFailureException, IllegalStateException JavaDoc {
72
73         PersistenceBrokerHolder pbHolder =
74                 (PersistenceBrokerHolder) TransactionSynchronizationManager.getResource(pbKey);
75         if (pbHolder != null) {
76             return pbHolder.getPersistenceBroker();
77         }
78
79         if (!allowCreate && !TransactionSynchronizationManager.isSynchronizationActive()) {
80             throw new IllegalStateException JavaDoc("No OJB PersistenceBroker bound to thread, " +
81                     "and configuration does not allow creation of non-transactional one here");
82         }
83
84         try {
85             logger.debug("Opening OJB PersistenceBroker");
86             PersistenceBroker pb = PersistenceBrokerFactory.createPersistenceBroker(pbKey);
87
88             if (TransactionSynchronizationManager.isSynchronizationActive()) {
89                 logger.debug("Registering transaction synchronization for OJB PersistenceBroker");
90                 pbHolder = new PersistenceBrokerHolder(pb);
91                 pbHolder.setSynchronizedWithTransaction(true);
92                 TransactionSynchronizationManager.registerSynchronization(
93                     new PersistenceBrokerSynchronization(pbHolder, pbKey));
94                 TransactionSynchronizationManager.bindResource(pbKey, pbHolder);
95             }
96
97             return pb;
98         }
99         catch (OJBRuntimeException ex) {
100             throw new DataAccessResourceFailureException("Could not open OJB PersistenceBroker", ex);
101         }
102     }
103
104     /**
105      * Close the given PersistenceBroker, created for the given PBKey,
106      * if it isn't bound to the thread.
107      * @deprecated in favor of releasePersistenceBroker
108      * @see #releasePersistenceBroker
109      */

110     public static void closePersistenceBrokerIfNecessary(PersistenceBroker pb, PBKey pbKey) {
111         releasePersistenceBroker(pb, pbKey);
112     }
113
114     /**
115      * Close the given PersistenceBroker, created for the given PBKey,
116      * if it is not managed externally (i.e. not bound to the thread).
117      * @param pb PersistenceBroker to close
118      * @param pbKey PBKey that the PersistenceBroker was created with
119      */

120     public static void releasePersistenceBroker(PersistenceBroker pb, PBKey pbKey) {
121         if (pb == null) {
122             return;
123         }
124
125         PersistenceBrokerHolder pbHolder =
126             (PersistenceBrokerHolder) TransactionSynchronizationManager.getResource(pbKey);
127         if (pbHolder != null && pb == pbHolder.getPersistenceBroker()) {
128             // It's the transactional PersistenceBroker: Don't close it.
129
return;
130         }
131
132         logger.debug("Closing OJB PersistenceBroker");
133         pb.close();
134     }
135
136
137     /**
138      * Callback for resource cleanup at the end of a non-OJB transaction
139      * (e.g. when participating in a JtaTransactionManager transaction).
140      * @see org.springframework.transaction.jta.JtaTransactionManager
141      */

142     private static class PersistenceBrokerSynchronization extends TransactionSynchronizationAdapter {
143
144         private final PersistenceBrokerHolder persistenceBrokerHolder;
145
146         private final PBKey pbKey;
147
148         private boolean holderActive = true;
149
150         private PersistenceBrokerSynchronization(PersistenceBrokerHolder pbHolder, PBKey pbKey) {
151             this.persistenceBrokerHolder = pbHolder;
152             this.pbKey = pbKey;
153         }
154
155         public int getOrder() {
156             return PERSISTENCE_BROKER_SYNCHRONIZATION_ORDER;
157         }
158
159         public void suspend() {
160             if (this.holderActive) {
161                 TransactionSynchronizationManager.unbindResource(this.pbKey);
162             }
163         }
164
165         public void resume() {
166             if (this.holderActive) {
167                 TransactionSynchronizationManager.bindResource(this.pbKey, this.persistenceBrokerHolder);
168             }
169         }
170
171         public void beforeCompletion() {
172             TransactionSynchronizationManager.unbindResource(this.pbKey);
173             this.holderActive = false;
174             releasePersistenceBroker(this.persistenceBrokerHolder.getPersistenceBroker(), this.pbKey);
175         }
176     }
177
178 }
179
Popular Tags