blob: 020758b6bc002caef8b5b187be7c86a6ea623a31 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 by SAP AG, Walldorf.
* 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:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.ws.jaxws.testutils.project;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.ws.jaxws.testutils.jobs.JobUtils;
import org.eclipse.jst.ws.jaxws.utils.ContractChecker;
import org.osgi.framework.Bundle;
@SuppressWarnings("restriction")
public class TestProject
{
public final static char CLASS_SEPARATOR = '#';
private int idInMillis = 0;
private IProject project;
private IJavaProject javaProject;
private IPackageFragmentRoot sourceFolder;
public TestProject() throws CoreException
{
this("");
}
public TestProject(String name) throws CoreException
{
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
/*
* Calculate the name of the test project. The formula: JavaProj_ + <current_time_in_millis? + <idInMillis> is ussed. In this formula
* JavaProj_ is a string litteral, current_time_in_millis is obvious. idInMillis is an integer incremented each time a project name is
* calculated. This is necessary because the system timer has precision about 10 ms. Thus it's possible that two consecutive project creations
* give the same project name. For example the project is creted then the test executes very fast and a new project is created again. In the
* same time simply the id is not enough as a different test run might produce the same project name. Thus the combination tim_millis +
* idInMillis gives a unique project name
*/
final String testProjectName = "JavaProj_" + Long.toString(System.currentTimeMillis()) + "_" + idInMillis++ + name;
project = root.getProject(testProjectName);
project.create(null);
project.open(null);
configureJavaProject();
}
private void configureJavaProject() throws CoreException
{
javaProject = JavaCore.create(project);
IFolder binFolder = createBinFolder();
setJavaNature();
javaProject.setRawClasspath(new IClasspathEntry[0], null);
createOutputFolder(binFolder);
addSystemLibraries();
}
public TestProject(final IProject project) throws CoreException
{
if (project == null)
{
throw new NullPointerException("project should not be null");
}
this.project = project;
this.javaProject = JavaCore.create(project);
this.sourceFolder = findSourceFolder();
}
private IPackageFragmentRoot findSourceFolder() throws JavaModelException
{
for (IPackageFragmentRoot pfr : javaProject.getAllPackageFragmentRoots())
{
if (pfr.getKind() == IPackageFragmentRoot.K_SOURCE)
{
return pfr;
}
}
return null;
}
public IProject getProject()
{
return project;
}
public IJavaProject getJavaProject()
{
return javaProject;
}
public void addJar(String plugin, String jar) throws MalformedURLException, IOException, JavaModelException
{
Path result = findFileInPlugin(plugin, jar);
IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = JavaCore.newLibraryEntry(result, null, null);
javaProject.setRawClasspath(newEntries, null);
String log = "\n"+javaProject.getProject().getName()+"\n"+String.valueOf(javaProject.getRawClasspath().length)+"\n";
for(int ii=0; ii < javaProject.getRawClasspath().length; ii++)
{
log = log + javaProject.getRawClasspath()[ii].getPath().toString()+"\n";
}
if(javaProject.getRawClasspath().length==0)
{
log = log + "Classpath not initialized !\n";
}
ResourcesPlugin.getPlugin().getLog().log(new Status(0,"testOutput",log));
}
public IPackageFragment createPackage(String name) throws CoreException
{
if (sourceFolder == null)
sourceFolder = createSourceFolder("src");
return sourceFolder.createPackageFragment(name, false, null);
}
public IType createType(IPackageFragment pack, String cuName, String source) throws JavaModelException
{
StringBuffer buf = new StringBuffer();
buf.append("package " + pack.getElementName() + ";\n");
buf.append("\n");
buf.append(source);
ICompilationUnit cu = pack.createCompilationUnit(cuName, buf.toString(), false, null);
return cu.getTypes()[0];
}
/**
* Creates multiple classes in project. The content of <code>source</code> should be in form -
* '#' char (separator for classes) followed by Class name, new line and after that class source without package declaration.<br>
* Example:
*
* <pre>
* #ImplementsRemote
* public class ImplementsRemote implements java.rmi.Remote
* {
* }
*
* #NoDefaultConstructor
* public class NoDefaultConstructor implements java.io.Serializable
* {
* public NoDefaultConstructor(String param) {
* }
* }
* </pre>
*
* This method is useful if lots of small classes should be created from a source file.
*
* @param sourcesFilePath
* @return map of className->IType. that have been created
* @throws Exception
*/
public Map<String, IType> createTypes(IPackageFragment pack, String source) throws Exception
{
Map<String, IType> types = new HashMap<String, IType>();
int startPos = 0;
while ((startPos = source.indexOf(CLASS_SEPARATOR)) > -1)
{
int endPos = source.indexOf(CLASS_SEPARATOR, startPos + 1);
if (endPos == -1) {
endPos = source.length();
}
String src = source.substring(startPos + 1, endPos);
source = source.substring(endPos);
String className = src.substring(0, src.indexOf('\n')).replaceAll("\r", "").trim();
src = src.substring(src.indexOf('\n') + 1);
types.put(className, createType(pack, className + ".java", src));
}
return types;
}
public void dispose() throws CoreException
{
JobUtils.waitForJobs();
try {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
project.delete(true, true, null);
} catch (ResourceException re) {
/*
* silently swallow the resource exception. For some reason this exception gets thrown
* from time to time and reports the test failing. The project deletion itself happens
* after the test has completed and a failure will not report a problem in the test.
* Only ResourceException is caught in order not to hide unexpected errors.
*/
return;
}
}
public void close() throws CoreException
{
JobUtils.waitForJobs();
project.close(new NullProgressMonitor());
}
private IFolder createBinFolder() throws CoreException
{
IFolder binFolder = project.getFolder("bin");
binFolder.create(false, true, null);
return binFolder;
}
private void setJavaNature() throws CoreException
{
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] { JavaCore.NATURE_ID });
project.setDescription(description, null);
}
private void createOutputFolder(IFolder binFolder) throws JavaModelException
{
IPath outputLocation = binFolder.getFullPath();
javaProject.setOutputLocation(outputLocation, null);
}
public IPackageFragmentRoot createSourceFolder(String name) throws CoreException
{
IFolder folder = project.getFolder(name);
folder.create(false, true, null);
IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath());
javaProject.setRawClasspath(newEntries, null);
this.sourceFolder = root;
String log = "\n"+javaProject.getProject().getName()+"\n"+String.valueOf(javaProject.getRawClasspath().length)+"\n";
for(int ii=0; ii < javaProject.getRawClasspath().length; ii++)
{
log = log + javaProject.getRawClasspath()[ii].getPath().toString()+"\n";
}
if(javaProject.getRawClasspath().length==0)
{
log = log + "Classpath not initialized !\n";
}
ResourcesPlugin.getPlugin().getLog().log(new Status(0,"testOutput",log));
return root;
}
private void addSystemLibraries() throws JavaModelException
{
IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = JavaRuntime.getDefaultJREContainerEntry();
javaProject.setRawClasspath(newEntries, null);
String log = "\n"+javaProject.getProject().getName()+"\n"+String.valueOf(javaProject.getRawClasspath().length)+"\n";
for(int ii=0; ii < javaProject.getRawClasspath().length; ii++)
{
log = log + javaProject.getRawClasspath()[ii].getPath().toString()+"\n";
}
if(javaProject.getRawClasspath().length==0)
{
log = log + "Classpath not initialized !\n";
}
ResourcesPlugin.getPlugin().getLog().log(new Status(0,"testOutput",log));
}
private Path findFileInPlugin(String plugin, String file) throws MalformedURLException, IOException
{
Bundle pluginBundle = Platform.getBundle(plugin);
URL jarURL = new URL(pluginBundle.getEntry("/"), file);
URL localJarURL = FileLocator.toFileURL(jarURL);
return new Path(localJarURL.getPath());
}
public IPackageFragmentRoot getSourceFolder()
{
return sourceFolder;
}
/**
*
* @return the container corresponding to the package fragment root, i.e. the source folder.<br>
* If this project is a jar/zip (if this is possible at all), the method will return null.
*/
public IContainer getSourceFolderContainer()
{
try{
IResource res = getSourceFolder().getCorrespondingResource();
if(res==null) {
return null;
}else {
IContainer retVal = (IContainer) res;
return retVal;
}
}catch(JavaModelException ex) {
return null;
}catch(ClassCastException ex) {
return null;
}
}
public IFolder createFolder(final String folderName) throws CoreException
{
ContractChecker.nullCheckParam(folderName, "folderName");
final IFolder folder = this.project.getFolder(folderName);
folder.create(false, true, null);
return folder;
}
/**
* Set the project root as source folder
* @throws JavaModelException
*/
public void assignProjectRootAsSourceFolder() throws JavaModelException
{
IClasspathEntry defaultSrcFolderEntry = JavaCore.newSourceEntry(project.getFullPath());
IClasspathEntry[] oldCp = javaProject.getRawClasspath();
IClasspathEntry[] newCp = new IClasspathEntry[oldCp.length + 1];
System.arraycopy(oldCp, 0, newCp, 0, oldCp.length);
newCp[newCp.length - 1] = defaultSrcFolderEntry;
javaProject.setRawClasspath(newCp, null);
this.sourceFolder = TestProjectsUtils.getSourceFolder(project, "");
String log = "\n"+javaProject.getProject().getName()+"\n"+String.valueOf(javaProject.getRawClasspath().length)+"\n";
for(int ii=0; ii < javaProject.getRawClasspath().length; ii++)
{
log = log + javaProject.getRawClasspath()[ii].getPath().toString()+"\n";
}
if(javaProject.getRawClasspath().length==0)
{
log = log + "Classpath not initialized !\n";
}
ResourcesPlugin.getPlugin().getLog().log(new Status(0,"testOutput",log));
}
}