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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [rmi/] [server/] [RMIClassLoaderImpl.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose
2
   Copyright (C) 2005 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 java.net.MalformedURLException;
42
import java.net.URL;
43
import java.net.URLClassLoader;
44
import java.rmi.server.RMIClassLoaderSpi;
45
import java.util.ArrayList;
46
import java.util.Hashtable;
47
import java.util.Map;
48
import java.util.StringTokenizer;
49
 
50
/**
51
 * The default implementation of {@link java.rmi.server.RMIClassLoaderSpi}.
52
 *
53
 * @author Roman Kennke (kennke@aicas.com)
54
 */
55
public class RMIClassLoaderImpl extends RMIClassLoaderSpi
56
{
57
  private static class MyClassLoader extends URLClassLoader
58
  {
59
    // Package-private to avoid a trampoline constructor.
60
    MyClassLoader (URL[] urls, ClassLoader parent, String annotation)
61
    {
62
      super (urls, parent);
63
      this.annotation = annotation;
64
    }
65
 
66
    private MyClassLoader (URL[] urls, ClassLoader parent)
67
    {
68
      super (urls, parent);
69
      this.annotation = urlToAnnotation (urls);
70
    }
71
 
72
    public static String urlToAnnotation (URL[] urls)
73
    {
74
      if (urls.length == 0)
75
        return null;
76
 
77
      StringBuffer annotation = new StringBuffer (64 * urls.length);
78
 
79
      for (int i = 0; i < urls.length; i++)
80
      {
81
        annotation.append (urls [i].toExternalForm());
82
        annotation.append (' ');
83
      }
84
 
85
      return annotation.toString();
86
    }
87
 
88
    public final String getClassAnnotation()
89
    {
90
      return annotation;
91
    }
92
 
93
    private final String annotation;
94
  }
95
 
96
  /**
97
   * This class is used to identify a cached classloader by its codebase and
98
   * the context classloader that is its parent.
99
   */
100
  private static class CacheKey
101
  {
102
     private String mCodeBase;
103
     private ClassLoader mContextClassLoader;
104
 
105
     public CacheKey (String theCodebase, ClassLoader theContextClassLoader)
106
     {
107
       mCodeBase = theCodebase;
108
       mContextClassLoader = theContextClassLoader;
109
     }
110
 
111
    /**
112
     * @return true if the codebase and the context classloader are equal
113
     */
114
    public boolean equals (Object theOther)
115
    {
116
      if (theOther instanceof CacheKey)
117
      {
118
        CacheKey key = (CacheKey) theOther;
119
 
120
        return (equals (this.mCodeBase,key.mCodeBase)
121
                && equals (this.mContextClassLoader, key.mContextClassLoader));
122
        }
123
      return false;
124
    }
125
 
126
    /**
127
     * Test if the two objects are equal or both null.
128
     * @param theOne
129
     * @param theOther
130
     * @return
131
     */
132
    private boolean equals (Object theOne, Object theOther)
133
    {
134
      return theOne != null ? theOne.equals (theOther) : theOther == null;
135
    }
136
 
137
    /**
138
     * @return hashCode
139
     */
140
    public int hashCode()
141
    {
142
      return ((mCodeBase != null           ? mCodeBase.hashCode()           :  0)
143
              ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1));
144
    }
145
 
146
    public String toString()
147
    {
148
      return "[" + mCodeBase + "," + mContextClassLoader + "]";
149
    }
150
 
151
  }
152
 
153
  private static RMIClassLoaderImpl instance = null;
154
 
155
  private static Map cacheLoaders; //map annotations to loaders
156
  private static Map cacheAnnotations; //map loaders to annotations
157
  //class loader for defaultAnnotation
158
  private static MyClassLoader defaultClassLoader;
159
 
160
  //defaultAnnotation is got from system property
161
  // "java.rmi.server.defaultAnnotation"
162
  private static String defaultAnnotation;
163
 
164
  //URL object for defaultAnnotation
165
  private static URL defaultCodebase;
166
 
167
  static
168
  {
169
    // 89 is a nice prime number for Hashtable initial capacity
170
    cacheLoaders = new Hashtable (89);
171
    cacheAnnotations = new Hashtable (89);
172
 
173
    defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation");
174
 
175
    try
176
      {
177
        if (defaultAnnotation != null)
178
          defaultCodebase = new URL (defaultAnnotation);
179
      }
180
    catch (Exception _)
181
      {
182
        defaultCodebase = null;
183
      }
184
 
185
    if (defaultCodebase != null)
186
      {
187
        defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null,
188
                                               defaultAnnotation);
189
        cacheLoaders.put (new CacheKey (defaultAnnotation,
190
                                        Thread.currentThread().getContextClassLoader()),
191
                                        defaultClassLoader);
192
      }
193
    }
194
 
195
  /**
196
   * This is a singleton class and may only be instantiated once from within
197
   * the {@link #getInstance} method.
198
   */
199
  private RMIClassLoaderImpl()
200
  {
201
  }
202
 
203
  /**
204
   * Returns an instance of RMIClassLoaderImpl.
205
   *
206
   * @return an instance of RMIClassLoaderImpl
207
   */
208
  public static RMIClassLoaderSpi getInstance()
209
  {
210
    if (instance == null)
211
      instance = new RMIClassLoaderImpl();
212
    return instance;
213
  }
214
 
215
  public Class loadClass(String codeBase, String name,
216
                         ClassLoader defaultLoader)
217
    throws MalformedURLException, ClassNotFoundException
218
  {
219
    ClassLoader loader;
220
    if (defaultLoader == null)
221
      loader = Thread.currentThread().getContextClassLoader();
222
    else
223
      loader = defaultLoader;
224
 
225
    //try context class loader first
226
    try
227
      {
228
        return Class.forName(name, false, loader);
229
      }
230
    catch (ClassNotFoundException e)
231
      {
232
        // class not found in the local classpath
233
      }
234
 
235
    if (codeBase.length() == 0) //==""
236
      {
237
        loader = defaultClassLoader;
238
      }
239
    else
240
      {
241
        loader = getClassLoader(codeBase);
242
      }
243
 
244
    if (loader == null)
245
      {
246
        //do not throw NullPointerException
247
        throw new ClassNotFoundException ("Could not find class (" + name +
248
                                          ") at codebase (" + codeBase + ")");
249
      }
250
 
251
    return Class.forName(name, false, loader);
252
  }
253
 
254
  public Class loadProxyClass(String codeBase, String[] interfaces,
255
                              ClassLoader defaultLoader)
256
      throws MalformedURLException, ClassNotFoundException
257
  {
258
    // FIXME: Implement this.
259
    return null;
260
  }
261
 
262
  /**
263
   * Gets a classloader for the given codebase and with the current
264
   * context classloader as parent.
265
   *
266
   * @param codebase
267
   *
268
   * @return a classloader for the given codebase
269
   *
270
   * @throws MalformedURLException if the codebase contains a malformed URL
271
   */
272
  public ClassLoader getClassLoader(String codebase)
273
    throws MalformedURLException
274
  {
275
    ClassLoader loader;
276
    CacheKey loaderKey = new CacheKey
277
    (codebase, Thread.currentThread().getContextClassLoader());
278
    loader = (ClassLoader) cacheLoaders.get (loaderKey);
279
 
280
    if (loader == null)
281
      {
282
        //create an entry in cacheLoaders mapping a loader to codebases.
283
        // codebases are separated by " "
284
        StringTokenizer tok = new StringTokenizer (codebase, " ");
285
        ArrayList urls = new ArrayList();
286
 
287
        while (tok.hasMoreTokens())
288
          urls.add (new URL(tok.nextToken()));
289
 
290
        loader = new MyClassLoader((URL[]) urls.toArray(new URL [urls.size()]),
291
                                 Thread.currentThread().getContextClassLoader(),
292
                                 codebase);
293
        cacheLoaders.put (loaderKey, loader);
294
      }
295
 
296
    return loader;
297
  }
298
 
299
  /**
300
   * Returns a string representation of the network location where a remote
301
   * endpoint can get the class-definition of the given class.
302
   *
303
   * @param cl
304
   *
305
   * @return a space seperated list of URLs where the class-definition
306
   * of cl may be found
307
   */
308
  public String getClassAnnotation(Class cl)
309
  {
310
    ClassLoader loader = cl.getClassLoader();
311
 
312
    if (loader == null
313
        || loader == ClassLoader.getSystemClassLoader())
314
      {
315
        return System.getProperty ("java.rmi.server.codebase");
316
      }
317
 
318
    if (loader instanceof MyClassLoader)
319
      {
320
        return ((MyClassLoader) loader).getClassAnnotation();
321
      }
322
 
323
    String s = (String) cacheAnnotations.get (loader);
324
 
325
    if (s != null)
326
      return s;
327
 
328
    if (loader instanceof URLClassLoader)
329
      {
330
        URL[] urls = ((URLClassLoader) loader).getURLs();
331
 
332
        if (urls.length == 0)
333
          return null;
334
 
335
        StringBuffer annotation = new StringBuffer (64 * urls.length);
336
 
337
        for (int i = 0; i < urls.length; i++)
338
          {
339
            annotation.append (urls [i].toExternalForm());
340
            annotation.append (' ');
341
          }
342
 
343
        s = annotation.toString();
344
        cacheAnnotations.put (loader, s);
345
        return s;
346
      }
347
 
348
    return System.getProperty ("java.rmi.server.codebase");
349
  }
350
}

powered by: WebSVN 2.1.0

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