org.eclipse.contribution.weaving.jdt.tests.WeavingTestCase.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.contribution.weaving.jdt.tests.WeavingTestCase.java

Source

/*******************************************************************************
 * Copyright (c) 2005 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
 *     Matt Chapman  - initial version
 *******************************************************************************/
package org.eclipse.contribution.weaving.jdt.tests;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

import junit.framework.TestCase;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
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.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
 * Mainly copied from AbstractJavaModelTests in org.eclipse.jdt.core.tests.model
 */
public class WeavingTestCase extends TestCase {

    protected IProgressMonitor monitor = new DumbProgressMonitor();

    public void tearDown() throws Exception {
        IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        for (int i = 0; i < allProjects.length; i++) {
            IProject project = allProjects[i];
            deleteProject(project, false);
        }
        allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        for (int i = 0; i < allProjects.length; i++) {
            IProject project = allProjects[i];
            deleteProject(project, true);
        }
    }

    /**
     * Returns the IWorkspace this test suite is running on.
     */
    public IWorkspace getWorkspace() {
        return ResourcesPlugin.getWorkspace();
    }

    public IWorkspaceRoot getWorkspaceRoot() {
        return getWorkspace().getRoot();
    }

    protected IProject createPredefinedProject(final String projectName) throws CoreException, IOException {
        IJavaProject jp = setUpJavaProject(projectName);
        jp.setOption("org.eclipse.jdt.core.compiler.problem.missingSerialVersion", "ignore"); //$NON-NLS-1$ //$NON-NLS-2$
        jp.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
        return jp.getProject();
    }

    /**
     * Create a named project, optionally turn of some irritating options that can clog up the output and then build it
     */
    protected IProject createPredefinedProject(final String projectName, boolean turnOffIrritatingOptions)
            throws CoreException, IOException {
        IJavaProject jp = setUpJavaProject(projectName);
        if (turnOffIrritatingOptions) {
            jp.setOption("org.eclipse.jdt.core.compiler.problem.missingSerialVersion", "ignore");//$NON-NLS-1$ //$NON-NLS-2$ // $NON-NLS-2$
            jp.setOption("org.eclipse.jdt.core.compiler.problem.rawTypeReference", "ignore");//$NON-NLS-1$ //$NON-NLS-2$ // $NON-NLS-2$
            jp.setOption("org.eclipse.jdt.core.compiler.taskTags", "");//$NON-NLS-1$ //$NON-NLS-2$ // $NON-NLS-2$
        }
        jp.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
        return jp.getProject();
    }

    protected IJavaProject setUpJavaProject(final String projectName) throws CoreException, IOException {
        return setUpJavaProject(projectName, "1.5"); //$NON-NLS-1$
    }

    protected IJavaProject setUpJavaProject(final String projectName, String compliance)
            throws CoreException, IOException {
        // copy files in project from source workspace to target workspace
        String sourceWorkspacePath = getSourceWorkspacePath();
        String targetWorkspacePath = getWorkspaceRoot().getLocation().toFile().getCanonicalPath();
        copyDirectory(new File(sourceWorkspacePath, projectName), new File(targetWorkspacePath, projectName));

        // create project
        final IProject project = getWorkspaceRoot().getProject(projectName);
        IWorkspaceRunnable populate = new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {
                project.create(null);
                project.open(null);
            }
        };
        getWorkspace().run(populate, null);

        IJavaProject javaProject = JavaCore.create(project);
        return javaProject;
    }

    /**
    * Returns the OS path to the directory that contains this plugin.
    */
    protected String getPluginDirectoryPath() {
        try {
            URL platformURL = Platform.getBundle("org.eclipse.contribution.weaving.jdt.tests").getEntry("/"); //$NON-NLS-1$ //$NON-NLS-2$
            return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getSourceWorkspacePath() {
        return getPluginDirectoryPath() + java.io.File.separator + "workspace"; //$NON-NLS-1$
    }

    // A dumb progressmonitor we can use - if we dont pass one it may create a UI one...
    static class DumbProgressMonitor implements IProgressMonitor {

        public void beginTask(String name, int totalWork) {
            /*dontcare*/}

        public void done() {
            /*dontcare*/}

        public void internalWorked(double work) {
            /*dontcare*/}

        public boolean isCanceled() {
            /*dontcare*/return false;
        }

        public void setCanceled(boolean value) {
            /*dontcare*/}

        public void setTaskName(String name) {
            /*dontcare*/}

        public void subTask(String name) {
            /*dontcare*/}

        public void worked(int work) {
            /*dontcare*/}

    }

    /**
     * Copy the given source directory (and all its contents) to the given target directory.
     */
    protected void copyDirectory(File source, File target) throws IOException {
        if (!target.exists()) {
            target.mkdirs();
        }
        File[] files = source.listFiles();
        if (files == null)
            return;
        for (int i = 0; i < files.length; i++) {
            File sourceChild = files[i];
            String name = sourceChild.getName();
            if (name.equals("CVS")) //$NON-NLS-1$
                continue;
            File targetChild = new File(target, name);
            if (sourceChild.isDirectory()) {
                copyDirectory(sourceChild, targetChild);
            } else {
                copy(sourceChild, targetChild);
            }
        }
    }

    /**
     * Copy file from src (path to the original file) to dest (path to the destination file).
     */
    public void copy(File src, File dest) throws IOException {
        // read source bytes
        byte[] srcBytes = this.read(src);

        // write bytes to dest
        FileOutputStream out = new FileOutputStream(dest);
        out.write(srcBytes);
        out.close();
    }

    public byte[] read(java.io.File file) throws java.io.IOException {
        int fileLength;
        byte[] fileBytes = new byte[fileLength = (int) file.length()];
        java.io.FileInputStream stream = new java.io.FileInputStream(file);
        int bytesRead = 0;
        int lastReadSize = 0;
        while ((lastReadSize != -1) && (bytesRead != fileLength)) {
            lastReadSize = stream.read(fileBytes, bytesRead, fileLength - bytesRead);
            bytesRead += lastReadSize;
        }
        stream.close();
        return fileBytes;
    }

    protected IProject getProject(String project) {
        return getWorkspaceRoot().getProject(project);
    }

    protected void deleteProject(IProject project, boolean force) throws CoreException {
        if (project.exists() && !project.isOpen()) { // force opening so that project can be deleted without logging (see bug 23629)
            project.open(null);
        }
        deleteResource(project, force);
    }

    protected void deleteProject(String projectName) throws CoreException {
        deleteProject(this.getProject(projectName), true);
    }

    /**
     * Delete this resource.
     */
    public void deleteResource(IResource resource, boolean force) throws CoreException {
        waitForManualBuild();
        waitForAutoBuild();
        CoreException lastException = null;
        try {
            resource.delete(false, null);
        } catch (CoreException e) {
            lastException = e;
            // just print for info
            System.out.println("(CoreException): " + e.getMessage() + " Resource " + resource.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
            e.printStackTrace();
        } catch (IllegalArgumentException iae) {
            // just print for info
            System.out.println(
                    "(IllegalArgumentException): " + iae.getMessage() + ", resource " + resource.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
        }
        if (!force) {
            return;
        }
        int retryCount = 10; // wait 1 minute at most
        while (resource.isAccessible() && --retryCount >= 0) {
            waitForAutoBuild();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            try {
                resource.delete(true, null);
            } catch (CoreException e) {
                lastException = e;
                // just print for info
                System.out.println("(CoreException) Retry " + retryCount + ": " + e.getMessage() + ", resource " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                        + resource.getFullPath());
            } catch (IllegalArgumentException iae) {
                // just print for info
                System.out.println("(IllegalArgumentException) Retry " + retryCount + ": " + iae.getMessage() //$NON-NLS-1$//$NON-NLS-2$
                        + ", resource " + resource.getFullPath()); //$NON-NLS-1$
            }
        }
        if (!resource.isAccessible())
            return;
        System.err.println("Failed to delete " + resource.getFullPath()); //$NON-NLS-1$
        if (lastException != null) {
            throw lastException;
        }
    }

    protected void waitForJobsToComplete() {
        SynchronizationUtils.joinBackgroudActivities();
    }

    private void ensureExists(IFolder folder) throws CoreException {
        if (folder.getParent().getType() == IResource.FOLDER && !folder.getParent().exists()) {
            ensureExists((IFolder) folder.getParent());
        }
        folder.create(false, true, null);
    }

    private IPackageFragmentRoot createDefaultSourceFolder(IJavaProject javaProject) throws CoreException {
        IProject project = javaProject.getProject();
        IFolder folder = project.getFolder("src");
        if (!folder.exists())
            ensureExists(folder);
        final IClasspathEntry[] entries = javaProject.getResolvedClasspath(false);
        final IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
        for (int i = 0; i < entries.length; i++) {
            final IClasspathEntry entry = entries[i];
            if (entry.getPath().equals(folder.getFullPath()))
                return root;
        }
        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);
        return root;
    }

    public IPackageFragment createPackage(String name, IJavaProject javaProject) throws CoreException {
        return createPackage(name, null, javaProject);
    }

    public IPackageFragment createPackage(String name, IPackageFragmentRoot sourceFolder, IJavaProject javaProject)
            throws CoreException {
        if (sourceFolder == null)
            sourceFolder = createDefaultSourceFolder(javaProject);
        return sourceFolder.createPackageFragment(name, false, null);
    }

    public ICompilationUnit createCompilationUnit(IPackageFragment pack, String cuName, String source)
            throws JavaModelException {
        StringBuffer buf = new StringBuffer();
        buf.append(source);
        ICompilationUnit unit = pack.createCompilationUnit(cuName, buf.toString(), false, null);
        waitForManualBuild();
        waitForAutoBuild();
        return unit;
    }

    public ICompilationUnit createCompilationUnitAndPackage(String packageName, String fileName, String source,
            IJavaProject javaProject) throws CoreException {
        return createCompilationUnit(createPackage(packageName, javaProject), fileName, source);
    }

    protected void buildProject(IJavaProject javaProject) throws CoreException {
        javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
        assertNoProblems(javaProject.getProject());
        performDummySearch(javaProject);
    }

    /**
     * Force indexes to be populated
     */
    public static void performDummySearch(IJavaElement element) throws CoreException {
        new SearchEngine().searchAllTypeNames(null, SearchPattern.R_EXACT_MATCH, "XXXXXXXXX".toCharArray(), // make sure we search a concrete name. This is faster according to Kent
                SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.CLASS,
                SearchEngine.createJavaSearchScope(new IJavaElement[] { element }), new Requestor(),
                IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
    }

    protected static class Requestor extends TypeNameRequestor {
    }

    public void assertNoProblems(IProject project) throws CoreException {
        String problems = getProblems(project);
        if (problems != null) {
            fail("Expecting no problems for project " + project.getName() + ", but found:\n\n" + problems);
        }
    }

    public String getProblems(IProject project) throws CoreException {
        IMarker[] markers = project.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true,
                IResource.DEPTH_INFINITE);
        StringBuffer sb = new StringBuffer();
        if (markers == null || markers.length == 0) {
            return null;
        }
        boolean errorFound = false;
        sb.append("Problems:\n");
        for (int i = 0; i < markers.length; i++) {
            if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) {
                sb.append("  ");
                sb.append(markers[i].getResource().getName()).append(" : ");
                sb.append(markers[i].getAttribute(IMarker.LINE_NUMBER)).append(" : ");
                sb.append(markers[i].getAttribute(IMarker.MESSAGE)).append("\n");
                errorFound = true;
            }
        }
        return errorFound ? sb.toString() : null;
    }

    public static void waitForAutoBuild() {
        waitForJobFamily(ResourcesPlugin.FAMILY_AUTO_BUILD);
    }

    public static void waitForManualBuild() {
        waitForJobFamily(ResourcesPlugin.FAMILY_MANUAL_BUILD);
    }

    public static void waitForAutoRefresh() {
        waitForJobFamily(ResourcesPlugin.FAMILY_AUTO_REFRESH);
    }

    public static void waitForManualRefresh() {
        waitForJobFamily(ResourcesPlugin.FAMILY_MANUAL_REFRESH);
    }

    public static void waitForJobFamily(Object family) {
        boolean wasInterrupted = false;
        do {
            try {
                Job.getJobManager().join(family, new NullProgressMonitor());
                wasInterrupted = false;
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                wasInterrupted = true;
            }
        } while (wasInterrupted);

    }

    public static void joinBackgroudActivities() {
        waitForAutoBuild();
        waitForManualBuild();
        waitForAutoRefresh();
        waitForManualRefresh();
    }

}

//Adapted from org.eclipse.jdt.ui.tests.performance.JdtPerformanceTestCase
class SynchronizationUtils {

    public static void joinBackgroudActivities() {
        // Join Building
        boolean interrupted = true;
        while (interrupted) {
            try {
                Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
                interrupted = false;
            } catch (InterruptedException e) {
                interrupted = true;
            }
        }
        boolean wasInterrupted = false;
        do {
            try {
                Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null);
                wasInterrupted = false;
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                wasInterrupted = true;
            }
        } while (wasInterrupted);
        // Join jobs
        joinJobs(100, 0, 500);
    }

    private static boolean joinJobs(long minTime, long maxTime, long intervalTime) {
        long startTime = System.currentTimeMillis() + minTime;
        runEventQueue();
        while (System.currentTimeMillis() < startTime)
            runEventQueue(intervalTime);

        long endTime = maxTime > 0 && maxTime < Long.MAX_VALUE ? System.currentTimeMillis() + maxTime
                : Long.MAX_VALUE;
        boolean calm = allJobsQuiet();
        while (!calm && System.currentTimeMillis() < endTime) {
            runEventQueue(intervalTime);
            calm = allJobsQuiet();
        }
        return calm;
    }

    private static void sleep(int intervalTime) {
        try {
            Thread.sleep(intervalTime);
        } catch (InterruptedException e) {
        }
    }

    private static boolean allJobsQuiet() {
        IJobManager jobManager = Job.getJobManager();
        Job[] jobs = jobManager.find(null);
        for (int i = 0; i < jobs.length; i++) {
            Job job = jobs[i];
            int state = job.getState();
            //ignore jobs we don't care about
            if (!job.getName().equals("Flush Cache Job") && //$NON-NLS-1$
                    !job.getName().equals("Usage Data Event consumer") && //$NON-NLS-1$
                    (state == Job.RUNNING || state == Job.WAITING)) {
                return false;
            }
        }
        return true;
    }

    private static void runEventQueue() {
        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null)
            runEventQueue(window.getShell());
    }

    private static void runEventQueue(Shell shell) {
        try {
            while (shell.getDisplay().readAndDispatch()) {
                // do nothing
            }
        } catch (SWTException e) {
            System.err.println(e);
        }
    }

    private static void runEventQueue(long minTime) {
        long nextCheck = System.currentTimeMillis() + minTime;
        while (System.currentTimeMillis() < nextCheck) {
            runEventQueue();
            sleep(1);
        }
    }
}