Package de.loskutov.bco.ui

Source Code of de.loskutov.bco.ui.TestJdtUtils

package de.loskutov.bco.ui;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

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.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.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
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.IParent;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

public abstract class TestJdtUtils extends TestCase {

    private static final boolean onlyPrintOutError = false;
    private static String EXTERNAL_JAR_DIR_PATH;
    private IWorkspace workspace;
    private IWorkspaceRoot root;
    private IJavaProject project;

    protected abstract String getFieldName() ;

    protected abstract String getJdkVersion();

    protected String getJavaProjectName() {
        return "TestJdtUtils" + getFieldName();
    }

    protected void setUp() throws Exception {
        super.setUp();
        if(project == null){
            workspace = ResourcesPlugin.getWorkspace();
            root = workspace.getRoot();
            project = setUpJavaProject(getJavaProjectName(), getJdkVersion());
            project.getProject().build(
                IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
            project.makeConsistent(null);
        }
    }

    protected void tearDown() throws Exception {
        deleteProject(project.getProject());
        super.tearDown();
    }


    protected IJavaProject getJavaProject() {
        return project;
    }

    protected ICompilationUnit getCompilationUnit(String cuName)
        throws JavaModelException {

        ICompilationUnit compilationUnit = getCompilationUnit("src", "inner", cuName);
        return compilationUnit;
    }

    /**
     * Returns the specified compilation unit in the given project, root, and package
     * fragment or <code>null</code> if it does not exist.
     */
    protected ICompilationUnit getCompilationUnit(String rootPath,
        String packageName, String cuName) throws JavaModelException {
        IPackageFragment pkg = getPackageFragment(rootPath, packageName);
        if (pkg == null) {
            return null;
        }
        return pkg.getCompilationUnit(cuName);
    }

    /**
     * Returns the specified package fragment in the given project and root, or
     * <code>null</code> if it does not exist. The rootPath must be specified as a
     * project relative path. The empty path refers to the default package fragment.
     */
    protected IPackageFragment getPackageFragment(String rootPath,
        String packageName) throws JavaModelException {
        IPackageFragmentRoot root1 = getPackageFragmentRoot(rootPath);
        if (root1 == null) {
            return null;
        }
        return root1.getPackageFragment(packageName);
    }

    /**
     * Returns the specified package fragment root in the given project, or
     * <code>null</code> if it does not exist. If relative, the rootPath must be
     * specified as a project relative path. The empty path refers to the package fragment
     * root that is the project folder iteslf. If absolute, the rootPath refers to either
     * an external jar, or a resource internal to the workspace
     */
    protected IPackageFragmentRoot getPackageFragmentRoot(String rootPath)
        throws JavaModelException {

        IJavaProject project = getJavaProject();
        if (project == null) {
            return null;
        }
        IPath path = new Path(rootPath);
        if (path.isAbsolute()) {
            IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
                .getRoot();
            IResource resource = workspaceRoot.findMember(path);
            IPackageFragmentRoot root1;
            if (resource == null) {
                // external jar
                root1 = project.getPackageFragmentRoot(rootPath);
            } else {
                // resource in the workspace
                root1 = project.getPackageFragmentRoot(resource);
            }
            return root1;
        }
        IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
        if (roots == null || roots.length == 0) {
            return null;
        }
        for (int i = 0; i < roots.length; i++) {
            IPackageFragmentRoot root1 = roots[i];
            if (!root1.isExternal()
                && root1.getUnderlyingResource().getProjectRelativePath()
                    .equals(path)) {
                return root1;
            }
        }
        return null;
    }


    protected IJavaProject createJavaProject(final String projectName,
        final String[] sourceFolders, final String[] libraries,
        final String projectOutput, final String compliance)
        throws CoreException {
        final IJavaProject[] result = new IJavaProject[1];
        IWorkspaceRunnable create = new IWorkspaceRunnable() {

            public void run(IProgressMonitor monitor) throws CoreException {
                // create project
                createProject(projectName);

                // set java nature
                addJavaNature(projectName);

                // create classpath entries
                IProject project = root.getProject(projectName);
                IPath projectPath = project.getFullPath();
                int sourceLength = sourceFolders.length;
                int libLength = libraries.length;

                IClasspathEntry[] entries = new IClasspathEntry[sourceLength
                    + libLength];
                for (int i = 0; i < sourceLength; i++) {
                    IPath sourcePath = new Path(sourceFolders[i]);
                    int segmentCount = sourcePath.segmentCount();
                    if (segmentCount > 0) {
                        // create folder and its parents
                        IContainer container = project;
                        for (int j = 0; j < segmentCount; j++) {
                            IFolder folder = container.getFolder(new Path(
                                sourcePath.segment(j)));
                            if (!folder.exists()) {
                                folder.create(true, true, null);
                            }
                            container = folder;
                        }
                    }

                    // create source entry
                    entries[i] = JavaCore.newSourceEntry(
                        projectPath.append(sourcePath), new IPath[0],
                        new IPath[0], null);
                }

                for (int i = 0; i < libLength; i++) {
                    String lib = libraries[i];
                    if (lib.startsWith("JCL")) {
                        // ensure JCL variables are set
                         try {
                            setUpJCLClasspathVariables(compliance);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    if (lib.indexOf(File.separatorChar) == -1
                        && lib.charAt(0) != '/'
                        && lib.equals(lib.toUpperCase())) { // all upper case is a var
                        char[][] vars = CharOperation.splitOn(',', lib
                            .toCharArray());
                        entries[sourceLength + i] = JavaCore.newVariableEntry(
                            new Path(new String(vars[0])), vars.length > 1
                                ? new Path(new String(vars[1]))
                                : null, vars.length > 2
                                ? new Path(new String(vars[2]))
                                : null);
                    } else {
                        IPath libPath = new Path(lib);
                        if (!libPath.isAbsolute() && libPath.segmentCount() > 0
                            && libPath.getFileExtension() == null) {
                            project.getFolder(libPath).create(true, true, null);
                            libPath = projectPath.append(libPath);
                        }
                        entries[sourceLength + i] = JavaCore.newLibraryEntry(
                            libPath, null, null, ClasspathEntry.getAccessRules(
                                new IPath[0], new IPath[0]),
                            new IClasspathAttribute[0], false);
                    }
                }

                // create project's output folder
                IPath outputPath = new Path(projectOutput);
                if (outputPath.segmentCount() > 0) {
                    IFolder output = project.getFolder(outputPath);
                    if (!output.exists()) {
                        output.create(true, true, null);
                    }
                }

                // set classpath and output location
                IJavaProject javaProject = JavaCore.create(project);
                javaProject.setRawClasspath(entries, projectPath
                    .append(outputPath), null);

                // set compliance level options
                if ("1.5".equals(compliance)) {
                    Map options = new HashMap();
                    options.put(
                        CompilerOptions.OPTION_Compliance,
                        CompilerOptions.VERSION_1_5);
                    options.put(
                        CompilerOptions.OPTION_Source,
                        CompilerOptions.VERSION_1_5);
                    options.put(
                        CompilerOptions.OPTION_TargetPlatform,
                        CompilerOptions.VERSION_1_5);
                    javaProject.setOptions(options);
                }

                result[0] = javaProject;
            }
        };
        workspace.run(create, null);
        return result[0];
    }

    protected IProject createProject(final String projectName)
        throws CoreException {
        final IProject project1 = root.getProject(projectName);

        deleteProject(project1);

        IWorkspaceRunnable create = new IWorkspaceRunnable() {

            public void run(IProgressMonitor monitor) throws CoreException {
                project1.create(null);
                project1.open(null);
            }
        };
        workspace.run(create, null);
        return project1;
    }

    protected void addJavaNature(String projectName) throws CoreException {
        IProject project1 = root.getProject(projectName);
        IProjectDescription description = project1.getDescription();
        description.setNatureIds(new String[]{JavaCore.NATURE_ID});
        project1.setDescription(description, null);
    }

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


    protected IJavaProject setUpJavaProject(final String projectName,
        String compliance) throws CoreException, IOException {
        // copy files in project from source workspace to target workspace
        String sourceWorkspacePath = getSourcesPath();

        String targetWorkspacePath = root.getLocation().toFile()
            .getCanonicalPath();
        copyDirectory(new File(sourceWorkspacePath), new File(
            targetWorkspacePath + "/" + projectName, "src"));

        // ensure variables are set
        setUpJCLClasspathVariables(compliance);

        String sdkLib = "JCL15_LIB";
        if(!"1.5".equals(compliance)){
            sdkLib = "JCL_LIB";
        }

        // create project
        IJavaProject javaProject = createJavaProject(
            projectName, new String[]{"src"}, new String[] {sdkLib}, "bin", compliance);

        setUpProjectCompliance(javaProject, compliance);
        return javaProject;
    }

    protected void setUpProjectCompliance(IJavaProject javaProject,
        String compliance) throws JavaModelException, IOException {
        // Look for version to set and return if that's already done
        String version = CompilerOptions.VERSION_1_4;
        String jclLibString = null;
        String newJclLibString = null;
        switch (compliance.charAt(2)) {
            case '5' :
                version = CompilerOptions.VERSION_1_5;
                if (version.equals(javaProject.getOption(
                    CompilerOptions.OPTION_Compliance, false))) {
                    return;
                }
                jclLibString = "JCL_LIB";
                newJclLibString = "JCL15_LIB";
                break;
            case '3' :
                version = CompilerOptions.VERSION_1_3;
            default :
                if (version.equals(javaProject.getOption(
                    CompilerOptions.OPTION_Compliance, false))) {
                    return;
                }
                jclLibString = "JCL15_LIB";
                newJclLibString = "JCL_LIB";
                break;
        }

        // ensure variables are set
        setUpJCLClasspathVariables(compliance);

        // set options
        Map options = new HashMap();
        options.put(CompilerOptions.OPTION_Compliance, version);
        options.put(CompilerOptions.OPTION_Source, version);
        options.put(CompilerOptions.OPTION_TargetPlatform, version);
        javaProject.setOptions(options);

        // replace JCL_LIB with JCL15_LIB, and JCL_SRC with JCL15_SRC
        IClasspathEntry[] classpath = javaProject.getRawClasspath();
        IPath jclLib = new Path(jclLibString);
        for (int i = 0, length = classpath.length; i < length; i++) {
            IClasspathEntry entry = classpath[i];
            if (entry.getPath().equals(jclLib)) {
                classpath[i] = JavaCore.newVariableEntry(
                    new Path(newJclLibString), null, entry
                        .getSourceAttachmentRootPath(), entry.getAccessRules(),
                    new IClasspathAttribute[0], entry.isExported());
                break;
            }
        }
        javaProject.setRawClasspath(classpath, null);
    }

    protected void setUpJCLClasspathVariables(String compliance) throws JavaModelException, IOException {
        if ("1.5".equals(compliance)) {
            if (JavaCore.getClasspathVariable("JCL15_LIB") == null) {
                setupExternalJCL("jclMin1.5");
                JavaCore.setClasspathVariables(
                    new String[] {"JCL15_LIB", "JCL15_SRC", "JCL_SRCROOT"},
                    new IPath[] {getExternalJCLPath(compliance), null, null},
                    null);
            }
        } else {
            if (JavaCore.getClasspathVariable("JCL_LIB") == null) {
                setupExternalJCL("jclMin");
                JavaCore.setClasspathVariables(
                    new String[] {"JCL_LIB", "JCL_SRC", "JCL_SRCROOT"},
                    new IPath[] {getExternalJCLPath(), null, null},
                    null);
            }
        }
    }

    /**
     * Returns the IPath to the external java class library (e.g. jclMin.jar)
     */
    protected IPath getExternalJCLPath() {
        return new Path(getExternalJCLPathString(""));
    }
    /**
     * Returns the IPath to the external java class library (e.g. jclMin.jar)
     */
    protected IPath getExternalJCLPath(String compliance) {
        return new Path(getExternalJCLPathString(compliance));
    }

    /**
     * Returns the java.io path to the external java class library (e.g. jclMin.jar)
     */
    protected String getExternalJCLPathString(String compliance) {
        return getExternalPath() + "jclMin" + compliance + ".jar";
    }

    /**
     * Check locally for the required JCL files, <jclName>.jar and <jclName>src.zip.
     * If not available, copy from the project resources.
     */
    protected void setupExternalJCL(String jclName) throws IOException {
        String externalPath = getExternalPath();
        String separator = java.io.File.separator;
        String resourceJCLDir = getPluginDirectoryPath() + separator + "test" + separator + "JCL";
        java.io.File jclDir = new java.io.File(externalPath);
        java.io.File jclMin =
            new java.io.File(externalPath + jclName + ".jar");
        if (!jclDir.exists()) {
            if (!jclDir.mkdir()) {
                //mkdir failed
                throw new IOException("Could not create the directory " + jclDir);
            }
            //copy the file to the JCL directory
            java.io.File resourceJCLMin =
                new java.io.File(resourceJCLDir + separator + jclName + ".jar");
            copy(resourceJCLMin, jclMin);
        } else {
            //check that the file, jclMin.jar present
            //copy either file that is missing or less recent than the one in workspace
            java.io.File resourceJCLMin =
                new java.io.File(resourceJCLDir + separator + jclName + ".jar");
            if ((jclMin.lastModified() < resourceJCLMin.lastModified())
                    || (jclMin.length() != resourceJCLMin.length())) {
                copy(resourceJCLMin, jclMin);
            }
        }
    }

    /*
     * Returns the OS path to the external directory that contains external jar files.
     * This path ends with a File.separatorChar.
     */
    protected String getExternalPath() {
        if (EXTERNAL_JAR_DIR_PATH == null) {
            try {
                String path = root.getLocation().toFile().getParentFile().getCanonicalPath();
                if (path.charAt(path.length()-1) != File.separatorChar) {
                    path += File.separatorChar;
                }
                EXTERNAL_JAR_DIR_PATH = path;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return EXTERNAL_JAR_DIR_PATH;
    }

    /**
     * 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()) {
            boolean result = target.mkdirs();
            if(!result){
                throw new IOException("Can't create directory: " + target);
            }
        }
        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") || name.equals("loskutov")) {
                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).
     */
    protected 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();
    }

    protected 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;
    }

    /**
     * Returns the OS path to the directory that contains this plugin.
     */
    protected String getPluginDirectoryPath() {
        try {
            URL platformURL = Platform.getBundle("de.loskutov.BytecodeOutline")
                .getEntry("/");
            return new File(FileLocator.toFileURL(platformURL).getFile())
                .getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected String getSourcesPath() {
        return getPluginDirectoryPath() + java.io.File.separator + "test";
    }

    protected IType[] getAllTypes(ICompilationUnit cu) throws JavaModelException {
        ArrayList list = new ArrayList();
        collectAllTypes(cu, list);
        return (IType[])list.toArray(new IType[list.size()]);
    }

    protected void collectAllTypes(IParent parent, List types) throws JavaModelException {
        // this call has a (good) side effect that the IParent will be opened
        IJavaElement[] children = parent.getChildren();
        for (int i = 0; i < children.length; i++) {
            if(children[i] instanceof IType){
                types.add(children[i]);
                collectAllTypes((IParent) children[i], types);
            } else if (children[i] instanceof IParent){
                collectAllTypes((IParent) children[i], types);
            }
        }
    }

    protected void doTest(String topClassName) throws JavaModelException {
        System.out.println("Test with " + topClassName + ".java");

        ICompilationUnit cu = getCompilationUnit(topClassName + ".java");
        assertNotNull(cu);

        String packagePath = root.getLocation().append(getJavaProjectName()).append(
            "bin").append("inner").toOSString()
            + File.separator;

        String fieldName = getFieldName();
        IType[] allTypes = getAllTypes(cu);
        for (int i = 0; i < allTypes.length; i++) {
            IType type = allTypes[i];
            IField field = type.getField(fieldName);
            if (field == null) {
                continue;
            }
            String constant = (String) field.getConstant();
            if(constant != null){
                constant = constant.substring(1, constant.length() - 1);
            }
            String expectedPath = packagePath + constant + ".class";
            String name = JdtUtils.getByteCodePath(type);
            if(!(expectedPath).equals(name)){
                System.out.println("Expected/received: \nexpected  -> " + expectedPath + "\nreceived -> " + name + "\n");
                if(!onlyPrintOutError) {
                    assertEquals(expectedPath, name);
                }
            } else {
                System.out.println("OK: " + name);
            }
        }
    }

    protected void pauseTests() throws InterruptedException {
        while (true) {
            synchronized (this) {
                wait(50);
                while (Display.getDefault().readAndDispatch()) {
                    // do events
                }
            }
            if (PlatformUI.getWorkbench().isClosing()) {
                break;
            }
        }
    }
}
TOP

Related Classes of de.loskutov.bco.ui.TestJdtUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.