Index: E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseConsoleConfiguration.java =================================================================== --- E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseConsoleConfiguration.java (revision 5434) +++ E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseConsoleConfiguration.java (working copy) @@ -21,8 +21,10 @@ */ package org.hibernate.eclipse.console; +import org.eclipse.jdt.core.IJavaProject; import org.hibernate.console.ConsoleConfiguration; import org.hibernate.console.preferences.ConsoleConfigurationPreferences; +import org.hibernate.eclipse.console.utils.ProjectUtils; /** * @author max @@ -34,8 +36,21 @@ super(config); } - protected ClassLoader getParentClassLoader() { + public EclipseConsoleConfiguration(ConsoleConfiguration o) { + this(o.prefs); + } + + protected ClassLoader getParentClassLoader() { return HibernateConsolePlugin.getDefault().getClass().getClassLoader(); } + + protected ClassLoader getContextLoader() { + IJavaProject project = ProjectUtils.findJavaProject(this); + if (project != null) { + return new HibernateToolsContextLoader(HibernateConsolePlugin + .getDefault().getClass().getClassLoader(), project); + } + return super.getContextLoader(); + } } Index: E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseLaunchConsoleConfigurationPreferences.java =================================================================== --- E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseLaunchConsoleConfigurationPreferences.java (revision 5434) +++ E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/EclipseLaunchConsoleConfigurationPreferences.java (working copy) @@ -161,6 +161,11 @@ } + public ILaunchConfiguration getLaunchConfiguration() { + return launchConfiguration; + } + + Index: E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateConsolePlugin.java =================================================================== --- E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateConsolePlugin.java (revision 5434) +++ E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateConsolePlugin.java (working copy) @@ -28,8 +28,11 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdapterManager; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; @@ -45,6 +48,8 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; @@ -72,6 +77,8 @@ */ public class HibernateConsolePlugin extends AbstractUIPlugin implements PluginLogger { + public static final String JBOSSS_TMP_UNPACK = "jboss_tmp_unpack"; + public static final String ID = "org.hibernate.eclipse.console"; static public final String LAST_USED_CONFIGURATION_PREFERENCE = "lastusedconfig"; @@ -115,7 +122,18 @@ loadExistingConfigurations(); listenForConfigurations(); - + // + PlatformUI.getWorkbench().addWorkbenchListener(new IWorkbenchListener() { + + public void postShutdown(IWorkbench workbench) { + deleteDirectory(getUnpackDirectory()); + } + + public boolean preShutdown(IWorkbench workbench, boolean forced) { + return true; + } + + }); } private void listenForConfigurations() { @@ -208,7 +226,7 @@ KnownConfigurations instance = KnownConfigurations.getInstance(); ConsoleConfigurationPreferences adapter = buildConfigurationPreferences(configuration); - instance.addConfiguration(new ConsoleConfiguration(adapter), true); + instance.addConfiguration(new EclipseConsoleConfiguration(adapter), true); } } @@ -233,7 +251,7 @@ ILaunchConfiguration[] launchConfigurations = launchManager.getLaunchConfigurations( lct ); for (int i = 0; i < launchConfigurations.length; i++) { KnownConfigurations.getInstance().addConfiguration( - new ConsoleConfiguration(new EclipseLaunchConsoleConfigurationPreferences(launchConfigurations[i])), false ); + new EclipseConsoleConfiguration(new EclipseLaunchConsoleConfigurationPreferences(launchConfigurations[i])), false ); } } @@ -634,6 +652,34 @@ logMessage(IStatus.WARNING, he==null?null:he.getMessage(), he); } - + public static File getUnpackDirectory() { + File rootFile = getRootFile(); + File baseUnpackDir = new File(rootFile, JBOSSS_TMP_UNPACK); + return baseUnpackDir; + } + + public static File getRootFile() { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IPath rootPath = workspaceRoot.getLocation(); + File rootFile = rootPath.toFile(); + if (!rootFile.exists()) { + throw new RuntimeException("Can't determine workspace"); //$NON-NLS-1$ + } + return rootFile; + + } + public static boolean deleteDirectory(File path) { + if (path.exists()) { + File[] files = path.listFiles(); + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) { + deleteDirectory(files[i]); + } else { + files[i].delete(); + } + } + } + return (path.delete()); + } } Index: E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateToolsContextLoader.java =================================================================== --- E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateToolsContextLoader.java (revision 0) +++ E:/workspace-3.3.1.1/plugins/org.hibernate.eclipse.console/src/org/hibernate/eclipse/console/HibernateToolsContextLoader.java (revision 0) @@ -0,0 +1,500 @@ +/******************************************************************************* + * Copyright (c) 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.hibernate.eclipse.console; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.IClassFile; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.osgi.framework.adaptor.BundleClassLoader; + +public class HibernateToolsContextLoader extends ClassLoader implements + PrivilegedAction { + + private ClassLoader sourceLoader; + private List URLs = new ArrayList(); + + private static final class Finder extends SecurityManager { + public Class[] getClassContext() { + return super.getClassContext(); + } + } + + private ClassLoader projectClassLoader; + private IJavaProject jProject; + private List jars; + private List dependentProjects = new ArrayList(); + private Map found = new HashMap(); + private List notFound = new ArrayList(); + static ClassLoader finderClassLoader; + static Finder contextFinder; + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + finderClassLoader = HibernateToolsContextLoader.class + .getClassLoader(); + contextFinder = new Finder(); + return null; + } + }); + } + + public HibernateToolsContextLoader(ClassLoader contextClassLoader, + ClassLoader projectClassLoader) { + super(contextClassLoader); + this.projectClassLoader = projectClassLoader; + } + + public HibernateToolsContextLoader(ClassLoader contextClassLoader, + IJavaProject jProject) { + super(contextClassLoader); + this.jProject = jProject; + this.jars = getJarPaths(jProject); + if (URLs.size() > 0) { + URL[] urls = (URL[]) URLs.toArray(new URL[0]); + sourceLoader = new URLClassLoader(urls,contextClassLoader); + } + } + + public HibernateToolsContextLoader(ClassLoader contextClassLoader) { + super(contextClassLoader); + } + + // Return a list of all classloaders on the stack that are neither the + // ContextFinder classloader nor the boot classloader. The last classloader + // in the list is either a bundle classloader or the framework's classloader + // We assume that the bootclassloader never uses the context classloader to + // find classes in itself. + ArrayList basicFindClassLoaders() { + Class[] stack = contextFinder.getClassContext(); + ArrayList result = new ArrayList(1); + for (int i = 1; i < stack.length; i++) { + ClassLoader tmp = stack[i].getClassLoader(); + if (stack[i] != HibernateToolsContextLoader.class && tmp != null + && tmp != this) { + if (checkClassLoader(tmp)) + result.add(tmp); + // stop at the framework classloader or the first bundle + // classloader + if (tmp == finderClassLoader + || tmp instanceof BundleClassLoader) + break; + } + } + if (projectClassLoader != null) + result.add(projectClassLoader); + return result; + } + + // ensures that a classloader does not have the ContextFinder as part of the + // parent hierachy. A classloader which has the ContextFinder as a parent + // must + // not be used as a delegate, otherwise we endup in endless recursion. + private boolean checkClassLoader(ClassLoader classloader) { + if (classloader == null || classloader == getParent()) + return false; + for (ClassLoader parent = classloader.getParent(); parent != null; parent = parent + .getParent()) + if (parent == this) + return false; + return true; + } + + private ArrayList findClassLoaders() { + if (System.getSecurityManager() == null) + return basicFindClassLoaders(); + return (ArrayList) AccessController.doPrivileged(this); + } + + public Object run() { + return basicFindClassLoaders(); + } + + protected synchronized Class loadClass(String clazz, boolean resolve) + throws ClassNotFoundException { + Class result = null; + try { + result = super.loadClass(clazz, resolve); + } catch (ClassNotFoundException e) { + // ignore + } + if (result == null) { + ArrayList toConsult = findClassLoaders(); + for (Iterator loaders = toConsult.iterator(); loaders.hasNext();) + try { + result = ((ClassLoader) loaders.next()).loadClass(clazz); + if (result != null) + break; + } catch (ClassNotFoundException e) { + // go to the next class loader + } + } + if (result == null && sourceLoader != null) { + try { + result = sourceLoader.loadClass(clazz); + } catch (ClassNotFoundException e) { + // ignore + } + } + if (result == null) { + try { + byte[] bytes = getBytes(clazz); + result = defineClass(clazz, bytes, 0, bytes.length); + if (resolve) { + resolveClass(result); + } + } catch (Exception e) { + // ignore + } + } + + if (result == null) + throw new ClassNotFoundException(clazz); + return result; + } + + private byte[] getBytes(String clazz) throws JavaModelException { + IType type = jProject.findType(clazz); + if (type == null) { + for (Iterator iter = dependentProjects.iterator(); iter + .hasNext();) { + IJavaProject project = (IJavaProject) iter.next(); + type = project.findType(clazz); + if (type != null) + break; + } + } + IClassFile classFile = type.getClassFile(); + byte[] bytes = classFile.getBytes(); + return bytes; + } + + protected URL findResource(String arg0) { + ArrayList toConsult = findClassLoaders(); + for (Iterator loaders = toConsult.iterator(); loaders.hasNext();) { + URL result = ((ClassLoader) loaders.next()).getResource(arg0); + if (result != null) + return result; + // go to the next class loader + } + URL result = sourceLoader.getResource(arg0); + if (result != null) + return result; + + result = findURL(arg0); + if (result != null) + return result; + return super.findResource(arg0); + } + + protected Enumeration findResources(String arg0) throws IOException { + ArrayList toConsult = findClassLoaders(); + Enumeration result; + for (Iterator loaders = toConsult.iterator(); loaders.hasNext();) { + result = ((ClassLoader) loaders.next()) + .getResources(arg0); + if (result != null && result.hasMoreElements()) + return result; + // go to the next class loader + } + result = sourceLoader.getResources(arg0); + if (result != null) + return result; + // FIXME find all resources + URL resultURL = findURL(arg0); + if (resultURL != null) { + return new ArrayEnumeration(resultURL); + } + return super.findResources(arg0); + } + + private URL findURL(String arg0) { + if (found.containsKey(arg0)) + return (URL) found.get(arg0); + if (notFound.contains(arg0)) + return null; + for (Iterator iter = jars.iterator(); iter.hasNext();) { + IPath path = (IPath) iter.next(); + File file = getRawLocationFile(path); + if (file.exists() && file.isDirectory()) { + File resource = new File(file, arg0); + if (resource.exists()) { + try { + URL url = file.toURI().toURL(); + found.put(arg0, url); + return url; + } catch (MalformedURLException e) { + // ignore + } + + } + } else if (file.exists()) { + try { + JarFile jarFile = new JarFile(file); + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry jarEntry = (JarEntry) entries.nextElement(); + if (jarEntry.getName().equals(arg0)) { + URL url = null; + if (isWindows()) + url = creatFileResource(jarEntry, jarFile, file); + else + url = new URL( + "jar:file:" + file.getAbsolutePath() + "!/" + arg0); + jarFile.close(); + found.put(arg0, url); + return url; + } + } + jarFile.close(); + } catch (Exception e) { + // ignore + } + } + } + notFound.add(arg0); + return null; + } + + private boolean isWindows() { + return Platform.getOS().equals(Platform.OS_WIN32); + } + + private URL creatFileResource(JarEntry jarEntry, JarFile jarFile, File file) + throws ClassNotFoundException { + File rootFile = HibernateConsolePlugin.getRootFile(); + File unpackDirectory = HibernateConsolePlugin.getUnpackDirectory(); + unpackDirectory = makeNewDirectory(rootFile, unpackDirectory); + File projectDirectory = new File(unpackDirectory, jProject + .getProject().getName()); + projectDirectory = makeNewDirectory(rootFile, projectDirectory); + File dest = null; + try { + dest = getDestination(projectDirectory, file); + } catch (IOException e) { + return null; + } + createFileResource(jarEntry, dest, jarFile, file); + URL url = null; + try { + if (isWindows()) + url = new URL( + "file:/" + dest.getAbsolutePath() + "/" + jarEntry.getName()); + else + url = new URL( + "file:" + dest.getAbsolutePath() + "/" + jarEntry.getName()); + } catch (MalformedURLException e) { + return null; + } + return url; + } + + private void createFileResource(JarEntry jarEntry, File dest, JarFile jarFile, + File file) throws ClassNotFoundException { + File dir = dest; + String separator = "/"; + String name = jarEntry.getName(); + while (name.indexOf(separator) > -1) { + String dirString = name.substring(0, name.indexOf(separator)); + File newDir = new File(dir, dirString); + newDir = makeNewDirectory(dir, newDir); + name = name.substring(name.indexOf(separator) + 1); + dir = newDir; + } + + InputStream input = null; + OutputStream output = null; + try { + input = jarFile.getInputStream(jarEntry); + File outputFile = new File(dir, name); + if (!outputFile.exists() + || outputFile.lastModified() < file.lastModified()) { + outputFile.delete(); + if (!outputFile.createNewFile()) + throw new ClassNotFoundException( + "Could not create the " + file.getName() + " file"); + output = new FileOutputStream(outputFile); + int c; + while (((c = input.read()) != -1)) + output.write(c); + } + } catch (Exception e) { + HibernateConsolePlugin.getDefault().logErrorMessage("Error", e); + } finally { + if (input != null) + try { + input.close(); + } catch (IOException e) { + } + if (output != null) + try { + output.close(); + } catch (IOException e) { + } + } + } + + private File getDestination(File baseUnpackDir, File file) + throws IOException { + File dest = new File(baseUnpackDir, getOutputFile(file.getName())); + if (dest.exists() || file.lastModified() < dest.lastModified()) + return dest; + HibernateConsolePlugin.deleteDirectory(dest); + dest.mkdirs(); + return dest; + } + + private String getOutputFile(String name) { + if (name == null) + return null; + if (name.endsWith(".jar")) + name = name.substring(0, name.length() - 4); + String out = name.replace('.', '_'); + + return out; + } + + private File makeNewDirectory(File rootFile, File dir) { + + if (!dir.isDirectory()) { + dir.delete(); + } + if (!dir.exists()) + dir.mkdirs(); + return dir; + } + + private File getRawLocationFile(IPath simplePath) { + IResource resource = ResourcesPlugin.getWorkspace().getRoot() + .findMember(simplePath); + File file = null; + if (resource != null) { + file = ResourcesPlugin.getWorkspace().getRoot().findMember( + simplePath).getLocation().toFile(); + } else { + file = simplePath.toFile(); + } + return file; + } + + private List getJarPaths(IJavaProject jProject) { + ArrayList classPaths = new ArrayList(); + try { + IClasspathEntry[] rawClassPaths = jProject.getRawClasspath(); + + for (int i = 0; i < rawClassPaths.length; i++) { + IClasspathEntry rawClassPath = rawClassPaths[i]; + if (rawClassPath.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + IPath path = rawClassPath.getOutputLocation(); + if (path == null) { + path = jProject.getOutputLocation(); + } + File file = getRawLocationFile(path); + URLs.add(file.toURI().toURL()); + } + if (rawClassPath.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { + IClasspathEntry resLib = JavaCore + .getResolvedClasspathEntry(rawClassPath); + addClassPath(classPaths, resLib); + } + if (rawClassPath.getEntryKind() == IClasspathEntry.CPE_PROJECT) { + IClasspathEntry entry = JavaCore + .getResolvedClasspathEntry(rawClassPath); + IPath path = entry.getPath(); + String name = path.segment(0); + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(name); + if (project.exists()) { + IJavaProject javaProject = JavaCore.create(project); + if (javaProject.exists()) { + dependentProjects.add(javaProject); + classPaths.addAll(getJarPaths(javaProject)); + } + } + } + if (rawClassPath.getEntryKind() == IClasspathEntry.CPE_VARIABLE) { + IClasspathEntry resLib = JavaCore + .getResolvedClasspathEntry(rawClassPath); + addClassPath(classPaths, resLib); + } + if (rawClassPath.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { + if (!rawClassPath.getPath().toString().endsWith( + "JRE_CONTAINER")) { + IClasspathEntry[] resLibs = JavaCore + .getClasspathContainer(rawClassPath.getPath(), + jProject).getClasspathEntries(); + for (int j = 0; j < resLibs.length; j++) { + addClassPath(classPaths, resLibs[j]); + } + } + } + } + + } catch (Exception e) { + HibernateConsolePlugin.getDefault().log( + "Problem with the classpath"); + } + return classPaths; + } + + private void addClassPath(ArrayList classPaths, IClasspathEntry resLibs) { + IPath path = resLibs.getPath(); + String ls = path.lastSegment(); + if (ls != null && ls.length() > 0) { + classPaths.add(path); + } + } + + class ArrayEnumeration implements Enumeration { + private Object[] array; + int cur = 0; + + public ArrayEnumeration(Object object) { + this.array = new Object[1]; + System.arraycopy(array, 0, this.array, 0, this.array.length); + } + + public boolean hasMoreElements() { + return cur < array.length; + } + + public Object nextElement() { + return array[cur++]; + } + } + +}