OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [rmi/] [server/] [RMIClassLoaderImpl.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose
2
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.rmi.server;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.lang.reflect.Proxy;
44
import java.net.MalformedURLException;
45
import java.net.URL;
46
import java.net.URLClassLoader;
47
import java.rmi.server.RMIClassLoaderSpi;
48
import java.util.ArrayList;
49
import java.util.Hashtable;
50
import java.util.Map;
51
import java.util.StringTokenizer;
52
 
53
/**
54
 * The default implementation of {@link java.rmi.server.RMIClassLoaderSpi}.
55
 *
56
 * @author Roman Kennke (kennke@aicas.com)
57
 */
58
public class RMIClassLoaderImpl extends RMIClassLoaderSpi
59
{
60
  private static class MyClassLoader extends URLClassLoader
61
  {
62
    // Package-private to avoid a trampoline constructor.
63
    MyClassLoader (URL[] urls, ClassLoader parent, String annotation)
64
    {
65
      super (urls, parent);
66
      this.annotation = annotation;
67
    }
68
 
69
    public static String urlToAnnotation (URL[] urls)
70
    {
71
      if (urls.length == 0)
72
        return null;
73
 
74
      CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
75
 
76
      for (int i = 0; i < urls.length; i++)
77
      {
78
        annotation.append (urls [i].toExternalForm());
79
        annotation.append (' ');
80
      }
81
 
82
      return annotation.toString();
83
    }
84
 
85
    public final String getClassAnnotation()
86
    {
87
      return annotation;
88
    }
89
 
90
    private final String annotation;
91
  }
92
 
93
  /**
94
   * This class is used to identify a cached classloader by its codebase and
95
   * the context classloader that is its parent.
96
   */
97
  private static class CacheKey
98
  {
99
     private String mCodeBase;
100
     private ClassLoader mContextClassLoader;
101
 
102
     public CacheKey (String theCodebase, ClassLoader theContextClassLoader)
103
     {
104
       mCodeBase = theCodebase;
105
       mContextClassLoader = theContextClassLoader;
106
     }
107
 
108
    /**
109
     * @return true if the codebase and the context classloader are equal
110
     */
111
    public boolean equals (Object theOther)
112
    {
113
      if (theOther instanceof CacheKey)
114
      {
115
        CacheKey key = (CacheKey) theOther;
116
 
117
        return (equals (this.mCodeBase,key.mCodeBase)
118
                && equals (this.mContextClassLoader, key.mContextClassLoader));
119
        }
120
      return false;
121
    }
122
 
123
    /**
124
     * Test if the two objects are equal or both null.
125
     * @param theOne
126
     * @param theOther
127
     * @return
128
     */
129
    private boolean equals (Object theOne, Object theOther)
130
    {
131
      return theOne != null ? theOne.equals (theOther) : theOther == null;
132
    }
133
 
134
    /**
135
     * @return hashCode
136
     */
137
    public int hashCode()
138
    {
139
      return ((mCodeBase != null           ? mCodeBase.hashCode()           :  0)
140
              ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1));
141
    }
142
 
143
    public String toString()
144
    {
145
      return "[" + mCodeBase + "," + mContextClassLoader + "]";
146
    }
147
 
148
  }
149
 
150
  private static RMIClassLoaderImpl instance = null;
151
 
152
  private static Map cacheLoaders; //map annotations to loaders
153
  private static Map cacheAnnotations; //map loaders to annotations
154
  //class loader for defaultAnnotation
155
  private static MyClassLoader defaultClassLoader;
156
 
157
  //defaultAnnotation is got from system property
158
  // "java.rmi.server.defaultAnnotation"
159
  private static String defaultAnnotation;
160
 
161
  //URL object for defaultAnnotation
162
  private static URL defaultCodebase;
163
 
164
  static
165
  {
166
    // 89 is a nice prime number for Hashtable initial capacity
167
    cacheLoaders = new Hashtable (89);
168
    cacheAnnotations = new Hashtable (89);
169
 
170
    defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation");
171
 
172
    try
173
      {
174
        if (defaultAnnotation != null)
175
          defaultCodebase = new URL (defaultAnnotation);
176
      }
177
    catch (Exception _)
178
      {
179
        defaultCodebase = null;
180
      }
181
 
182
    if (defaultCodebase != null)
183
      {
184
        defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null,
185
                                               defaultAnnotation);
186
        // XXX using getContextClassLoader here *cannot* be right
187
        cacheLoaders.put (new CacheKey (defaultAnnotation,
188
                                        Thread.currentThread().getContextClassLoader()),
189
                                        defaultClassLoader);
190
      }
191
    }
192
 
193
  /**
194
   * This is a singleton class and may only be instantiated once from within
195
   * the {@link #getInstance} method.
196
   */
197
  private RMIClassLoaderImpl()
198
  {
199
  }
200
 
201
  /**
202
   * Returns an instance of RMIClassLoaderImpl.
203
   *
204
   * @return an instance of RMIClassLoaderImpl
205
   */
206
  public static RMIClassLoaderSpi getInstance()
207
  {
208
    if (instance == null)
209
      instance = new RMIClassLoaderImpl();
210
    return instance;
211
  }
212
 
213
  public Class loadClass(String codeBase, String name,
214
                         ClassLoader defaultLoader)
215
    throws MalformedURLException, ClassNotFoundException
216
  {
217
    try
218
      {
219
        if (defaultLoader != null)
220
            return Class.forName(name, false, defaultLoader);
221
      }
222
    catch (ClassNotFoundException e)
223
      {
224
      }
225
 
226
    return Class.forName(name, false, getClassLoader(codeBase));
227
  }
228
 
229
  public Class loadProxyClass(String codeBase, String[] interfaces,
230
                              ClassLoader defaultLoader)
231
      throws MalformedURLException, ClassNotFoundException
232
  {
233
    Class clss[] = new Class[interfaces.length];
234
 
235
    for (int i = 0; i < interfaces.length; i++)
236
      {
237
        clss[i] = loadClass(codeBase, interfaces[i], defaultLoader);
238
      }
239
 
240
    // Chain all class loaders (they may differ).
241
    ArrayList loaders = new ArrayList(clss.length);
242
    ClassLoader loader = null;
243
    for (int i = 0; i < clss.length; i++)
244
      {
245
        loader = clss[i].getClassLoader();
246
        if (! loaders.contains(loader))
247
          {
248
            loaders.add(0, loader);
249
          }
250
      }
251
    if (loaders.size() > 1)
252
      {
253
        loader = new CombinedClassLoader(loaders);
254
      }
255
 
256
    try
257
      {
258
        return Proxy.getProxyClass(loader, clss);
259
      }
260
    catch (IllegalArgumentException e)
261
      {
262
        throw new ClassNotFoundException(null, e);
263
      }
264
  }
265
 
266
  /**
267
   * Gets a classloader for the given codebase and with the current
268
   * context classloader as parent.
269
   *
270
   * @param codebase
271
   *
272
   * @return a classloader for the given codebase
273
   *
274
   * @throws MalformedURLException if the codebase contains a malformed URL
275
   */
276
  public ClassLoader getClassLoader(String codebase)
277
    throws MalformedURLException
278
  {
279
    if (codebase == null || codebase.length() == 0)
280
      return Thread.currentThread().getContextClassLoader();
281
 
282
    ClassLoader loader;
283
    CacheKey loaderKey = new CacheKey
284
    (codebase, Thread.currentThread().getContextClassLoader());
285
    loader = (ClassLoader) cacheLoaders.get (loaderKey);
286
 
287
    if (loader == null)
288
      {
289
        //create an entry in cacheLoaders mapping a loader to codebases.
290
        // codebases are separated by " "
291
        StringTokenizer tok = new StringTokenizer (codebase, " ");
292
        ArrayList urls = new ArrayList();
293
 
294
        while (tok.hasMoreTokens())
295
          urls.add (new URL(tok.nextToken()));
296
 
297
        loader = new MyClassLoader((URL[]) urls.toArray(new URL [urls.size()]),
298
                                 Thread.currentThread().getContextClassLoader(),
299
                                 codebase);
300
        cacheLoaders.put (loaderKey, loader);
301
      }
302
 
303
    return loader;
304
  }
305
 
306
  /**
307
   * Returns a string representation of the network location where a remote
308
   * endpoint can get the class-definition of the given class.
309
   *
310
   * @param cl
311
   *
312
   * @return a space seperated list of URLs where the class-definition
313
   * of cl may be found
314
   */
315
  public String getClassAnnotation(Class cl)
316
  {
317
    ClassLoader loader = cl.getClassLoader();
318
 
319
    if (loader == null
320
        || loader == ClassLoader.getSystemClassLoader())
321
      {
322
        return System.getProperty ("java.rmi.server.codebase");
323
      }
324
 
325
    if (loader instanceof MyClassLoader)
326
      {
327
        return ((MyClassLoader) loader).getClassAnnotation();
328
      }
329
 
330
    String s = (String) cacheAnnotations.get (loader);
331
 
332
    if (s != null)
333
      return s;
334
 
335
    if (loader instanceof URLClassLoader)
336
      {
337
        URL[] urls = ((URLClassLoader) loader).getURLs();
338
 
339
        if (urls.length == 0)
340
          return null;
341
 
342
        CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
343
 
344
        for (int i = 0; i < urls.length; i++)
345
          {
346
            annotation.append (urls [i].toExternalForm());
347
            annotation.append (' ');
348
          }
349
 
350
        s = annotation.toString();
351
        cacheAnnotations.put (loader, s);
352
        return s;
353
      }
354
 
355
    return System.getProperty ("java.rmi.server.codebase");
356
  }
357
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.