blob: fd2726e2ffdb0b24a16d699f270e1c106eaf79b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jem.internal.proxy.ide;
/*
*/
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
import org.eclipse.jem.internal.proxy.common.IVMServer;
import org.eclipse.jem.internal.proxy.core.*;
/**
* This implementation runs the Beans inside the Eclipse IDE
* It should only be used by plugins that can guarantee their their beans do
* not change during the lifetime of the IDE and can run at the same JDK level
* that the Eclipse IDE is running
*/
public class IDEProxyFactoryRegistry extends BaseProxyFactoryRegistry implements IVMServer {
public static final String IDE_REGISTRY_TYPE_ID = "org.eclipse.jem.IDE"; //$NON-NLS-1$
protected String fName;
protected ClassLoader fClassLoader;
protected IDECallbackRegistry fCallbackRegistry;
/*
* Special classloader that firsts tries to load from bundle then tries from url paths so
* that bundle is treated as being at the head of the url paths.
*
* @since 1.0.0
*/
private static class IDESpecialClassLoader extends URLClassLoader {
private Bundle bundle;
// This is the bundle that contains the IDE Eclipse code.
// This must be checked first because there are IDE specific stuff that is used on the "remote vm" too and
// so must be common.
private Bundle ideBundle;
public IDESpecialClassLoader(URL[] urls, Bundle bundle) {
super(urls, null);
ideBundle = ProxyPlugin.getPlugin().getBundle();
this.bundle = bundle;
}
public IDESpecialClassLoader(URL[] urls) {
this(urls, null);
}
/* (non-Javadoc)
* @see java.lang.ClassLoader#findClass(java.lang.String)
*/
protected Class findClass(String name) throws ClassNotFoundException {
try {
return ideBundle.loadClass(name);
} catch (ClassNotFoundException e) {
if (bundle != null) {
try {
return bundle.loadClass(name);
} catch (ClassNotFoundException e1) {
}
}
return super.findClass(name);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.ClassLoader#findResource(java.lang.String)
*/
public URL findResource(String name) {
URL r = ideBundle.getResource(name);
if (r == null && bundle != null)
r = bundle.getResource(name);
return r != null ? r : super.findResource(name);
}
}
/**
* Create a special loader that has the plugin classloader of the passed in plugin
* as the parent loader, plus all of the urls, plus the remotevm.jar file that is
* needed by IDE Proxy to work.
*/
public static ClassLoader createSpecialLoader(String pluginName, URL[] otherURLs) {
Bundle bundle = pluginName != null ? Platform.getBundle(pluginName) : null;
URL[] mustHaveUrls = ProxyPlugin.getPlugin().urlLocalizeAllFromBundleAndFragments(ProxyPlugin.getPlugin().getBundle(), "vm/remotevm.jar"); //$NON-NLS-1$
URL[] urls = null;
if (otherURLs != null) {
urls = new URL[otherURLs.length+mustHaveUrls.length];
System.arraycopy(mustHaveUrls, 0, urls, 0, mustHaveUrls.length);
System.arraycopy(otherURLs, 0, urls, mustHaveUrls.length, otherURLs.length);
} else
urls = mustHaveUrls;
return bundle != null ? new IDESpecialClassLoader(urls, bundle) : new IDESpecialClassLoader(urls);
}
public IDEProxyFactoryRegistry(String aName, ClassLoader loader) {
super(IDE_REGISTRY_TYPE_ID);
fName = aName;
fClassLoader = loader;
}
ClassLoader getPluginClassLoader(){
return fClassLoader;
}
protected void registryTerminated(boolean wait){
List runnables = null;
synchronized (this) {
runnables = shutdownRunnables;
shutdownRunnables = null;
}
if (runnables != null) {
for (Iterator itr = runnables.iterator(); itr.hasNext();) {
try {
((Runnable) itr.next()).run();
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
Class loadClass(String aClassName) throws ClassNotFoundException, ExceptionInInitializerError, LinkageError {
return fClassLoader.loadClass(aClassName);
}
public ICallbackRegistry getCallbackRegistry(){
if ( fCallbackRegistry == null ){
fCallbackRegistry = new IDECallbackRegistry(this);
}
return fCallbackRegistry;
}
/**
* Get a bean proxy from the bean of the correct type.
*
* @param returnType
* @param bean
* @return
*
* @since 1.0.0
*/
IBeanProxy getBeanProxy(Class returnType, Object bean) {
IDEStandardBeanTypeProxyFactory proxyFactory = (IDEStandardBeanTypeProxyFactory) this.getBeanTypeProxyFactory();
if (!returnType.isPrimitive()) {
return IDEStandardBeanProxyFactory.createBeanProxy(this, bean);
} else if (returnType == Integer.TYPE) {
return proxyFactory.intType.newBeanProxy(bean);
} else if (returnType == Boolean.TYPE) {
return proxyFactory.booleanType.newBeanProxy(bean);
} else if (returnType == Float.TYPE) {
return proxyFactory.floatType.newBeanProxy(bean);
} else if (returnType == Long.TYPE) {
return proxyFactory.longType.newBeanProxy(bean);
} else if (returnType == Short.TYPE) {
return proxyFactory.shortType.newBeanProxy(bean);
} else if (returnType == Double.TYPE) {
return proxyFactory.doubleType.newBeanProxy(bean);
} else if (returnType == Byte.TYPE) {
return proxyFactory.byteType.newBeanProxy(bean);
} else if (returnType == Character.TYPE) {
return proxyFactory.charType.newBeanProxy(bean);
} else {
throw new RuntimeException("Unknown primitive type " + returnType.getName()); //$NON-NLS-1$
}
}
List shutdownRunnables;
public synchronized void addShutdownListener(Runnable runnable) {
if (shutdownRunnables == null) {
shutdownRunnables = new ArrayList();
} else if (shutdownRunnables.contains(runnable))
return;
shutdownRunnables.add(runnable);
}
public synchronized void removeShutdownListener(Runnable runnable) {
if (shutdownRunnables != null)
shutdownRunnables.remove(runnable);
}
}