package org.objectstyle.wolips.eomodeler.core.model; import java.io.File; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.internal.runtime.InternalPlatform; import org.osgi.framework.Bundle; public abstract class AbstractEOClassLoader implements IEOClassLoaderFactory { private static Map<String, Reference<ClassLoader>> CLASSLOADER_CACHE; static { AbstractEOClassLoader.CLASSLOADER_CACHE = new HashMap<String, Reference<ClassLoader>>(); } public ClassLoader createClassLoaderForModel(EOModel model) throws EOModelException { try { // System.out.println("AbstractEOClassLoader.createClassLoaderForModel: " // + model.getName() + " ..."); Set<URL> classpathSet = new LinkedHashSet<URL>(); fillInModelClasspath(model, classpathSet); fillInDevelopmentClasspath(classpathSet); Bundle bundle = InternalPlatform.getDefault().getBundle("org.objectstyle.wolips.eomodeler.core"); URL wosqlJarUrl = bundle.getEntry("/lib/EOFSQLUtils.jar"); if (wosqlJarUrl != null) { classpathSet.add(wosqlJarUrl); } URL wo53sqlJarUrl = bundle.getEntry("/lib/EOFSQLUtils53.jar"); if (wo53sqlJarUrl != null) { classpathSet.add(wo53sqlJarUrl); } URL wo56sqlJarUrl = bundle.getEntry("/lib/EOFSQLUtils56.jar"); if (wo56sqlJarUrl != null) { classpathSet.add(wo56sqlJarUrl); } StringBuffer webobjectsClasspath = new StringBuffer(); Iterator<URL> classpathIter = classpathSet.iterator(); while (classpathIter.hasNext()) { URL classpathUrl = classpathIter.next(); webobjectsClasspath.append(File.pathSeparator); webobjectsClasspath.append(classpathUrl.getPath()); } System.setProperty("com.webobjects.classpath", webobjectsClasspath.toString()); System.setProperty("NSProjectBundleEnabled", "true"); ClassLoader eomodelClassLoader = createEOModelClassLoader(model, classpathSet); return eomodelClassLoader; } catch (Exception e) { throw new EOModelException("Failed to create EOF class loader.", e); } } protected synchronized ClassLoader createEOModelClassLoader(EOModel model, Set<URL> classpathUrlSet) { URLClassLoader classLoader = null; String cacheKey = getCacheKey(model, classpathUrlSet); Reference classLoaderReference = AbstractEOClassLoader.CLASSLOADER_CACHE.get(cacheKey); if (classLoaderReference != null) { classLoader = (URLClassLoader) classLoaderReference.get(); if (classLoader != null) { LinkedHashSet<URL> previousURLSet = new LinkedHashSet<URL>(); for (URL previousURL : classLoader.getURLs()) { previousURLSet.add(previousURL); } if (!previousURLSet.equals(classpathUrlSet)) { classLoader = null; } } } if (classLoader == null) { if (classpathUrlSet.size() == 1) { classLoader = null; } else { URL[] classpathUrls = classpathUrlSet.toArray(new URL[classpathUrlSet.size()]); classLoader = URLClassLoader.newInstance(classpathUrls); AbstractEOClassLoader.CLASSLOADER_CACHE.put(cacheKey, new SoftReference<ClassLoader>(classLoader)); } } return classLoader; } protected String getCacheKey(EOModel model, Set<URL> classpathUrlSet) { return model.getName() + "_" + String.valueOf(classpathUrlSet.hashCode()); } protected abstract void fillInModelClasspath(EOModel model, Set<URL> classpathUrls) throws Exception; protected abstract void fillInDevelopmentClasspath(Set<URL> classpathUrls) throws Exception; }