KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > NestingInfo


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 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28
29 //----------------------------------------------------------------------------
30
//
31
// Module: NestingInfo.java
32
//
33
// Description: Subtransaction state management.
34
//
35
// Product: com.sun.jts.CosTransactions
36
//
37
// Author: Simon Holdsworth
38
//
39
// Date: March, 1997
40
//
41
// Copyright (c): 1995-1997 IBM Corp.
42
//
43
// The source code for this program is not published or otherwise divested
44
// of its trade secrets, irrespective of what has been deposited with the
45
// U.S. Copyright Office.
46
//
47
// This software contains confidential and proprietary information of
48
// IBM Corp.
49
//----------------------------------------------------------------------------
50

51 package com.sun.jts.CosTransactions;
52
53 import java.util.*;
54
55 import org.omg.CORBA.*;
56 import org.omg.CosTransactions.*;
57
58 /**
59  * The NestingInfo interface provides operations that record all nesting
60  * information relevant to a Coordinator, that is, the set of children
61  * (SubCoordinators) and the sequence of ancestors (Coordinators/global IDs).
62  * As an instance of this class may be accessed from multiple threads within a
63  * process, serialisation for thread-safety is necessary in the
64  * implementation. The information recorded in an instance of this class does
65  * not need to be reconstructible in the case of a system failure as
66  * subtransactions are not durable.
67  *
68  * @version 0.01
69  *
70  * @author Simon Holdsworth, IBM Corporation
71  *
72  * @see
73  */

74 class NestingInfo {
75     CoordinatorImpl[] ancestorSeq = null;
76     Vector childSet = new Vector();
77     boolean removed = false;
78
79     /**
80      * Default NestingInfo constructor.
81      *
82      * @param
83      *
84      * @return
85      *
86      * @see
87      */

88     NestingInfo() {}
89
90     /**
91      * Defines the sequence of ancestors and initialises the
92      * set of children to be empty.
93      *
94      * @param ancestors The ancestors
95      *
96      * @return
97      *
98      * @see
99      */

100     NestingInfo(CoordinatorImpl[] ancestors) {
101
102         // If the sequence of ancestors is empty, set the removed flag as this
103
// NestingInfo is part of a top-level transaction.
104

105         ancestorSeq = (CoordinatorImpl[])ancestors.clone();
106         removed = (ancestors.length == 0);
107     }
108
109     /**
110      * Cleans up the state of the object.
111      *
112      * @param
113      *
114      * @return
115      *
116      * @see
117      */

118     public void finalize() {
119
120     if( childSet != null ) childSet.removeAllElements();
121         childSet = null;
122
123         if( ancestorSeq != null )
124           {
125           for( int i = 0; i < ancestorSeq.length; i++ )
126             ancestorSeq[i] = null;
127           ancestorSeq = null;
128           }
129     }
130
131     /**
132      * Adds the given SubCoordinator as a child.
133      * <p>
134      * If the reference is already in the set, the operation returns false.
135      *
136      * @param child The child Coordinator.
137      *
138      * @return Indicates success of the operation.
139      *
140      * @see
141      */

142     boolean addChild(CoordinatorImpl child) {
143
144         boolean result = !childSet.contains(child);
145         if( result ) childSet.addElement(child);
146
147         return result;
148     }
149
150     /**
151      * Removes the given SubCoordinator as a child.
152      * <p>
153      * If the reference is not in the set, the operation returns false.
154      *
155      * @param child The child Coordinator.
156      *
157      * @return Indicates success of the operation.
158      *
159      * @see
160      */

161     boolean removeChild(CoordinatorImpl child) {
162         boolean result = childSet.removeElement(child);
163         return result;
164     }
165
166     /**
167      * Empties the set of children.
168      *
169      * @param
170      *
171      * @return
172      *
173      * @see
174      */

175     void empty() {
176         childSet.removeAllElements();
177     }
178
179     /**
180      * Removes the given Coordinator as a child from the parent Coordinator.
181      * <p>
182      * If the child could not be removed from the parent, the operation returns
183      * false.
184      *
185      * @param child The child coordinator.
186      *
187      * @return Indicates success of the operation.
188      *
189      * @see
190      */

191     boolean removeFromParent(CoordinatorImpl child) {
192
193         // If not already done, remove the child from the set of its parents.
194
// If the NestingInfo instance was created for a top-level
195
// transaction, the known to parent flag will always be set.
196
// NOTE: Assumes parent is a CoordinatorImpl.
197

198         boolean result = true;
199         if(!removed) {
200             CoordinatorImpl parent = ancestorSeq[0];
201
202             result = parent.removeChild(child);
203             removed = true;
204         }
205
206         return result;
207     }
208
209     /**
210      * Returns a reference to the parent Coordinator.
211      * <p>
212      * If there is none, returns null.
213      * <p>
214      * The parent Coordinator is the first in the sequence of ancestors.
215      * <p>
216      * If the forgetting flag is set, the NestingInfo must not call the parent
217      * when the child calls removeFromParent.
218      *
219      * @param forgetting Indicates whether the transaction is being forgotten.
220      *
221      * @return The parent Coordinator.
222      *
223      * @see
224      */

225     CoordinatorImpl getParent(boolean forgetting) {
226
227         CoordinatorImpl result = null;
228
229         // If there are no ancestors, there is no parent,
230
// otherwise return the first ancestor.
231

232         if (ancestorSeq.length != 0)
233             result = ancestorSeq[0];
234
235         // If the Coordinator is being cleaned up, then we must not
236
// call the parent when the child calls removeFromParent.
237

238         if( forgetting ) removed = true;
239
240         return result;
241     }
242
243     /**
244      * Returns a reference to the top-level Coordinator.
245      * <p>
246      * If the containing Coordinator is the top-level one, a null reference is
247      * returned.
248      * <p>
249      * The top-level Coordinator is the last in the sequence of ancestors.
250      *
251      * @param
252      *
253      * @return The top-level ancestor.
254      *
255      * @see
256      */

257     CoordinatorImpl getTopLevel() {
258
259         CoordinatorImpl result = null;
260
261         // If there are no ancestors, there is no top-level,
262
// otherwise return the last ancestor.
263

264         if( ancestorSeq.length != 0 )
265             result = ancestorSeq[ancestorSeq.length - 1];
266
267         return result;
268     }
269
270     /**
271      * Returns a copy of the sequence of ancestors of the Coordinator.
272      * <p>
273      * If the containing Coordinator is the top-level one, an empty
274      * sequence is returned.
275      * <p>
276      * The caller is responsible for freeing the sequence storage.
277      *
278      * @param
279      *
280      * @return The sequence of ancestors.
281      *
282      * @see
283      */

284     CoordinatorImpl[] getAncestors() {
285
286         CoordinatorImpl[] result = null;
287
288         // If there are no ancestors, return the empty sequence.
289
// If we cannot obtain a buffer to copy the sequence, return
290
// empty sequence Perhaps an exception should be raised instead ?
291

292         result = (CoordinatorImpl[]) ancestorSeq.clone();
293
294         return result;
295     }
296
297     /**
298      * Returns a count of the number of children that have been defined.
299      * <p>
300      * If no nesting information has been defined, the operation returns 0.
301      *
302      * @param
303      *
304      * @return The number of children.
305      *
306      * @see
307      */

308     int numChildren() {
309         return childSet.size();
310     }
311
312     /**
313      * Checks whether any child represents an active transaction.
314      * <p>
315      * This is used during sending_reply to check for outstanding work.
316      * <p>
317      * 'active' here means subordinate children that have not
318      * registered with their superior, or root children -
319      * these represent parts of a transaction that may not be
320      * committed or rolled back before the parent completes.
321      *
322      * @param
323      *
324      * @return Indicates if all is OK.
325      *
326      * @see
327      */

328     boolean replyCheck() {
329
330         boolean result = false;
331
332         // If there are any children, browse through the set, checking them.
333

334         for (int i = 0; i < childSet.size() && !result; i++) {
335             CoordinatorImpl child = (CoordinatorImpl) childSet.elementAt(i);
336             result = child.isActive();
337         }
338
339         return result;
340     }
341
342     /**
343      * Determines whether the Coordinator containing the NestingInfo object is
344      * a descendant of the other Coordinator.
345      * <p>
346      * This is true if the other Coordinator is the same
347      * as one of the ancestors.
348      *
349      * @param other The other Coordinator.
350      *
351      * @return Indicates success of the operation.
352      *
353      * @see
354     */

355     boolean isDescendant(Coordinator other) {
356
357         boolean result = false;
358
359         // Go through the ancestors, checking whether the given
360
// transaction is the same as any of them.
361

362         try {
363             for (int i = 0; i < ancestorSeq.length && !result; i++) {
364                 result = ancestorSeq[i].is_same_transaction(other);
365             }
366         } catch(SystemException exc) {
367             result = false;
368         }
369
370         return result;
371     }
372
373     /**
374      * Rolls back all children in the set; if there are none the operation does
375      * nothing.
376      *
377      * @param
378      *
379      * @return
380      *
381      * @see
382      */

383     void rollbackFamily() {
384
385         // If there are any children, browse through the set,
386
// rolling them back.
387

388         while (childSet.size() > 0) {
389
390             // Note that we browse in a different way here, as each
391
// child removes itself from the set when the rollback is
392
// complete, so we just keep getting the
393
// first element in the set until the set is empty.
394

395             CoordinatorImpl child = (CoordinatorImpl)childSet.elementAt(0);
396             try {
397                 child.rollback(true);
398             } catch (Throwable JavaDoc exc) {}
399         }
400     }
401 }
402
Popular Tags