Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2005, 2006 Richard Hoefter 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: Richard Hoefter (richard.hoefter@web.de) - initial API and implementation IBM Corporation - incorporating into Eclipse /
 
 
 package org.eclipse.ant.internal.ui.datatransfer;
 
 import java.io.File;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import  org.eclipse.swt.widgets.Shell;

Provides a method to analyze sources if it is possible to export projects to an Ant buildfile which compiles correctly.
 
 public class SourceAnalyzer {
    
    
Utility class.
 
     private SourceAnalyzer() {
 
     }

    
Check if source directories of project has cycles or if there are dependencies between them that are not conform with classpath order.

NOTE: Unused references in classes are not considered if they cause cycles or classpath order problems. This is because this class analyzes the bytecode and indeed the compiler throws unused references away.

 
     public static void checkCycles(IJavaProject currentProject,
             EclipseClasspath classpath, Shell shell) {
 
         StringBuffer message = new StringBuffer();
         Map src2dir = new TreeMap(); // map string to string
         Map srcdir2classes = new TreeMap(); // map string to Set of strings
 
         determineSources(currentProjectclasspathsrc2dirsrcdir2classes);
 
         Map srcdir2sourcedirs = determineRequiredSrcDirs(src2dir,
                 srcdir2classes);
         String projectName = currentProject.getProject().getName();
 
         List cycle = new ArrayList();
         if (isCyclic(srcdir2sourcedirscycle)) {
             showCycleWarning(projectNameshellcyclemessage);
             return;
         }
 
         checkBuildOrder(classpathprojectNameshellsrcdir2sourcedirs);
     }

    
Determine all sources belonging to a source directory.
 
     private static void determineSources(IJavaProject currentProject,
             EclipseClasspath classpathMap src2dirMap srcdir2classes) {
 
         for (int i = 0; i < classpath.srcDirs.size(); i++) {
             String srcDir = (Stringclasspath.srcDirs.get(i);
             String classDir = (Stringclasspath.classDirs.get(i);
             if (EclipseClasspath.isReference(srcDir)) {
                 continue;
             }
             File dir;
             if (srcDir.equals(".")) { //$NON-NLS-1$
                 dir = currentProject.getResource().getLocation().toFile();
             } else {
                 IFile file = currentProject.getProject().getFile(srcDir);
                 dir = file.getLocation().toFile();
             }
            if (EclipseClasspath.isLinkedResource(srcDir)) {
                String link = classpath.resolveLinkedResource(srcDir);
                dir = new File(link);
            }
            Set sources = findFiles(dir".java"); //$NON-NLS-1$
            // find all required classfiles for each source directory
            for (Iterator iter = sources.iterator(); iter.hasNext();) {
                String srcFile = (Stringiter.next();
                src2dir.put(srcFilesrcDir);
                IFile classFile = currentProject.getProject().getFile(
                        classDir + '/' + srcFile + ".class"); //$NON-NLS-1$
                if (!classFile.exists()) {
                    // project was not compiled, check not possible
                    continue;
                }
                Set classes = (Setsrcdir2classes.get(srcDir);
                if (classes == null) {
                    classes = new TreeSet();
                }
                classes.addAll(getRequiredClasses(classFile));
                srcdir2classes.put(srcDirclasses);
            }
        }
    }

    
Determine for each source directory which other source directories it requires.

Returns:
Map string to Set of strings. (Maps source dir to Set of required source dirs.)
    private static Map determineRequiredSrcDirs(Map src2dirMap srcdir2classes) {
        Map srcdir2sourcedirs = new TreeMap(); // map string to Set of strings
        for (Iterator iter = srcdir2classes.keySet().iterator(); iter.hasNext();) {
            String srcDir = (Stringiter.next();
            Set classes = (Setsrcdir2classes.get(srcDir);
            for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
                String classname = (Stringiterator.next();
                String classsrc = (Stringsrc2dir.get(classname);
                // don't add reference to itself
                if (classsrc != null && !classsrc.equals(srcDir)) {
                    Set sourcedirs = (Setsrcdir2sourcedirs.get(srcDir);
                    if (sourcedirs == null) {
                        sourcedirs = new TreeSet();
                    }
                    sourcedirs.add(classsrc);
                    srcdir2sourcedirs.put(srcDirsourcedirs);
                }
            }
        }
        return srcdir2sourcedirs;
    }
    private static void showCycleWarning(String projectName, Shell shell,
            List cycleStringBuffer message) {
        String m = MessageFormat.format(.,
                new String[] { projectName });
        message.append(m);
        message.append(.);
        // print cycle path
        for (Iterator iter = cycle.iterator(); iter.hasNext();) {
            String s = (Stringiter.next();
            s = EclipseClasspath.getLinkedResourceName(s);
            message.append(s);
            message.append(" -> "); //$NON-NLS-1$
        }
        message.append(EclipseClasspath.getLinkedResourceName((Stringcycle
                .get(0)));
        MessageDialog.openWarning(shell.,
                message.toString());
    }

    
Check if build order is correct.
    private static void checkBuildOrder(EclipseClasspath classpath,
            String projectName, Shell shellMap srcdir2sourcedirs) {
        for (Iterator iter = srcdir2sourcedirs.keySet().iterator(); iter
                .hasNext();) {
            String srcdir = (Stringiter.next();
            Set sourcedirs = (Setsrcdir2sourcedirs.get(srcdir);
            int classpathIndex = classpath.srcDirs.indexOf(srcdir);
            for (Iterator iterator = sourcedirs.iterator(); iterator.hasNext();) {
                String requiredSrc = (Stringiterator.next();
                int i = classpath.srcDirs.indexOf(requiredSrc);
                if (i > classpathIndex// wrong order
                {
                    String s = MessageFormat.format(
                            .,
                            new String[] { projectName });
                    MessageDialog.openWarning(shell,
                            .s
                                    + . + requiredSrc
                                    + " <-> " + srcdir //$NON-NLS-1$
                                    + .);
                    break;
                }
            }
        }
    }

    
Find all classes that are required by given class file.

Parameters:
file a ".class" file
Returns:
set of strings, each contains a full qualified classname (forward slash as package separator)
    public static Set getRequiredClasses(IFile file) {
        Set classes = new TreeSet();
        IClassFile classFile = JavaCore.createClassFileFrom(file);
        IClassFileReader reader = ToolFactory.createDefaultClassFileReader(
                classFile.);
        if (reader == null) {
            // class not compiled
            return classes;
        }
        IConstantPool pool = reader.getConstantPool();
        for (int i = 0; i < pool.getConstantPoolCount(); i++) {
            if (pool.getEntryKind(i) == .) {
                IConstantPoolEntry entry = pool.decodeEntry(i);
                String classname = new String(entry.getClassInfoName());
                // don't return inner classes
                int index = classname.indexOf('$');
                if (index != -1) {
                    classname = classname.substring(0, index);
                }
                classes.add(classname);
            }
        }
        return classes;
    }

    
Find all files with particular extension under given directory.

Parameters:
dir directory to start search
extension extension to search
Returns:
filenames relative to dir (without extension and with forward slashes)
    public static Set findFiles(File dirString extension) {
        Set visited = new TreeSet();
        findFiles(dirdirextensionvisited);
        return visited;
    }
    private static void findFiles(File baseFile dirString extension,
            Set visited) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            for (int i = 0; i < children.lengthi++) {
                findFiles(basechildren[i], extensionvisited);
            }
        } else if (dir.getAbsolutePath().endsWith(extension)) {
            // remove base directory
            String filename = ExportUtil.removePrefixAndSuffix(dir
                    .getAbsolutePath(),
                    base.getAbsolutePath() + .extension);
            visited.add(filename.replace('\\''/'));
        }
    }

    
Check if given graph that is described through a map is cyclic.

Parameters:
srcdir2sourcedirs Maps string to set of strings. The keys are the graph nodes which are mapped to its neighbours.
cycle filled with name of nodes which cause cycle
    private static boolean isCyclic(Map srcdir2sourcedirsList cycle) {
        return !isAcyclic(srcdir2sourcedirscycle);
    }
    private static boolean isAcyclic(Map srcdir2sourcedirsList cycle) {
        // standard graph theory
        List visited = new ArrayList();
        List exited = new ArrayList();
        for (Iterator iter = srcdir2sourcedirs.keySet().iterator(); iter
                .hasNext();) {
            String srcdir = (Stringiter.next();
            if (!visited.contains(srcdir)) {
                if (circleSearch(srcdirsrcdir2sourcedirsvisitedexited,
                        cycle)) {
                    return false;
                }
            }
        }
        return true;
    }
    private static boolean circleSearch(String srcdirMap srcdir2sourcedirs,
            List visitedList exitedList cycle) {
        boolean res = false;
        visited.add(srcdir);
        cycle.add(srcdir);
        Set sourcedirs = (Setsrcdir2sourcedirs.get(srcdir); // neighbours
        if (sourcedirs != null) {
            for (Iterator iter = sourcedirs.iterator(); iter.hasNext();) {
                String src = (Stringiter.next();
                if (!visited.contains(src)) {
                    res = circleSearch(srcsrcdir2sourcedirsvisitedexited,
                            cycle);
                } else if (!exited.contains(src)) {
                    res = true;
                }
                if (res) {
                    break;
                }
            }
        }
        if (!res) {
            cycle.clear();
        }
        exited.add(srcdir);
        return res;
    }
New to GrepCode? Check out our FAQ X