blob: 58b08e403e92ec091f832c03e2820fda4321e636 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute and Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* 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
* $Id$
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.test.builder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.objectteams.otdt.core.ext.OTREContainer;
import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
/**
* Utility class for launching a program in a controlled environment.
* Disposing the application's object and the OTLaunchEnvironment
* should enable the JVM to also dispose all classes loaded in the process.
*
* @author stephan
* @version $Id: OTLaunchEnvironment.java 14220 2006-09-04 22:13:40Z stephan $
*/
public class OTLaunchEnvironment extends URLClassLoader
{
ObjectTeamsTransformer transformer = null;
/** Where to look for class files. */
IPath bindir;
/**
* Setup a launch environment for the given paths.
* @param workspaceRoot path to the workspace root
* @param bindir absolute workspace path to the output location holding class files.
* @throws MalformedURLException if the OTRE_JAR_PATH is not a valid path.
*/
OTLaunchEnvironment(IPath workspaceRoot, IPath bindir) throws MalformedURLException {
super(new URL[]{getOTREURL()});
this.bindir = workspaceRoot.append(bindir);
}
/**
* Same as above but supports the use of OTRE transformers, if `useTransformer == true'
*/
OTLaunchEnvironment(IPath workspaceRoot, IPath bindir, boolean useTransformer)
throws MalformedURLException
{
this(workspaceRoot, bindir);
if (useTransformer)
this.transformer = new ObjectTeamsTransformer();
}
static URL getOTREURL() throws MalformedURLException {
IClasspathEntry[] entries = new OTREContainer().getClasspathEntries();
String url = "file:"+entries[0].getPath(); //$NON-NLS-1$
if (!url.endsWith(".jar")) //$NON-NLS-1$
url += '/';
return new URL(url);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String fileName = name.replace('.', File.separatorChar)+".class"; //$NON-NLS-1$
File file = new File(bindir.append(fileName).toOSString());
if (file.exists()) {
try {
return defineClassFromFile(name, file);
} catch (Exception e) {
// we have a file but it was invalid, don't continue
throw new ClassNotFoundException(name);
}
}
// this will use the URL pointing to the OTRE:
return super.findClass(name);
}
@Override
public InputStream getResourceAsStream(String name) {
File file = new File(bindir.append(name).toOSString());
if (file.exists())
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return super.getResourceAsStream(name);
}
/* We found an existing file, load its bytes and define the class. */
private Class<?> defineClassFromFile(String name, File file)
throws Exception
{
try (FileInputStream fis = new FileInputStream(file)) {
byte[] bytes = new byte[(int) file.length()];
fis.read(bytes);
if (transformer != null)
bytes = transformer.transform(this, name, null, null, bytes);
return defineClass(name, bytes, 0, bytes.length);
}
}
/**
* Load class `className' and invoke its method `methodName'.
* The method must be static and without arguments.
*
* @param className
* @param methodName
* @return the methods return (possibly boxed).
*
* @throws Exception too many to list explicitly ;-)
*/
public Object launch(String className, String methodName)
throws Exception
{
Class<?> clazz = this.loadClass(className);
Method method = clazz.getMethod(methodName, new Class[0]);
return method.invoke(null, new Object[0]);
}
}