001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.rmi;
018
019 import java.io.File;
020 import java.net.MalformedURLException;
021 import java.net.URL;
022 import java.rmi.server.RMIClassLoader;
023 import java.rmi.server.RMIClassLoaderSpi;
024 import java.util.StringTokenizer;
025
026
027 /**
028 * An implementation of {@link java.rmi.server.RMIClassLoaderSpi} which provides normilzation
029 * of codebase URLs and delegates to the default {@link RMIClassLoaderSpi}.
030 *
031 * @version $Rev: 209990 $ $Date: 2005-07-09 21:24:52 -0700 (Sat, 09 Jul 2005) $
032 */
033 public class RMIClassLoaderSpiImpl extends RMIClassLoaderSpi {
034
035 private static final RMIClassLoaderSpi delegate = RMIClassLoader.getDefaultProviderInstance();
036
037 public Class loadClass(String codebase, String name, ClassLoader defaultLoader)
038 throws MalformedURLException, ClassNotFoundException
039 {
040 if (codebase != null) {
041 codebase = normalizeCodebase(codebase);
042 }
043
044 return delegate.loadClass(codebase, name, defaultLoader);
045 }
046
047 public Class loadProxyClass(String codebase, String[] interfaces, ClassLoader defaultLoader)
048 throws MalformedURLException, ClassNotFoundException
049 {
050 if (codebase != null) {
051 codebase = normalizeCodebase(codebase);
052 }
053
054 return delegate.loadProxyClass(codebase, interfaces, defaultLoader);
055 }
056
057 public ClassLoader getClassLoader(String codebase) throws MalformedURLException {
058
059 if (codebase != null) {
060 codebase = normalizeCodebase(codebase);
061 }
062
063 return delegate.getClassLoader(codebase);
064 }
065
066 public String getClassAnnotation(Class type) {
067
068 Object obj = type.getClassLoader();
069 if (obj instanceof ClassLoaderServerAware) {
070 ClassLoaderServerAware classLoader = (ClassLoaderServerAware) obj;
071 URL urls[] = classLoader.getClassLoaderServerURLs();
072 if (null == urls) {
073 return delegate.getClassAnnotation(type);
074 }
075 StringBuffer codebase = new StringBuffer();
076 for (int i = 0; i < urls.length; i++) {
077 URL url = normalizeURL(urls[i]);
078 if (codebase.length() != 0) {
079 codebase.append(' ');
080 }
081 codebase.append(url);
082 }
083 return codebase.toString();
084 }
085
086 return delegate.getClassAnnotation(type);
087 }
088
089 static String normalizeCodebase(String input) throws MalformedURLException {
090
091 StringBuffer codebase = new StringBuffer();
092 StringBuffer working = new StringBuffer();
093 StringTokenizer stok = new StringTokenizer(input, " \t\n\r\f", true);
094
095 while (stok.hasMoreTokens()) {
096 String item = stok.nextToken();
097 try {
098 // If we got this far then item is a valid url, so commit the current
099 // buffer and start collecting any trailing bits from where we are now
100
101 updateCodebase(working, codebase);
102 }
103 catch (MalformedURLException ignore) {
104 // just keep going & append to the working buffer
105 }
106
107 working.append(item);
108 }
109
110 // Handle trailing elements
111 updateCodebase(working, codebase);
112
113 return codebase.toString();
114 }
115
116 private static void updateCodebase(final StringBuffer working, final StringBuffer codebase) throws MalformedURLException {
117
118 if (working.length() != 0) {
119 // Normalize the URL
120 URL url = normalizeURL(new URL(working.toString()));
121
122 // Put spaces back in for URL delims
123 if (codebase.length() != 0) {
124 codebase.append(" ");
125 }
126 codebase.append(url);
127
128 // Reset the working buffer
129 working.setLength(0);
130 }
131 }
132
133 static URL normalizeURL(URL url) {
134
135 if (url.getProtocol().equals("file")) {
136 String filename = url.getFile().replace('/', File.separatorChar);
137 File file = new File(filename);
138 try {
139 url = file.toURI().toURL();
140 }
141 catch (MalformedURLException ignore) {
142 }
143 }
144
145 return url;
146 }
147
148 public interface ClassLoaderServerAware {
149 public URL[] getClassLoaderServerURLs();
150 }
151 }
152