/******************************************************************************* * Copyright 2015 Software Evolution and Architecture Lab, University of Zurich * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package eu.cloudwave.wp5.feedback.eclipse.tests.fixtures.base; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPluginDescriptor; import org.eclipse.core.runtime.IPluginRegistry; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; 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.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.ITypeNameRequestor; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.launching.JavaRuntime; import com.google.common.io.CharStreams; /** * This class acts as a fixture for projects in the junit-workspace. * * It provides functionality to create a Java project and fill it with packages and types. * * The code comes from the book 'Contributing to Eclipse: Principles, Patterns, and Plug-Ins' by Erich Gamma and Kent * Beck and has been adapted/extended. */ @SuppressWarnings("deprecation") public class JavaProjectFixture { private static final String UTF_8 = "UTF-8"; private static final String BIN_FOLDER = "bin"; private IProject project; private IJavaProject javaProject; private IPackageFragmentRoot sourceFolder; public JavaProjectFixture(final String name) throws CoreException { final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); project = root.getProject(name); project.create(null); project.open(null); javaProject = JavaCore.create(project); final IFolder binFolder = createBinFolder(); addJavaNature(); javaProject.setRawClasspath(new IClasspathEntry[0], null); createOutputFolder(binFolder); addSystemLibraries(); } public IProject getProject() { return project; } public String getName() { return project.getName(); } public IJavaProject getJavaProject() { return javaProject; } /** * Adds a jar-File from a plugin deployed with the workbench to the project. * * @param plugin * the id of the plugin that contains the jar-File * @param name * the name of the jar-File */ public void addJar(final String plugin, final String name) throws MalformedURLException, IOException, JavaModelException { addJar(findFileInPlugin(plugin, name)); } /** * Adds a jar-File from a specified path to the project. * * @param path * the path to the jar-File (can be either relative to the project root or absolute) */ public void addJar(final String path) throws MalformedURLException, IOException, JavaModelException { addJar(new Path(getAbsolutePath(path))); } private String getAbsolutePath(final String path) { return new File(path).getAbsolutePath(); } /** * Adds a jar-File from a specified path to the project. * * @param path * the path to the jar-File */ public void addJar(final Path path) throws MalformedURLException, IOException, JavaModelException { final IClasspathEntry[] oldEntries = javaProject.getRawClasspath(); final IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = JavaCore.newLibraryEntry(path, null, null); javaProject.setRawClasspath(newEntries, null); } /** * Creates a package fragment. * * @param name * the name of the package fragment * @return the created {@link IPackageFragment} */ public IPackageFragment createPackage(final String name) throws CoreException { if (sourceFolder == null) sourceFolder = createSourceFolder(); return sourceFolder.createPackageFragment(name, false, null); } /** * Creates a Java type (i.e. a class or an interface). * * @param packageFragment * the package to which the type should be added * @param name * the name of the type * @param content * the source content of the type * @return the created {@link IType} */ public IType createTypeFromContent(final IPackageFragment packageFragment, final String name, final String content) throws JavaModelException { final ICompilationUnit compilationUnit = packageFragment.createCompilationUnit(name, content, false, null); return compilationUnit.getTypes()[0]; } /** * Creates a Java type (i.e. a class or an interface). * * @param packageFragment * the package to which the type should be added * @param name * the name of the type * @param filePath * the path to the file that contains the content for the type * @return the created {@link IType} */ public IType createTypeFromFile(final IPackageFragment packageFragment, final String name, final String filePath) throws JavaModelException, UnsupportedEncodingException, IOException { return createTypeFromContent(packageFragment, name, getResourceAsString(filePath)); } private String getResourceAsString(final String path) throws UnsupportedEncodingException, IOException { final InputStream is = getClass().getResourceAsStream(path); return CharStreams.toString(new InputStreamReader(is, UTF_8)); } /** * Disppses the project. */ public void dispose() throws CoreException { waitForIndexer(); project.delete(true, true, null); } private IFolder createBinFolder() throws CoreException { final IFolder binFolder = project.getFolder(BIN_FOLDER); binFolder.create(false, true, null); return binFolder; } private void addJavaNature() throws CoreException { final IProjectDescription description = project.getDescription(); description.setNatureIds(new String[] { JavaCore.NATURE_ID }); project.setDescription(description, null); } private void createOutputFolder(final IFolder binFolder) throws JavaModelException { final IPath outputLocation = binFolder.getFullPath(); javaProject.setOutputLocation(outputLocation, null); } private IPackageFragmentRoot createSourceFolder() throws CoreException { final IFolder folder = project.getFolder("src"); folder.create(false, true, null); final IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder); final IClasspathEntry[] oldEntries = javaProject.getRawClasspath(); final 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); return root; } private void addSystemLibraries() throws JavaModelException { final IClasspathEntry[] oldEntries = javaProject.getRawClasspath(); final IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = JavaRuntime.getDefaultJREContainerEntry(); javaProject.setRawClasspath(newEntries, null); } private Path findFileInPlugin(final String plugin, final String file) throws MalformedURLException, IOException { final IPluginRegistry registry = Platform.getPluginRegistry(); final IPluginDescriptor descriptor = registry.getPluginDescriptor(plugin); final URL pluginURL = descriptor.getInstallURL(); final URL jarURL = new URL(pluginURL, file); final URL localJarURL = Platform.asLocalURL(jarURL); return new Path(localJarURL.getPath()); } private void waitForIndexer() throws JavaModelException { new SearchEngine().searchAllTypeNames(ResourcesPlugin.getWorkspace(), null, null, IJavaSearchConstants.EXACT_MATCH, IJavaSearchConstants.CASE_SENSITIVE, IJavaSearchConstants.CLASS, SearchEngine.createJavaSearchScope(new IJavaElement[0]), new ITypeNameRequestor() { @Override public void acceptClass(final char[] packageName, final char[] simpleTypeName, final char[][] enclosingTypeNames, final String path) {} @Override public void acceptInterface(final char[] packageName, final char[] simpleTypeName, final char[][] enclosingTypeNames, final String path) {} }, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null); } }