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