/*
* (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id$
*/
package org.nuxeo.runtime.remoting;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Hashtable;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.runtime.model.ComponentName;
/**
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*/
public class RemoteClassLoader extends ClassLoader {
private static final Log log = LogFactory.getLog(RemoteClassLoader.class);
private final ComponentName component;
private final ServerDescriptor sd;
private final Map<String, Class> loadedClasses = new Hashtable<String, Class>();
private final Map<String, URI> loadedResources = new Hashtable<String, URI>();
public RemoteClassLoader(ServerDescriptor sd, ComponentName component,
ClassLoader parent) {
super(parent != null ? parent
: Thread.currentThread().getContextClassLoader());
this.component = component;
this.sd = sd;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class klass = loadedClasses.get(name);
if (klass != null) {
return klass;
}
log.info("Loading class " + name + " from remote");
try {
byte[] bytes = sd.getServer().getClass(component, name);
if (bytes != null) {
klass = defineClass(name, bytes, 0, bytes.length, null);
loadedClasses.put(name, klass);
return klass;
}
} catch (Exception e) {
log.error("findClass failed", e);
throw new ClassNotFoundException("Failed to find remote class", e);
}
return klass;
}
@Override
protected URL findResource(String name) {
URL resource;
try {
resource = loadedResources.get(name).toURL();
} catch (MalformedURLException e) {
resource = null;
}
if (resource != null) {
return resource;
}
log.info("Loading resource " + name + " from remote");
try {
byte[] bytes = sd.getServer().getClass(component, name);
if (bytes != null) {
File file = createTempFile(name);
resource = file.toURI().toURL();
if (resource != null) {
loadedResources.put(name, resource.toURI());
return resource;
}
}
} catch (Exception e) {
log.error("Failed to create temp file for storing remote resource",
e);
}
return resource;
}
protected static File createTempFile(String name) throws IOException {
File file = File.createTempFile("nxruntime-remote-" + name, ".tmp");
file.deleteOnExit();
return file;
}
}