KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > base > io > EJBObjectOutputStream


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 package com.sun.ejb.base.io;
25
26 import java.io.*;
27 import java.security.*;
28 import java.rmi.*;
29 import javax.ejb.*;
30 import javax.naming.*;
31
32
33 import java.util.logging.*;
34 import com.sun.logging.*;
35
36 import com.sun.ejb.containers.BaseContainer;
37 import com.sun.ejb.containers.RemoteBusinessWrapperBase;
38
39 import com.sun.ejb.spi.io.IndirectlySerializable;
40 import com.sun.ejb.spi.io.SerializableObjectFactory;
41 import com.sun.ejb.spi.io.NonSerializableObjectHandler;
42
43 import com.sun.ejb.EJBUtils;
44 import com.sun.enterprise.Switch;
45 import com.sun.enterprise.NamingManager;
46
47
48 import com.sun.corba.ee.spi.ior.IOR;
49 import com.sun.corba.ee.spi.ior.IORFactories;
50 import com.sun.corba.ee.spi.ior.ObjectKey;
51 import com.sun.corba.ee.spi.ior.TaggedProfile ;
52
53 import com.sun.enterprise.util.Utility;
54 import com.sun.enterprise.util.ORBManager;
55
56 import com.sun.corba.ee.spi.presentation.rmi.StubAdapter;
57
58 /**
59  * A class that is used to passivate SFSB conversational state
60  *
61  * @author Mahesh Kannan
62  */

63 class EJBObjectOutputStream
64     extends java.io.ObjectOutputStream JavaDoc
65 {
66
67     protected static Logger _ejbLogger =
68        LogDomains.getLogger(LogDomains.EJB_LOGGER);
69
70     protected NonSerializableObjectHandler handler;
71
72     static final int EJBID_OFFSET = 0;
73     static final int INSTANCEKEYLEN_OFFSET = 8;
74     static final int INSTANCEKEY_OFFSET = 12;
75
76     private static final byte HOME_KEY = (byte)0xff;
77
78     EJBObjectOutputStream(OutputStream out,
79             boolean replaceObject,
80             NonSerializableObjectHandler handler)
81         throws IOException
82     {
83         super(out);
84         if (replaceObject == true) {
85            enableReplaceObject(replaceObject);
86         }
87
88         this.handler = handler;
89     }
90
91     /**
92      * This code is needed to serialize non-Serializable objects that
93      * can be part of a bean's state. See EJB2.0 section 7.4.1.
94      */

95     protected Object JavaDoc replaceObject(Object JavaDoc obj)
96         throws IOException
97     {
98     Object JavaDoc result = obj;
99     if (obj instanceof IndirectlySerializable) {
100         result = ((IndirectlySerializable) obj).getSerializableObjectFactory();
101     } else if (obj instanceof RemoteBusinessWrapperBase) {
102             result = getRemoteBusinessObjectFactory
103                 ((RemoteBusinessWrapperBase)obj);
104     } else if (StubAdapter.isStub(obj) && StubAdapter.isLocal(obj)) {
105         org.omg.CORBA.Object JavaDoc target = (org.omg.CORBA.Object JavaDoc) obj;
106             // If we're here, it's always for the 2.x RemoteHome view.
107
// There is no remote business wrapper class.
108
result = getSerializableEJBReference(target, null);
109     } else if ( obj instanceof Serializable ) {
110         result = obj;
111     } else if (obj instanceof Context) {
112             result = new SerializableJNDIContext((Context) obj);
113         } else {
114         if (_ejbLogger.isLoggable(Level.INFO)) {
115         _ejbLogger.log(Level.INFO,
116             "EJBObjectInputStream_handling_non_serializable_object",
117             obj.getClass().getName());
118         }
119     
120         result = (handler == null)
121         ? obj
122         : handler.handleNonSerializableObject(obj);
123     }
124
125     return result;
126     }
127
128     private Serializable getRemoteBusinessObjectFactory
129         (RemoteBusinessWrapperBase remoteBusinessWrapper)
130         throws IOException {
131         // Create a serializable object with the remote delegate and
132
// the name of the client wrapper class.
133
org.omg.CORBA.Object JavaDoc target = (org.omg.CORBA.Object JavaDoc)
134             remoteBusinessWrapper.getStub();
135         return getSerializableEJBReference(target,
136                       remoteBusinessWrapper.getBusinessInterfaceName());
137     }
138
139     private Serializable getSerializableEJBReference(org.omg.CORBA.Object JavaDoc obj,
140                              String JavaDoc remoteBusinessInterface)
141     throws IOException
142     {
143     Serializable result = (Serializable) obj;
144     try {
145           
146         IOR ior = ((com.sun.corba.ee.spi.orb.ORB)ORBManager.getORB()).getIOR(obj, false);
147         java.util.Iterator JavaDoc iter = ior.iterator();
148
149         byte[] oid = null;
150         if (iter.hasNext()) {
151         TaggedProfile profile = (TaggedProfile) iter.next();
152         ObjectKey objKey = profile.getObjectKey();
153         oid = objKey.getId().getId();
154         }
155
156         long containerId = -1;
157         int keyLength = -1;
158         if ((oid != null) && (oid.length > INSTANCEKEY_OFFSET)) {
159         containerId = Utility.bytesToLong(oid, EJBID_OFFSET);
160         //To be really sure that is indeed a ref generated
161
// by our container we do the following checks
162
keyLength = Utility.bytesToInt(oid, INSTANCEKEYLEN_OFFSET);
163         if (oid.length == keyLength + INSTANCEKEY_OFFSET) {
164             boolean isHomeReference =
165             ((keyLength == 1) && (oid[INSTANCEKEY_OFFSET] == HOME_KEY));
166             if (isHomeReference) {
167             result = new SerializableS1ASEJBHomeReference(containerId);
168             } else {
169             result = new SerializableS1ASEJBObjectReference(containerId,
170                 oid, keyLength, remoteBusinessInterface);
171             }
172         }
173         }
174     } catch (Exception JavaDoc ex) {
175         _ejbLogger.log(Level.WARNING, "Exception while getting serializable object", ex);
176         IOException ioEx = new IOException("Exception during extraction of instance key");
177         ioEx.initCause(ex);
178         throw ioEx;
179     }
180     return result;
181     }
182 }
183
184 final class SerializableJNDIContext
185     implements SerializableObjectFactory
186 {
187     private String JavaDoc name;
188     
189     SerializableJNDIContext(Context ctx)
190         throws IOException
191     {
192         try {
193             // Serialize state for a jndi context. The spec only requires
194
// support for serializing contexts pointing to java:comp/env
195
// or one of its subcontexts. We also support serializing the
196
// references to the the default no-arg InitialContext, as well
197
// as references to the the contexts java: and java:comp. All
198
// other contexts will either not serialize correctly or will
199
// throw an exception during deserialization.
200
this.name = ctx.getNameInNamespace();
201         } catch (NamingException ex) {
202             IOException ioe = new IOException();
203             ioe.initCause(ex);
204             throw ioe;
205         }
206     }
207
208     public Object JavaDoc createObject()
209         throws IOException
210     {
211         try {
212             if ((name == null) || (name.length() == 0)) {
213                 return new InitialContext();
214             } else {
215                 NamingManager nm = Switch.getSwitch().getNamingManager();
216                 return nm.restoreJavaCompEnvContext(name);
217             }
218         } catch (NamingException namEx) {
219             IOException ioe = new IOException();
220             ioe.initCause(namEx);
221             throw ioe;
222     }
223     }
224
225 }
226
227 abstract class AbstractSerializableS1ASEJBReference
228     implements SerializableObjectFactory
229 {
230     protected long containerId;
231     protected String JavaDoc debugStr; //used for loggin purpose only
232

233     protected static Logger _ejbLogger =
234        LogDomains.getLogger(LogDomains.EJB_LOGGER);
235
236     AbstractSerializableS1ASEJBReference(long containerId) {
237     this.containerId = containerId;
238     BaseContainer container = (BaseContainer) Switch.getSwitch().
239         getContainerFactory().getContainer(containerId);
240
241     //container can be null if the app has been undeployed
242
// after this was serialized
243
if (container == null) {
244         _ejbLogger.log(Level.WARNING, "ejb.base.io.EJBOutputStream.null_container: "
245         + containerId);
246         debugStr = "" + containerId;
247     } else {
248         debugStr = container.toString();
249     }
250     }
251
252     protected static java.rmi.Remote JavaDoc doRemoteRefClassLoaderConversion
253         (java.rmi.Remote JavaDoc reference) throws IOException {
254
255         Thread JavaDoc currentThread = Thread.currentThread();
256         ClassLoader JavaDoc contextClassLoader =
257             currentThread.getContextClassLoader();
258         
259         java.rmi.Remote JavaDoc returnReference = reference;
260
261         if( reference.getClass().getClassLoader() !=
262             contextClassLoader) {
263             try {
264                 byte[] serializedRef = IOUtils.serializeObject
265                     (reference, false);
266                 returnReference = (java.rmi.Remote JavaDoc)
267                     IOUtils.deserializeObject(serializedRef, false,
268                                               contextClassLoader);
269                 StubAdapter.connect
270                     (returnReference,
271                      (com.sun.corba.ee.spi.orb.ORB) ORBManager.getORB());
272             } catch(IOException ioe) {
273                 throw ioe;
274             } catch(Exception JavaDoc e) {
275                 IOException ioEx = new IOException(e.getMessage());
276                 ioEx.initCause(e);
277                 throw ioEx;
278             }
279         }
280
281         return returnReference;
282     }
283 }
284
285 final class SerializableS1ASEJBHomeReference
286     extends AbstractSerializableS1ASEJBReference
287 {
288     
289     SerializableS1ASEJBHomeReference(long containerId) {
290     super(containerId);
291     }
292
293     public Object JavaDoc createObject()
294         throws IOException
295     {
296     Object JavaDoc result = null;
297     BaseContainer container = (BaseContainer) Switch.getSwitch().
298         getContainerFactory().getContainer(containerId);
299     //container can be null if the app has been undeployed
300
// after this was serialized
301
if (container == null) {
302         _ejbLogger.log(Level.WARNING, "ejb.base.io.EJBOutputStream.null_container "
303         + debugStr);
304         result = null;
305     } else {
306             // Note that we can assume it's a RemoteHome stub because an
307
// application never sees a reference to the internal
308
// Home for the Remote Business view.
309
result = AbstractSerializableS1ASEJBReference.
310                 doRemoteRefClassLoaderConversion(container.getEJBHomeStub());
311     }
312
313     return result;
314     }
315 }
316
317 final class SerializableS1ASEJBObjectReference
318     extends AbstractSerializableS1ASEJBReference
319 {
320     private byte[] instanceKey;
321
322     // If 3.0 Remote business view, the name of the remote business
323
// interface to which this stub corresponds.
324
private String JavaDoc remoteBusinessInterface;
325
326     SerializableS1ASEJBObjectReference(long containerId,
327         byte[] objKey, int keySize, String JavaDoc remoteBusinessInterfaceName)
328     {
329     super(containerId);
330         remoteBusinessInterface = remoteBusinessInterfaceName;
331     instanceKey = new byte[keySize];
332     System.arraycopy(objKey,
333         EJBObjectOutputStream.INSTANCEKEY_OFFSET, instanceKey, 0, keySize);
334     }
335
336     public Object JavaDoc createObject()
337         throws IOException
338     {
339     Object JavaDoc result = null;
340     BaseContainer container = (BaseContainer) Switch.getSwitch().
341         getContainerFactory().getContainer(containerId);
342     //container can be null if the app has been undeployed
343
// after this was serialized
344
if (container == null) {
345         _ejbLogger.log(Level.WARNING,
346                            "ejb.base.io.EJBOutputStream.null_container: "
347                            + debugStr);
348         result = null;
349     } else {
350             try {
351                 if( remoteBusinessInterface == null ) {
352                     java.rmi.Remote JavaDoc reference = container.
353                         createRemoteReferenceWithId(instanceKey, null);
354                     result = AbstractSerializableS1ASEJBReference.
355                         doRemoteRefClassLoaderConversion(reference);
356                         
357                 } else {
358
359                     String JavaDoc generatedRemoteIntfName = EJBUtils.
360                         getGeneratedRemoteIntfName(remoteBusinessInterface);
361
362                     java.rmi.Remote JavaDoc remoteRef = container.
363                         createRemoteReferenceWithId(instanceKey,
364                                                     generatedRemoteIntfName);
365
366                     java.rmi.Remote JavaDoc newRemoteRef =
367                         AbstractSerializableS1ASEJBReference.
368                             doRemoteRefClassLoaderConversion(remoteRef);
369
370                     
371                     Thread JavaDoc currentThread = Thread.currentThread();
372                     ClassLoader JavaDoc contextClassLoader =
373                         currentThread.getContextClassLoader();
374
375                     result = EJBUtils.createRemoteBusinessObject
376                         (contextClassLoader, remoteBusinessInterface,
377                          newRemoteRef);
378                          
379                 }
380             } catch(Exception JavaDoc e) {
381                 IOException ioex = new IOException("remote ref create error");
382                 ioex.initCause(e);
383                 throw ioex;
384             }
385     }
386
387     return result;
388     }
389 }
390
391
392
Popular Tags