KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jotm > ots > OTSInterceptor


1 /*
2  * @(#) OTSInterceptor.java 1.0 02/07/15
3  *
4  * JOTM: Java Open Transaction Manager
5  *
6  * This module was originally developed by
7  * - INRIA inside the ObjectWeb Consortium(http://www.objectweb.org)
8  *
9  * The original code and portions created by INRIA are
10  * Copyright (C) 2002 - INRIA (www.inria.fr)
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * -Redistributions of source code must retain the above copyright notice, this
17  * list of conditions and the following disclaimer.
18  *
19  * -Redistributions in binary form must reproduce the above copyright notice,
20  * this list of conditions and the following disclaimer in the documentation
21  * and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * --------------------------------------------------------------------------
36  * $Id: OTSInterceptor.java,v 1.7 2004/12/15 22:52:40 tonyortiz Exp $
37  * --------------------------------------------------------------------------
38  */

39 package org.objectweb.jotm.ots;
40
41 import javax.rmi.PortableRemoteObject JavaDoc;
42 import javax.transaction.xa.Xid JavaDoc;
43
44 import org.omg.CORBA.Any JavaDoc;
45 import org.omg.CORBA.LocalObject JavaDoc;
46 import org.omg.CORBA.ORB JavaDoc;
47 import org.omg.CORBA.TCKind JavaDoc;
48 import org.omg.CosTransactions.PropagationContext;
49 import org.omg.CosTransactions.PropagationContextHelper;
50 import org.omg.CosTransactions.TransIdentity;
51 import org.omg.CosTransactions.otid_t;
52 import org.omg.DynamicAny.DynAnyFactory JavaDoc;
53 import org.omg.DynamicAny.DynAnyFactoryHelper JavaDoc;
54 import org.omg.IOP.Codec JavaDoc;
55 import org.omg.IOP.ServiceContext JavaDoc;
56 import org.omg.PortableInterceptor.ForwardRequest JavaDoc;
57 import org.omg.PortableInterceptor.ORBInitInfo JavaDoc;
58 import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName JavaDoc;
59
60 import org.objectweb.jotm.Coordinator;
61 import org.objectweb.jotm.InternalTransactionContext;
62 import org.objectweb.jotm.Terminator;
63 import org.objectweb.jotm.TransactionContext;
64 import org.objectweb.jotm.XidImpl;
65
66 public abstract class OTSInterceptor extends LocalObject JavaDoc {
67
68     // Used to encode/decode the call
69
protected Codec JavaDoc codec;
70
71     // for identifying client or server.
72
protected DynAnyFactory JavaDoc dynAnyFactoryS_;
73     
74     // Service context identifier
75
protected final int TX_CTX_ID = org.omg.IOP.TransactionService.value; //100;
76

77     // ORB instance
78
protected static ORB JavaDoc orb = null ;
79
80     /**
81      * constructor
82      */

83
84     public OTSInterceptor(ORBInitInfo JavaDoc info) {
85     
86         // Get the codec factory
87
org.omg.IOP.CodecFactory JavaDoc factory = info.codec_factory();
88         if(factory == null) throw new RuntimeException JavaDoc();
89
90             // Create codec
91
org.omg.IOP.Encoding JavaDoc how = new org.omg.IOP.Encoding JavaDoc();
92             how.major_version = 1;
93             how.minor_version = 0;
94             how.format = org.omg.IOP.ENCODING_CDR_ENCAPS.value;
95
96             try {
97                 codec = factory.create_codec(how);
98             } catch(org.omg.IOP.CodecFactoryPackage.UnknownEncoding JavaDoc ex) {
99                 throw new RuntimeException JavaDoc();
100         }
101
102         if(codec == null) throw new RuntimeException JavaDoc();
103
104             //
105
// Get the dynamic any factory
106
//
107
DynAnyFactory JavaDoc dynAnyFactory = null;
108             try {
109                 org.omg.CORBA.Object JavaDoc obj = info.resolve_initial_references("DynAnyFactory");
110                 dynAnyFactory = DynAnyFactoryHelper.narrow(obj);
111             } catch(InvalidName JavaDoc ex) {
112                 throw new RuntimeException JavaDoc();
113             } catch(org.omg.CORBA.BAD_PARAM JavaDoc ex) {
114                 throw new RuntimeException JavaDoc();
115         }
116
117         dynAnyFactoryS_ = dynAnyFactory;
118
119     } // end constructor
120

121     protected Any JavaDoc create_any() throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode JavaDoc{
122         org.omg.DynamicAny.DynAny JavaDoc dynAny = dynAnyFactoryS_.create_dyn_any_from_type_code(PropagationContextHelper.type());
123         return dynAny.to_any();
124     }
125
126     /**
127      * Build and returns the CORBA PropagationContext (JTS)
128      */

129     protected ServiceContext JavaDoc buildCorbaPropagationContext(TransactionContext txCtx) throws ForwardRequest JavaDoc {
130         try {
131
132             // Build a new CORBA Propagation context
133
// For the moment, JOTM does not implement tx interoperability EJB2.1 ?19.6 and
134
// so the fields CosTransactions:Coordinator and CosTransactions:Terminator are set
135
// to null in order to generate a 'null transaction ctx'
136
// The coordinator/terminator are propagated in the 'implementation_specific_data' field.
137

138             // Get Information of TransactionContext
139
Xid JavaDoc xid = txCtx.getXid();
140             int timeout = txCtx.getTimeout();
141             Coordinator coord = txCtx.getCoordinator();
142
143             // Xid is coded in the otid_t
144
byte[] gtrid = xid.getGlobalTransactionId();
145             byte[] bqual = xid.getBranchQualifier();
146             byte[] tid = new byte[gtrid.length + bqual.length];
147             System.arraycopy(bqual, 0, tid, 0, bqual.length);
148             System.arraycopy(gtrid, 0, tid, bqual.length, gtrid.length);
149             otid_t otid = new otid_t(xid.getFormatId(), bqual.length, tid);
150
151             // current holds only otid_t
152
TransIdentity curr = new TransIdentity(null, null, otid);
153             
154             // Create the PropagationContext
155
PropagationContext pctx =
156                 new PropagationContext(timeout, curr, new TransIdentity[0], null);
157
158             // In JOTM, the Coordinator and the terminator interface are implemented
159
// by the same class : ControlImpl. The stub is propagated to others JOnAS
160
// instances in the implementation_specific_data field. It is coded in an Any
161
// field
162
if (orb==null){
163                 // Get ORB instance
164
orb=ORB.init(new String JavaDoc[]{}, null) ;
165             }
166             
167             Any JavaDoc specific = orb.create_any();
168             if (coord != null) {
169                 // Set the JOTM's coordinator in the 'specific' field
170
specific.insert_Object((javax.rmi.CORBA.Stub JavaDoc) PortableRemoteObject.toStub(coord));
171                 pctx.implementation_specific_data = specific;
172             } else {
173                 // If the coordinator is unknown, set a 'JONAS' pattern
174
// to allow the other side to recognize a
175
// JOTM context
176
specific.insert_string("JOnAS");
177                 pctx.implementation_specific_data = specific;
178             }
179
180             Any JavaDoc pAny = create_any();
181             PropagationContextHelper.insert(pAny, pctx);
182
183             // encode the PropagationContext in a service context
184
byte[] propagationContextData = codec.encode_value(pAny);
185             return new ServiceContext JavaDoc(TX_CTX_ID, propagationContextData);
186             
187         } catch (Exception JavaDoc e) {
188             throw new ForwardRequest JavaDoc();
189         }
190     }
191
192     /**
193      * decode the Corba Propagation Context and build an internal transaction context
194      * @param sCtx ServiceContext
195      */

196     protected TransactionContext decodeCorbaPropagationContext(ServiceContext JavaDoc sCtx){
197  
198         if (sCtx == null) { // no tx ctx
199

200             return null ;
201         }
202         Xid JavaDoc xid = null;
203         int timeout;
204         Any JavaDoc specific = null ;
205         
206         // try to decode the corba tx context
207
try {
208             // unmarshall the Propagation Context
209
Any JavaDoc pctxAny = codec.decode_value(sCtx.context_data, PropagationContextHelper.type());
210             PropagationContext pctx = PropagationContextHelper.extract(pctxAny);
211
212             // get the propagation context values
213
specific = pctx.implementation_specific_data;
214             otid_t otid = pctx.current.otid;
215             timeout = pctx.timeout;
216             xid = new XidImpl(otid.formatID, otid.bqual_length, otid.tid);
217
218         } catch (Exception JavaDoc e) { // invalid tx ctx
219

220             return null;
221         }
222
223         // JOTM don't be able to detect whether the context is a valid or a null ctx
224
// If it isn't a JOTM's context (fail during decoding), it considers it's a null ctx
225
boolean isJotmCtx=false;
226         Coordinator coord = null;
227         Terminator JavaDoc term = null;
228         
229         try {
230             if ((specific == null) || (specific.type().kind() == TCKind.tk_null) ||
231                 (specific.type().kind() == TCKind.tk_octet)) {
232                     // null ctx or valid ctx but sent from another app server
233
// isJotmCtx=false ;
234
} else if (specific.type().kind() == TCKind.tk_string) {
235                 String JavaDoc pattern = specific.extract_string() ;
236                 // Here, maybe we have received a JOTM context with an unknown coordinator
237
// In this case, a JONAS pattern has been set
238
if (pattern.compareTo("JOnAS")==0) {
239                     isJotmCtx=true ;
240                 }
241
242             } else {
243                 // Last try, it should be a typical JOTM context with the coordinator set in 'specific' field
244
coord = (Coordinator) PortableRemoteObject.narrow((java.rmi.Remote JavaDoc) specific.extract_Object(),
245                         Coordinator.class);
246                 term = (Terminator JavaDoc) PortableRemoteObject.narrow((java.rmi.Remote JavaDoc) specific.extract_Object(),
247                         Terminator JavaDoc.class);
248                 isJotmCtx=true ;
249                 
250
251             }
252         } catch (Exception JavaDoc e) {
253             // null ctx or valid ctx but sent from another app server
254
// isJotmCtx=false ;
255
}
256         
257         TransactionContext tCtx = new InternalTransactionContext(timeout, coord, term, xid);
258         if ( isJotmCtx == false ) {
259             // flag the internal context to indicate the ctx comes from
260
// another vendor
261
tCtx.setNotJotmCtx();
262         }
263         return tCtx;
264     }
265 }
266
267
Popular Tags