eu.cloudwave.wp5.feedback.eclipse.tests.fixtures.base.JavaProjectFixture.java Source code

Java tutorial

Introduction

Here is the source code for eu.cloudwave.wp5.feedback.eclipse.tests.fixtures.base.JavaProjectFixture.java

Source

/*******************************************************************************
 * 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);
    }

}