KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > system > rmi > RMIClassLoaderSpiImpl


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.system.rmi;
19
20 import java.net.MalformedURLException JavaDoc;
21 import java.net.URL JavaDoc;
22
23 import java.io.File JavaDoc;
24
25 import java.util.StringTokenizer JavaDoc;
26
27 import java.rmi.server.RMIClassLoader JavaDoc;
28 import java.rmi.server.RMIClassLoaderSpi JavaDoc;
29
30 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
31
32 /**
33  * An implementation of {@link RMIClassLoaderSpi} which provides normilzation
34  * of codebase URLs and delegates to the default {@link RMIClassLoaderSpi}.
35  *
36  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
37  */

38 public class RMIClassLoaderSpiImpl
39     extends RMIClassLoaderSpi JavaDoc
40 {
41     private RMIClassLoaderSpi JavaDoc delegate = RMIClassLoader.getDefaultProviderInstance();
42
43     //TODO: Not sure of the best initial size. Starting with 100 which should be reasonable.
44
private ConcurrentHashMap cachedCodebases = new ConcurrentHashMap(100, 0.75F);
45
46
47     public Class JavaDoc loadClass(String JavaDoc codebase, String JavaDoc name, ClassLoader JavaDoc defaultLoader)
48         throws MalformedURLException JavaDoc, ClassNotFoundException JavaDoc
49     {
50         if (codebase != null) {
51             codebase = getNormalizedCodebase(codebase);
52         }
53         
54         return delegate.loadClass(codebase, name, defaultLoader);
55     }
56     
57     public Class JavaDoc loadProxyClass(String JavaDoc codebase, String JavaDoc[] interfaces, ClassLoader JavaDoc defaultLoader)
58         throws MalformedURLException JavaDoc, ClassNotFoundException JavaDoc
59     {
60         if (codebase != null) {
61             codebase = getNormalizedCodebase(codebase);
62         }
63         
64         return delegate.loadProxyClass(codebase, interfaces, defaultLoader);
65     }
66     
67     public ClassLoader JavaDoc getClassLoader(String JavaDoc codebase)
68         throws MalformedURLException JavaDoc
69     {
70         if (codebase != null) {
71             codebase = getNormalizedCodebase(codebase);
72         }
73         
74         return delegate.getClassLoader(codebase);
75     }
76     
77     public String JavaDoc getClassAnnotation(Class JavaDoc type) {
78         Object JavaDoc obj = type.getClassLoader();
79         if (obj instanceof ClassLoaderServerAware) {
80             ClassLoaderServerAware classLoader = (ClassLoaderServerAware) obj;
81             URL JavaDoc urls[] = classLoader.getClassLoaderServerURLs();
82             if (null == urls) {
83                 return delegate.getClassAnnotation(type);
84             }
85             StringBuffer JavaDoc codebase = new StringBuffer JavaDoc();
86             for (int i = 0; i < urls.length; i++) {
87                 URL JavaDoc url = normalizeURL(urls[i]);
88                 if (codebase.length() != 0) {
89                     codebase.append(' ');
90                 }
91                 codebase.append(url);
92             }
93             return codebase.toString();
94         }
95         
96         return delegate.getClassAnnotation(type);
97     }
98
99     /**
100      * Uses a ConcurrentReaderHashmap to save the contents of previous parses.
101      *
102      * @param codebase
103      * @return
104      * @throws MalformedURLException
105      */

106     private String JavaDoc getNormalizedCodebase(String JavaDoc codebase)
107             throws MalformedURLException JavaDoc {
108         String JavaDoc cachedCodebase = (String JavaDoc)cachedCodebases.get(codebase);
109         if (cachedCodebase != null)
110             return cachedCodebase;
111
112         String JavaDoc normalizedCodebase = normalizeCodebase(codebase);
113         String JavaDoc oldValue = (String JavaDoc)cachedCodebases.put(codebase, normalizedCodebase);
114
115         // If there was a previous value remove the one we just added to make sure the
116
// cache doesn't grow.
117
if (oldValue != null) {
118             cachedCodebases.remove(codebase);
119         }
120         return normalizedCodebase; // We can use the oldValue
121
}
122
123
124     static String JavaDoc normalizeCodebase(String JavaDoc input)
125         throws MalformedURLException JavaDoc
126     {
127         assert input != null;
128
129         StringBuffer JavaDoc codebase = new StringBuffer JavaDoc();
130         StringBuffer JavaDoc working = new StringBuffer JavaDoc();
131         StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(input, " \t\n\r\f", true);
132         
133         while (stok.hasMoreTokens()) {
134             String JavaDoc item = stok.nextToken();
135             // Optimisation: This optimisation to prevent unnecessary MalformedURLExceptions
136
// being generated is most helpful on windows where directory names in the path
137
// often contain spaces. E.G:
138
// file:/C:/Program Files/Apache Software Foundation/Maven 1.0.2/lib/ant-1.5.3-1.jar
139
//
140
// Therefore we won't attempt URL("Files/Apache) or URL(" ") for the path delimiter.
141
if ( item.indexOf(':') != -1 )
142             {
143                 try {
144                     URL JavaDoc url = new URL JavaDoc(item);
145                     // If we got this far then item is a valid url, so commit the current
146
// buffer and start collecting any trailing bits from where we are now
147
updateCodebase(working, codebase);
148                 } catch (MalformedURLException JavaDoc ignore) {
149                     // just keep going & append to the working buffer
150
}
151             }
152             
153             // Append the URL or delimiter to the working buffer
154
working.append(item);
155         }
156         
157         // Handle trailing elements
158
updateCodebase(working, codebase);
159         
160         // System.out.println("Normalized codebase: " + codebase);
161
return codebase.toString();
162     }
163     
164     private static void updateCodebase(final StringBuffer JavaDoc working, final StringBuffer JavaDoc codebase)
165         throws MalformedURLException JavaDoc
166     {
167         if (working.length() != 0) {
168             // Normalize the URL
169
URL JavaDoc url = normalizeURL(new URL JavaDoc(working.toString()));
170             // System.out.println("Created normalized URL: " + url);
171

172             // Put spaces back in for URL delims
173
if (codebase.length() != 0) {
174                 codebase.append(" ");
175             }
176             codebase.append(url);
177             
178             // Reset the working buffer
179
working.setLength(0);
180         }
181     }
182     
183     static URL JavaDoc normalizeURL(URL JavaDoc url)
184     {
185         assert url != null;
186         
187         if (url.getProtocol().equals("file")) {
188             String JavaDoc filename = url.getFile().replace('/', File.separatorChar);
189             File JavaDoc file = new File JavaDoc(filename);
190             try {
191                 url = file.toURI().toURL();
192             }
193             catch (MalformedURLException JavaDoc ignore) {}
194         }
195         
196         return url;
197     }
198     
199     public interface ClassLoaderServerAware {
200         public URL JavaDoc[] getClassLoaderServerURLs();
201     }
202 }
203
Popular Tags