blob: d7e041b717cf52ab30de0e3a7afdcc184062da4d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2006 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.tests;
/*
* $RCSfile: JavaProjectUtil.java,v $
* $Revision: 1.16 $ $Date: 2007/04/01 03:28:18 $
*/
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import org.eclipse.ant.core.AntRunner;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.*;
import org.osgi.framework.Bundle;
import org.eclipse.jem.internal.proxy.core.ProxyPlugin;
/**
* The purpose of this class is to be a utility for manipulating/populating java projects.
* 1) Get a java project as one of the resources.
* 2) Create a project from a directory. The directory needs to be all set up to be a project already. Typically
* from an unzip.
*/
public class JavaProjectUtil {
public static IProject getProject(String projectName) throws CoreException {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
return (project.exists()) ? project: null;
}
/**
* Create a project from the path. The path will be a complete project, including a .project file.
*
* @param workspace
* @param projectPath Needs to be a complete path to a directory within the file system. The directory must be a complete project including .project file.
* @param pm
* @return The new IProject.
* @throws CoreException
*/
public static IProject createProject(IWorkspace workspace, IPath projectPath, final IProgressMonitor pm) throws CoreException {
IProjectDescription newDescription = null;
File projectFile = new File(projectPath.toFile(), IProjectDescription.DESCRIPTION_FILE_NAME);
if (!projectFile.exists())
throw new CoreException(new Status(IStatus.ERROR, JavaTestsPlugin.getPlugin().getBundle().getSymbolicName(), 0, "Project file not in project directory. Couldn't create project \""+projectPath.toString()+"\"", null));
IPath projectFilePath = new Path(projectFile.getPath());
newDescription = workspace.loadProjectDescription(projectFilePath);
// create the new project operation
final IProject project = workspace.getRoot().getProject(newDescription.getName());
final IProjectDescription description = newDescription;
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
project.create(description, new SubProgressMonitor(monitor, 1000));
project.open(new SubProgressMonitor(monitor, 1000));
}
}, project, 0, pm);
return project;
}
/**
* Create an empty project in the workspace root. If there is a .project file already there, then use it.
* @param workspace The workspace to create projec in.
* @param projectPath The name of the project. It should only be one segment long, and that will be the name of the project.
* @param pm
* @return The project.
* @throws CoreException
*
* @since 1.0.0
*/
public static IProject createEmptyJavaProject(IWorkspace workspace, IPath projectPath, final IProgressMonitor pm) throws CoreException {
projectPath = workspace.getRoot().getFullPath().append(projectPath); // Put it into the workspace relative.
File projectFile = new File(projectPath.toFile(), IProjectDescription.DESCRIPTION_FILE_NAME);
if (projectFile.exists())
return createProject(workspace, projectPath, pm); // Let it be created normally.
// create the new project operation
final IProject project = workspace.getRoot().getProject(projectPath.lastSegment());
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
project.create(new SubProgressMonitor(monitor, 1000));
project.open(new SubProgressMonitor(monitor, 1000));
IProjectDescription description = project.getDescription();
String[] natureids = description.getNatureIds();
for (int i = 0; i < natureids.length; i++) {
if (natureids[i].equals("org.eclipse.jdt.core.javanature"))
return; // Already has nature.
}
String[] newNatureids = new String[natureids.length+1];
newNatureids[0] = "org.eclipse.jdt.core.javanature";
System.arraycopy(natureids, 0, newNatureids, 1, natureids.length);
description.setNatureIds(newNatureids);
project.setDescription(description, new SubProgressMonitor(monitor, 1000));
// Need to put out a classfile too. We need a src and a bin directory for the classpath.
IFolder sf = project.getFolder("src");
sf.create(true, true, new SubProgressMonitor(monitor, 1000));
IFolder bf = project.getFolder("bin");
bf.create(true, true, new SubProgressMonitor(monitor, 1000));
IFile cp = project.getFile(".classpath");
try {
cp.create(getClass().getResource(".classpath").openStream(), true, new SubProgressMonitor(monitor, 1000));
} catch (IOException e) {
e.printStackTrace();
}
}
}, workspace.getRoot(), 0, pm);
return project;
}
/**
* Delete a project and all files from the project.
* @param project
* @throws CoreException
*/
public static void deleteProject(IProject project) throws CoreException {
if (project != null) {
project.delete(true, false, null); // Get rid of the project and the files themselves.
}
}
/**
* This sets the workspace autobuild to the specified state. It returns what
* the state was previously so that it can be later restored.
* @param autoBuild
* @return Previous autoBuild state.
* @throws CoreException
*/
public static boolean setAutoBuild(boolean autoBuild) throws CoreException {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
if (autoBuild != workspace.isAutoBuilding()) {
IWorkspaceDescription description = workspace.getDescription();
description.setAutoBuilding(true);
workspace.setDescription(description);
return !autoBuild; // It wasn't this state.
} else
return autoBuild; // It already is this state.
}
/**
* Import the given projects from the given zipfiles into the current workspace root.
* @param projectNames The array of project names to create
* @param zipFiles The zipfiles containing each project. It must be a complete project.
* The first directory in the zip must be the project directory.
* It must be the same name as from projectNames. Also it must include a .project file
* in that directory.
* @return The array of IProjects that were created.
* @throws CoreException
*/
public static IProject[] importProjects(final String[] projectNames, final String[] zipFiles) throws CoreException {
// Delete/create/populate within a runnable so that the build is done only after all changes have been made.
// Make sure autobuild is on.
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IProject[] result = new IProject[projectNames.length];
workspace.run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
// First import all, then after that, create the projects.
IPath rootLocation = workspace.getRoot().getLocation();
try {
String antFile = FileLocator.toFileURL(JavaTestsPlugin.getPlugin().getBundle().getEntry("testdata/unzip.xml")).getFile();
for (int i = 0; i < zipFiles.length; i++) {
// First create/recreate the project.
IProject p = getProject(projectNames[i]);
if (p != null)
p.delete(true, true, new SubProgressMonitor(monitor, 50)); // Get rid of it, we want a clean one for testing.
// Now import the requested files.
AntRunner ant = new AntRunner();
ant.setBuildFileLocation(antFile);
ant.setArguments(new String[] { "-Dzipfrom=" + zipFiles[i], "-Dzipto=" + rootLocation.toString()});
ant.run(new SubProgressMonitor(monitor, 50));
}
for (int i = 0; i < zipFiles.length; i++) {
result[i] = createProject(workspace, rootLocation.append(projectNames[i]), new SubProgressMonitor(monitor, 50));
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
}, workspace.getRoot(), 0, null);
return result;
}
static int cfSuffix = 0;
/**
* Add a path to plugin jar to the java project's class path.
* @param bundle The plugin where the jar is located.
* @param pathToJar Path to the jar within the above plugin
* @param project java project to add to.
*
* @since 1.0.0
*/
public static void addBundleJarToPath(Bundle bundle, String pathToJar, final IJavaProject project, IProgressMonitor pm) throws CoreException {
final IPath actualPath = new Path(ProxyPlugin.getPlugin().localizeFromBundleAndFragments(bundle, pathToJar));
if (actualPath.isEmpty())
return; // Didn't exist.
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
if (actualPath.toFile().isFile()) {
// It is a jar, this will be during runtime
// Create an external jar entry.
IClasspathEntry[] raw = project.getRawClasspath();
IClasspathEntry[] newRaw = new IClasspathEntry[raw.length+1];
newRaw[raw.length] = JavaCore.newLibraryEntry(actualPath, null, null);
System.arraycopy(raw, 0, newRaw, 0, raw.length);
project.setRawClasspath(newRaw, new SubProgressMonitor(monitor, 100));
} else {
// It is a path to class folder, this will be during development time.
// But classfolders MUST exist in the workspace. JDT doesn't understand them outside workspace,
// so we will link it into the project.
IFolder cf = project.getProject().getFolder("linkbin"+(++cfSuffix));
cf.createLink(actualPath, 0, new SubProgressMonitor(monitor, 100));
// Create class folder entry.
IClasspathEntry[] raw = project.getRawClasspath();
IClasspathEntry[] newRaw = new IClasspathEntry[raw.length+1];
newRaw[raw.length] = JavaCore.newLibraryEntry(cf.getFullPath(), null, null);
System.arraycopy(raw, 0, newRaw, 0, raw.length);
project.setRawClasspath(newRaw, new SubProgressMonitor(monitor, 100));
}
}
}, workspace.getRoot(), 0, pm);
}
public static void waitForAutoBuild() throws CoreException {
IJobManager jobManager = Job.getJobManager();
if (jobManager.find(ResourcesPlugin.FAMILY_AUTO_BUILD).length > 0) {
while (true) {
try {
jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, new NullProgressMonitor());
break;
} catch (InterruptedException e) {
}
}
}
}
}