KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > invocation > pooled > interfaces > OptimizedObjectInputStream


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.invocation.pooled.interfaces;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.ObjectInputStream JavaDoc;
27 import java.io.ObjectStreamClass JavaDoc;
28 import java.lang.ref.WeakReference JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.lang.reflect.Proxy JavaDoc;
31
32 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
33
34 /**
35  * An ObjectInputStream subclass used by the MarshalledValue class to
36  * ensure the classes and proxies are loaded using the thread context
37  * class loader.
38  *
39  * @author Scott.Stark@jboss.org
40  * @author Clebert.Suconic@jboss.org
41  * @version $Revision: 44821 $
42  */

43 public class OptimizedObjectInputStream
44         extends ObjectInputStream JavaDoc
45 {
46    /** A class wide cache of proxy classes populated by resolveProxyClass */
47    private static ConcurrentReaderHashMap classCache;
48    private static ConcurrentReaderHashMap objectStreamClassCache;
49    private static Method JavaDoc lookupStreamClass = null;
50
51    static
52    {
53       useClassCache(true);
54       try
55       {
56          lookupStreamClass = ObjectStreamClass JavaDoc.class.getDeclaredMethod("lookup", new Class JavaDoc[]{Class JavaDoc.class, boolean.class});
57          lookupStreamClass.setAccessible(true);
58       }
59       catch (Exception JavaDoc ex)
60       {
61          ex.printStackTrace();
62       }
63    }
64
65    /** Enable local caching of resolved proxy classes. This can only be used
66     * if there is a single ULR and no redeployment of the proxy classes.
67     *
68     * @param flag true to enable caching, false to disable it
69     */

70    public static void useClassCache(boolean flag)
71    {
72       if (flag == true)
73       {
74          classCache = new ConcurrentReaderHashMap();
75          objectStreamClassCache = new ConcurrentReaderHashMap();
76       }
77       else
78       {
79          classCache = null;
80          objectStreamClassCache = null;
81       }
82    }
83
84    /** Clear the current proxy cache.
85     *
86     */

87    public static void flushClassCache()
88    {
89       classCache.clear();
90       objectStreamClassCache.clear();
91    }
92
93    private static Class JavaDoc forName(String JavaDoc className) throws ClassNotFoundException JavaDoc
94    {
95       Class JavaDoc clazz = null;
96       if (classCache != null)
97       {
98          WeakReference JavaDoc ref = (WeakReference JavaDoc) classCache.get(className);
99          if (ref != null) clazz = (Class JavaDoc) ref.get();
100          if (clazz == null)
101          {
102             if (ref != null) classCache.remove(className);
103             ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
104             try
105             {
106                clazz = loader.loadClass(className);
107             }
108             catch (ClassNotFoundException JavaDoc e)
109             {
110                /* Use the Class.forName call which will resolve array classes. We
111                do not use this by default as this can result in caching of stale
112                values across redeployments.
113                */

114                clazz = Class.forName(className, false, loader);
115             }
116             classCache.put(className, new WeakReference JavaDoc(clazz));
117          }
118       }
119       else
120       {
121          clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
122       }
123       return clazz;
124    }
125
126    /**
127     * Creates a new instance of MarshalledValueOutputStream
128     */

129    public OptimizedObjectInputStream(InputStream JavaDoc is) throws IOException JavaDoc
130    {
131       super(is);
132    }
133
134    protected static ObjectStreamClass JavaDoc lookup(Class JavaDoc clazz)
135    {
136       Object JavaDoc[] args = {clazz, Boolean.TRUE};
137       try
138       {
139          return (ObjectStreamClass JavaDoc) lookupStreamClass.invoke(null, args);
140       }
141       catch (Exception JavaDoc ex)
142       {
143          ex.printStackTrace();
144       }
145       return null;
146    }
147
148    protected ObjectStreamClass JavaDoc readClassDescriptor()
149            throws IOException JavaDoc, ClassNotFoundException JavaDoc
150    {
151       if (CompatibilityVersion.pooledInvokerLegacy)
152       {
153           String JavaDoc className = readUTF();
154           ObjectStreamClass JavaDoc osc = null;
155           if (objectStreamClassCache != null)
156           {
157              osc = (ObjectStreamClass JavaDoc) objectStreamClassCache.get(className);
158           }
159           if (osc == null)
160           {
161              Class JavaDoc clazz = forName(className);
162              osc = ObjectStreamClass.lookup(clazz);
163              if (osc == null) osc = lookup(clazz);
164              if (osc == null) throw new IOException JavaDoc("Unable to readClassDescriptor for class " + className);
165              if (objectStreamClassCache != null) objectStreamClassCache.put(className, osc);
166           }
167           return osc;
168       }
169       else
170       {
171           return super.readClassDescriptor();
172       }
173    }
174
175    /**
176     * Use the thread context class loader to resolve the class
177     *
178     * @throws IOException Any exception thrown by the underlying OutputStream.
179     */

180    protected Class JavaDoc resolveClass(ObjectStreamClass JavaDoc v)
181            throws IOException JavaDoc, ClassNotFoundException JavaDoc
182    {
183       String JavaDoc className = v.getName();
184       return forName(className);
185    }
186
187    protected Class JavaDoc resolveProxyClass(String JavaDoc[] interfaces)
188            throws IOException JavaDoc, ClassNotFoundException JavaDoc
189    {
190       // Load the interfaces from the cache or thread context class loader
191
ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
192       Class JavaDoc[] ifaceClasses = new Class JavaDoc[interfaces.length];
193       for (int i = 0; i < interfaces.length; i++)
194       {
195          String JavaDoc className = interfaces[i];
196          Class JavaDoc iface = forName(className);
197          ifaceClasses[i] = iface;
198       }
199
200       return Proxy.getProxyClass(loader, ifaceClasses);
201    }
202 }
203
Popular Tags