KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > support > SynchronizationManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 /*
24  * SynchronizationManager.java
25  *
26  * Created on May 30, 2002, 8:43 AM
27  */

28
29 package com.sun.jdo.api.persistence.support;
30
31 import java.util.ArrayList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Hashtable JavaDoc;
34
35 import javax.transaction.Synchronization JavaDoc;
36
37 /** This class allows for multiple instances to be called at transaction
38  * completion, which JDO does not currently provide. JDO only provides
39  * for a single instance to be registered. This service exploits
40  * the JDO capability by registering an instance of SynchronizationManager
41  * with JDO and then calling each instance registered with itself.
42  *
43  * @author Craig Russell
44  * @version 1.0
45  */

46 public class SynchronizationManager implements Synchronization JavaDoc {
47
48     /** Creates new SynchronizationManager instance specifying the initial
49      * capacity of the list of Synchronization instances.
50      * @param initialCapacity the initial capacity of the List of Synchronization instances
51      */

52     public SynchronizationManager(int initialCapacity) {
53         synchronizations = new ArrayList JavaDoc(initialCapacity);
54     }
55     
56     /** Creates new SynchronizationManager instance with a default
57      * capacity of the List of Synchronization instances.
58      */

59     public SynchronizationManager() {
60         this(defaultCapacity);
61     }
62     
63     /** Register a new Synchronization with the current transaction.
64      * @param instance the instance to be registered
65      * @param pm the persistence manager which manages this transaction
66      */

67     public static void registerSynchronization(Synchronization JavaDoc instance, PersistenceManager pm) {
68         SynchronizationManager synchronizationManager = getSynchronizationManager(pm);
69         synchronizationManager.registerSynchronization(instance);
70     }
71     
72     /** Specify the default capacity of the list of Synchronizations.
73      * @param capacity the default capacity of the List of Synchronizations
74      */

75     public static void setDefaultCapacity(int capacity) {
76         defaultCapacity = capacity;
77     }
78     
79     /** The default capacity of the List of Synchronizations.
80      */

81     protected static int defaultCapacity = 100;
82     
83     /** The list of instances to synchronize. Duplicate registrations will
84      * result in the instance being called multiple times. Since we cannot
85      * depend on the caller implementing hashCode and equals, we cannot use
86      * a Set implementaion.
87      */

88     protected final List JavaDoc synchronizations;
89     
90     /** Creates new SynchronizationManager instance and registers it with
91      * the persistence manager.
92      * @param pm the persistence manager managing this transaction
93      */

94     protected SynchronizationManager(PersistenceManager pm) {
95         this();
96         Transaction tx = pm.currentTransaction();
97         tx.setSynchronization((Synchronization JavaDoc)this);
98     }
99     
100     /** Get the synchronization manager already registered with this persistence manager.
101      * If the synchronization instance is not of the proper class, then replace it with
102      * a new instance of the synchronization manager, and register the previous synchronization
103      * with the newly created synchronization manager.
104      * @param pm the persistence manager
105      * @return the synchronization manager
106      */

107     protected static SynchronizationManager getSynchronizationManager(PersistenceManager pm) {
108         Transaction tx = pm.currentTransaction();
109         Synchronization JavaDoc oldsync = tx.getSynchronization();
110         if (oldsync instanceof SynchronizationManager) {
111             // This is the one we want.
112
return (SynchronizationManager) oldsync;
113         } else {
114             // We need a new one. The constructor automatically registers it
115
// with the persistence manager.
116
SynchronizationManager newsync = new SynchronizationManager(pm);
117             if (oldsync != null) {
118                 // There is an existing Synchronization to register with the new one
119
newsync.registerSynchronization(oldsync);
120             }
121             return newsync;
122         }
123     }
124     
125     /** This method will be called during transaction completion. Resource
126      * access is allowed.
127      * This method in turn calls each registered instance beforeCompletion
128      * method.
129      */

130     public void beforeCompletion() {
131         int size = synchronizations.size();
132         for (int i = 0; i < size; ++i) {
133             Synchronization JavaDoc instance = (Synchronization JavaDoc) synchronizations.get(i);
134             instance.beforeCompletion();
135         }
136     }
137     
138     /** This method will be called during transaction completion. No resource
139      * access is allowed.
140      * This method in turn calls each registered instance afterCompletion
141      * method. After this method completes,
142      * instances must register again in the new transaction, but
143      * the synchronization manager remains bound to the persistence manager
144      * transaction instance.
145      * @param status the completion status of the transaction
146      */

147     public void afterCompletion(int status) {
148         int size = synchronizations.size();
149         StringBuffer JavaDoc sb = null;
150         for (int i = 0; i < size; ++i) {
151             Synchronization JavaDoc instance = (Synchronization JavaDoc) synchronizations.get(i);
152             try {
153                 instance.afterCompletion(status);
154             } catch (Exception JavaDoc e) {
155                 if (sb == null) {
156                     sb = new StringBuffer JavaDoc();
157                 }
158                 sb.append(e.getMessage()).append('\n'); // NOI18N
159
}
160         }
161         synchronizations.clear();
162         if (sb != null) {
163             throw new JDOUserException(sb.toString());
164         }
165     }
166     
167     /** Register an instance with this synchronization manager.
168      * Note that this is not thread-safe. If multiple threads call this method
169      * at the same time, the synchronizations List might become corrupt.
170      * The correct way to fix this is to ask the PersistenceManager for the
171      * Multithreaded flag and perform a synchronized add if the flag is true.
172      * We currently do not have the Multithreaded flag implemented.
173      * @param instance the instance to be registered
174      */

175     protected void registerSynchronization(Synchronization JavaDoc instance) {
176         synchronizations.add(instance);
177     }
178     
179 }
180
Popular Tags