ca.mcgill.cs.swevo.ppa.ui.PPAUtil.java Source code

Java tutorial

Introduction

Here is the source code for ca.mcgill.cs.swevo.ppa.ui.PPAUtil.java

Source

/*******************************************************************************
 * PPA - Partial Program Analysis for Java
 * Copyright (C) 2008 Barthelemy Dagenais
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either 
 * version 3 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this library. If not, see 
 * <http://www.gnu.org/licenses/lgpl-3.0.txt>
 * 
 * Contributors:
 *     Puneet Kapur - 2009
 *******************************************************************************/
package ca.mcgill.cs.swevo.ppa.ui;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTRequestor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.PPAASTParser;
import org.eclipse.jdt.core.dom.PPAEngine;
import org.eclipse.jdt.core.dom.PPATypeRegistry;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.internal.core.JavaProject;

import ca.mcgill.cs.swevo.ppa.PPAOptions;
import ca.mcgill.cs.swevo.ppa.SnippetUtil;

/**
 * <p>
 * Collection of utility methods to get compilation units from partial programs.
 * </p>
 * 
 * @author Barthelemy Dagenais
 * 
 */
@SuppressWarnings("restriction")
public class PPAUtil {

    private final static Logger logger = Logger.getLogger(PPAUtil.class);

    public static void cleanUp(CompilationUnit cu, String requestName) {
        ICompilationUnit icu = (ICompilationUnit) cu.getJavaElement();
        IFile iFile = (IFile) icu.getResource();
        IProject project = iFile.getProject();
        if (project.equals(ResourcesPlugin.getWorkspace().getRoot().getProject(getPPAProjectName(requestName)))) {
            try {
                PPAResourceUtil.cleanUp(iFile);
            } catch (CoreException ce) {
                logger.error("Error during file cleanup.", ce);
            } finally {
                PPAUIActivator.getDefault().releaseId(requestName);
            }
        }
    }

    public static void cleanUp(CompilationUnit cu) {
        cleanUp(cu, Thread.currentThread().getName());
    }

    public static void cleanUpAll() {
        cleanUpAll(Thread.currentThread().getName());
    }

    public static void cleanUpAll(String requestName) {
        IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(getPPAProjectName(requestName));
        if (project.exists()) {
            int deleted = 0;
            IFolder src = project.getFolder("src");
            final List<IFile> toDelete = new ArrayList<IFile>();
            try {
                src.accept(new IResourceVisitor() {

                    public boolean visit(IResource resource) throws CoreException {
                        if (resource.getType() == IResource.FILE) {
                            toDelete.add((IFile) resource);
                        }
                        return true;
                    }

                });
            } catch (Exception e) {
                logger.error("Error while cleaning up PPA project", e);
            }

            for (IFile file : toDelete) {
                try {
                    file.delete(true, new NullProgressMonitor());
                    deleted++;
                } catch (Exception e) {
                    logger.error("Error while cleaning up PPA project", e);
                }
            }
            PPAUIActivator.getDefault().releaseId(requestName);
            // logger.info("DELETED: " + deleted + " files deleted out of " +
            // toDelete.size());
        }
    }

    public static void cleanUpSnippet(String requestName) {
        IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(getPPAProjectName(requestName));
        IFolder snippetFolder = project.getFolder("src").getFolder(SnippetUtil.SNIPPET_PACKAGE);
        IFile snippetFile = snippetFolder.getFile(SnippetUtil.SNIPPET_FILE);
        try {
            snippetFile.delete(true, new NullProgressMonitor());
            snippetFolder.delete(true, new NullProgressMonitor());
        } catch (CoreException ce) {
            logger.error("Error during file cleanup.", ce);
        } finally {
            PPAUIActivator.getDefault().releaseId(requestName);
        }
    }

    public static void cleanUpSnippet() {
        cleanUpSnippet(Thread.currentThread().getName());
    }

    public static CompilationUnit getCU(String content, PPAOptions options) {
        CompilationUnit cu = null;

        try {
            File temp = File.createTempFile(SnippetUtil.SNIPPET_CLASS, ".java");
            BufferedWriter out = new BufferedWriter(new FileWriter(temp));
            out.write(content);
            out.close();
            cu = getCU(temp, options);
            temp.delete();
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }
        return cu;
    }

    public static CompilationUnit getCU(final File file, final PPAOptions options) {
        return getCU(file, options, Thread.currentThread().getName());
    }

    public static CompilationUnit getCU(File file, PPAOptions options, String requestName) {
        CompilationUnit cu = null;
        String fileName = file.getName();

        try {
            String packageName = getPackageFromFile(file);
            String ppaProjectName = getPPAProjectName(requestName);
            PPAJavaProjectHelper helper = new PPAJavaProjectHelper();
            IJavaProject javaProject = helper.setupJavaProject(ppaProjectName);
            IFile newFile = PPAResourceUtil.copyJavaSourceFile(javaProject.getProject(), file, packageName,
                    fileName);
            cu = getCU(newFile, options);
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }

        return cu;
    }

    public static CompilationUnit getCU(IFile file, PPAOptions options) {
        CompilationUnit cu = null;
        try {
            ICompilationUnit icu = JavaCore.createCompilationUnitFrom(file);
            PPATypeRegistry registry = new PPATypeRegistry(
                    (JavaProject) JavaCore.create(icu.getUnderlyingResource().getProject()));
            ASTNode node = null;
            PPAASTParser parser2 = new PPAASTParser(AST.JLS3);
            parser2.setStatementsRecovery(true);
            parser2.setResolveBindings(true);
            parser2.setSource(icu);
            node = parser2.createAST(null);
            PPAEngine ppaEngine = new PPAEngine(registry, options);

            cu = (CompilationUnit) node;

            ppaEngine.addUnitToProcess(cu);
            ppaEngine.doPPA();
            ppaEngine.reset();
        } catch (JavaModelException jme) {
            // Retry with the file version.
            logger.warn("Warning while getting CU from PPA");
            logger.debug("Exception", jme);
            cu = getCU(file.getLocation().toFile(), options);
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }

        return cu;
    }

    public static CompilationUnit getCUNoPPA(IFile file) {
        CompilationUnit cu = null;
        try {
            ICompilationUnit icu = JavaCore.createCompilationUnitFrom(file);
            ASTNode node = null;
            PPAASTParser parser2 = new PPAASTParser(AST.JLS3);
            parser2.setStatementsRecovery(true);
            parser2.setResolveBindings(true);
            parser2.setSource(icu);
            node = parser2.createAST(null);
            cu = (CompilationUnit) node;
        } catch (Exception e) {
            logger.error("Error while getting CU without PPA", e);
        }

        return cu;
    }

    public static List<CompilationUnit> getCUs(final List<File> files, final PPAOptions options) {
        return getCUs(files, options, Thread.currentThread().getName());
    }

    public static List<CompilationUnit> getCUs(List<File> files, PPAOptions options, String requestName) {
        List<CompilationUnit> cus = new ArrayList<CompilationUnit>();
        List<IFile> iFiles = new ArrayList<IFile>();

        for (File file : files) {
            String fileName = file.getName();
            try {
                String packageName = getPackageFromFile(file);
                String ppaProjectName = getPPAProjectName(requestName);
                PPAJavaProjectHelper helper = new PPAJavaProjectHelper();
                IJavaProject javaProject = helper.setupJavaProject(ppaProjectName);
                IFile newFile = PPAResourceUtil.copyJavaSourceFile(javaProject.getProject(), file, packageName,
                        fileName);
                iFiles.add(newFile);
                System.out.println(fileName);
            } catch (Exception e) {
                logger.error("Error while getting IFile from PPA", e);
            }
        }

        for (IFile file : iFiles) {
            logger.info("Getting CU for file: " + file.getLocation().toOSString());
            CompilationUnit cu = getCU(file, options);
            if (cu == null) {
                cu = getCUNoPPA(file);
            }
            cus.add(cu);
        }

        return cus;
    }

    /**
     * <p>
     * </p>
     * 
     * @param units
     * @return
     */
    public List<CompilationUnit> getCUsWithOnePPAPass(List<ICompilationUnit> units) {

        if (units.size() == 0)
            return new ArrayList<CompilationUnit>();

        final List<CompilationUnit> astList = new ArrayList<CompilationUnit>();
        try {

            // FIXME a hack to get the current project.
            JavaProject jproject = (JavaProject) JavaCore.create(units.get(0).getUnderlyingResource().getProject());
            PPATypeRegistry registry = new PPATypeRegistry(jproject);
            final PPAEngine ppaEngine = new PPAEngine(registry, new PPAOptions());

            PPAASTParser parser2 = new PPAASTParser(AST.JLS3);
            parser2.setStatementsRecovery(true);
            parser2.setResolveBindings(true);
            parser2.setProject((IJavaProject) jproject);

            ASTRequestor requestor = new ASTRequestor() {

                @Override
                public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
                    astList.add(ast);
                    ppaEngine.addUnitToProcess(ast);
                }
            };

            parser2.createASTs(units.toArray(new ICompilationUnit[units.size()]), new String[0], requestor, null);

            ppaEngine.doPPA();
            ppaEngine.reset();

        } catch (JavaModelException jme) {
            jme.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return astList;
    }

    public static ASTNode getNode(IFile file, PPAOptions options, int kind) {
        ASTNode node = null;
        try {
            ICompilationUnit icu = JavaCore.createCompilationUnitFrom(file);
            PPATypeRegistry registry = new PPATypeRegistry(
                    (JavaProject) JavaCore.create(icu.getUnderlyingResource().getProject()));
            PPAASTParser parser2 = new PPAASTParser(AST.JLS3);
            parser2.setStatementsRecovery(true);
            parser2.setResolveBindings(true);
            parser2.setSource(icu);
            parser2.setKind(kind);
            node = parser2.createAST(null);
            PPAEngine ppaEngine = new PPAEngine(registry, options);

            ppaEngine.addUnitToProcess(node);
            ppaEngine.doPPA();
            ppaEngine.reset();
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }

        return node;
    }

    public static String getPackageFromFile(File file) throws IOException {
        String packageName = "";
        PPAASTParser parser2 = new PPAASTParser(AST.JLS3);
        parser2.setStatementsRecovery(true);
        parser2.setResolveBindings(true);
        parser2.setSource(PPAResourceUtil.getContent(file).toCharArray());
        CompilationUnit cu = (CompilationUnit) parser2.createAST(null);
        PackageDeclaration pDec = cu.getPackage();
        if (pDec != null) {
            packageName = pDec.getName().getFullyQualifiedName();
        }
        return packageName;
    }

    public static String getPPAProjectName(String requestName) {
        PPAUIActivator activator = PPAUIActivator.getDefault();
        String projectName = activator.getPreferenceStore().getString(PPAPreferenceConstants.PPA_PROJECT_PREF);

        projectName += activator.acquireId(requestName);

        return projectName;
    }

    public static ASTNode getSnippet(File file, PPAOptions options, boolean isTypeBody) {
        return getSnippet(file, options, isTypeBody, Thread.currentThread().getName());
    }

    public static ASTNode getSnippet(File file, PPAOptions options, boolean isTypeBody, String requestName) {
        CompilationUnit cu = null;
        try {
            String ppaProjectName = getPPAProjectName(requestName);
            PPAJavaProjectHelper helper = new PPAJavaProjectHelper();
            IJavaProject javaProject = helper.setupJavaProject(ppaProjectName);
            IFile newFile = PPAResourceUtil.copyJavaSourceFileSnippet(javaProject.getProject(), file,
                    SnippetUtil.SNIPPET_PACKAGE, SnippetUtil.SNIPPET_FILE, isTypeBody);
            cu = getCU(newFile, options);
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }

        return cu;
    }

    public static ASTNode getSnippet(String codeSnippet, PPAOptions options, boolean isTypeBody) {
        return getSnippet(codeSnippet, options, isTypeBody, Thread.currentThread().getName());
    }

    public static ASTNode getSnippet(String codeSnippet, PPAOptions options, boolean isTypeBody,
            String requestName) {
        CompilationUnit cu = null;
        try {
            String ppaProjectName = getPPAProjectName(requestName);
            PPAJavaProjectHelper helper = new PPAJavaProjectHelper();
            IJavaProject javaProject = helper.setupJavaProject(ppaProjectName);
            IFile newFile = PPAResourceUtil.copyJavaSourceFileSnippet(javaProject.getProject(), codeSnippet,
                    SnippetUtil.SNIPPET_PACKAGE, SnippetUtil.SNIPPET_FILE, isTypeBody);
            cu = getCU(newFile, options);
        } catch (Exception e) {
            logger.error("Error while getting CU from PPA", e);
        }

        return cu;
    }

}