FileDocCategorySizeDatePackage
ProjectHelper.javaAPI DocAndroid 1.5 API29958Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.adt.project

ProjectHelper

public final class ProjectHelper extends Object
Utility class to manipulate Project parameters/properties.

Fields Summary
public static final int
COMPILER_COMPLIANCE_OK
public static final int
COMPILER_COMPLIANCE_LEVEL
public static final int
COMPILER_COMPLIANCE_SOURCE
public static final int
COMPILER_COMPLIANCE_CODEGEN_TARGET
Constructors Summary
Methods Summary
public static org.eclipse.jdt.core.IClasspathEntry[]addEntryToClasspath(org.eclipse.jdt.core.IClasspathEntry[] entries, org.eclipse.jdt.core.IClasspathEntry new_entry)
Adds the corresponding source folder to the class path entries.

param
entries The class path entries to read. A copy will be returned.
param
new_entry The parent source folder to remove.
return
A new class path entries array.


                                               
       
                
        int n = entries.length;
        IClasspathEntry[] newEntries = new IClasspathEntry[n + 1];
        System.arraycopy(entries, 0, newEntries, 0, n);
        newEntries[n] = new_entry;
        return newEntries;
    
public static final voidcheckAndFixCompilerCompliance(org.eclipse.core.resources.IProject project)
Checks, and fixes if needed, the compiler compliance level, and the source compatibility level

param
project The project to check and fix.

        // get the java project from the IProject resource object
        IJavaProject javaProject = JavaCore.create(project);

        // Now we check the compiler compliance level and make sure it is valid
        checkAndFixCompilerCompliance(javaProject);
    
public static final voidcheckAndFixCompilerCompliance(org.eclipse.jdt.core.IJavaProject javaProject)
Checks, and fixes if needed, the compiler compliance level, and the source compatibility level

param
javaProject The Java project to check and fix.

        if (checkCompilerCompliance(javaProject) != COMPILER_COMPLIANCE_OK) {
            // setup the preferred compiler compliance level.
            javaProject.setOption(JavaCore.COMPILER_COMPLIANCE,
                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);
            javaProject.setOption(JavaCore.COMPILER_SOURCE,
                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);
            javaProject.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);

            // clean the project to make sure we recompile
            try {
                javaProject.getProject().build(IncrementalProjectBuilder.CLEAN_BUILD,
                        new NullProgressMonitor());
            } catch (CoreException e) {
                AdtPlugin.printErrorToConsole(javaProject.getProject(),
                        "Project compiler settings changed. Clean your project.");
            }
        }
    
public static final intcheckCompilerCompliance(org.eclipse.jdt.core.IJavaProject javaProject)
Checks the project compiler compliance level is supported.

param
javaProject The project to check
return
  • COMPILER_COMPLIANCE_OK if the project is properly configured
  • COMPILER_COMPLIANCE_LEVEL for unsupported compiler level
  • COMPILER_COMPLIANCE_SOURCE for unsupported source compatibility
  • COMPILER_COMPLIANCE_CODEGEN_TARGET for unsupported .class format

        // get the project compliance level option
        String compliance = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);

        // check it against a list of valid compliance level strings.
        if (checkCompliance(compliance) == false) {
            // if we didn't find the proper compliance level, we return an error
            return COMPILER_COMPLIANCE_LEVEL;
        }

        // otherwise we check source compatibility
        String source = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);

        // check it against a list of valid compliance level strings.
        if (checkCompliance(source) == false) {
            // if we didn't find the proper compliance level, we return an error
            return COMPILER_COMPLIANCE_SOURCE;
        }

        // otherwise check codegen level
        String codeGen = javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);

        // check it against a list of valid compliance level strings.
        if (checkCompliance(codeGen) == false) {
            // if we didn't find the proper compliance level, we return an error
            return COMPILER_COMPLIANCE_CODEGEN_TARGET;
        }

        return COMPILER_COMPLIANCE_OK;
    
public static final intcheckCompilerCompliance(org.eclipse.core.resources.IProject project)
Checks the project compiler compliance level is supported.

param
project The project to check
return
  • COMPILER_COMPLIANCE_OK if the project is properly configured
  • COMPILER_COMPLIANCE_LEVEL for unsupported compiler level
  • COMPILER_COMPLIANCE_SOURCE for unsupported source compatibility
  • COMPILER_COMPLIANCE_CODEGEN_TARGET for unsupported .class format

        // get the java project from the IProject resource object
        IJavaProject javaProject = JavaCore.create(project);

        // check and return the result.
        return checkCompilerCompliance(javaProject);
    
private static booleancheckCompliance(java.lang.String optionValue)
Checks a Java project compiler level option against a list of supported versions.

param
optionValue the Compiler level option.
return
true if the option value is supproted.

        for (String s : AndroidConstants.COMPILER_COMPLIANCE) {
            if (s != null && s.equals(optionValue)) {
                return true;
            }
        }

        return false;
    
public static org.eclipse.core.resources.IProjectfindAndroidProjectByAppName(java.lang.String applicationName)
Returns a {@link IProject} by its running application name, as it returned by the AVD.

applicationName will in most case be the package declared in the manifest, but can, in some cases, be a custom process name declared in the manifest, in the application, activity, receiver, or service nodes.

param
applicationName The application name.
return
a project or null if no matching project were found.

        // Get the list of project for the current workspace
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IProject[] projects = workspace.getRoot().getProjects();
        
        // look for a project that matches the packageName of the app
        // we're trying to debug
        for (IProject p : projects) {
            if (p.isOpen()) {
                try {
                    if (p.hasNature(AndroidConstants.NATURE) == false) {
                        // ignore non android projects
                        continue;
                    }
                } catch (CoreException e) {
                    // failed to get the nature? skip project.
                    continue;
                }

                // check that there is indeed a manifest file.
                IFile manifestFile = AndroidManifestParser.getManifest(p);
                if (manifestFile == null) {
                    // no file? skip this project.
                    continue;
                }

                AndroidManifestParser parser = null;
                try {
                    parser = AndroidManifestParser.parseForData(manifestFile);
                } catch (CoreException e) {
                    // ignore, handled below.
                }
                if (parser == null) {
                    // skip this project.
                    continue;
                }

                String manifestPackage = parser.getPackage();

                if (manifestPackage != null && manifestPackage.equals(applicationName)) {
                    // this is the project we were looking for!
                    return p;
                } else {
                    // if the package and application name don't match,
                    // we look for other possible process names declared in the manifest.
                    String[] processes = parser.getProcesses();
                    for (String process : processes) {
                        if (process.equals(applicationName)) {
                            return p;
                        }
                    }
                }
            }
        }

        return null;

    
public static intfindClasspathEntryByName(org.eclipse.jdt.core.IClasspathEntry[] entries, java.lang.String entryName, int entryKind, int startIndex)
Look for a specific classpath entry for file name only and return its index.

param
entries The entry array to search in.
param
entryName The filename of the entry.
param
entryKind The kind of the entry. Accepted values are 0 (no filter), IClasspathEntry.CPE_LIBRARY, IClasspathEntry.CPE_PROJECT, IClasspathEntry.CPE_SOURCE, IClasspathEntry.CPE_VARIABLE, and IClasspathEntry.CPE_CONTAINER
param
startIndex Index where to start the search
return
the index of the found classpath entry or -1.

        if (startIndex < 0) {
            startIndex = 0;
        }
        for (int i = startIndex ; i < entries.length ; i++) {
            IClasspathEntry entry = entries[i];

            int kind = entry.getEntryKind();

            if (kind == entryKind || entryKind == 0) {
                // get the path
                IPath path = entry.getPath();
                String name = path.segment(path.segmentCount()-1);

                if (name.equals(entryName)) {
                    return i;
                }
            }
        }

        // not found, return bad index.
        return -1;
    
public static intfindClasspathEntryByPath(org.eclipse.jdt.core.IClasspathEntry[] entries, java.lang.String entryPath, int entryKind)
Look for a specific classpath entry by full path and return its index.

param
entries The entry array to search in.
param
entryPath The OS specific path of the entry.
param
entryKind The kind of the entry. Accepted values are 0 (no filter), IClasspathEntry.CPE_LIBRARY, IClasspathEntry.CPE_PROJECT, IClasspathEntry.CPE_SOURCE, IClasspathEntry.CPE_VARIABLE, and IClasspathEntry.CPE_CONTAINER
return
the index of the found classpath entry or -1.

        for (int i = 0 ; i < entries.length ; i++) {
            IClasspathEntry entry = entries[i];

            int kind = entry.getEntryKind();

            if (kind == entryKind || entryKind == 0) {
                // get the path
                IPath path = entry.getPath();

                String osPathString = path.toOSString();
                if (osPathString.equals(entryPath)) {
                    return i;
                }
            }
        }

        // not found, return bad index.
        return -1;
    
public static voidfixProject(org.eclipse.core.resources.IProject project)
Fix the project. This checks the SDK location.

param
project The project to fix.
throws
JavaModelException

        if (AdtPlugin.getOsSdkFolder().length() == 0) {
            AdtPlugin.printToConsole(project, "Unknown SDK Location, project not fixed.");
            return;
        }
        
        // get a java project
        IJavaProject javaProject = JavaCore.create(project);
        fixProjectClasspathEntries(javaProject);
    
public static voidfixProjectClasspathEntries(org.eclipse.jdt.core.IJavaProject javaProject)
Fix the project classpath entries. The method ensures that:
  • The project does not reference any old android.zip/android.jar archive.
  • The project does not use its output folder as a sourc folder.
  • The project does not reference a desktop JRE
  • The project references the AndroidClasspathContainer.

param
javaProject The project to fix.
throws
JavaModelException


        // get the project classpath
        IClasspathEntry[] entries = javaProject.getRawClasspath();
        IClasspathEntry[] oldEntries = entries;

        // check if the JRE is set as library
        int jreIndex = ProjectHelper.findClasspathEntryByPath(entries, JavaRuntime.JRE_CONTAINER,
                IClasspathEntry.CPE_CONTAINER);
        if (jreIndex != -1) {
            // the project has a JRE included, we remove it
            entries = ProjectHelper.removeEntryFromClasspath(entries, jreIndex);
        }

        // get the output folder
        IPath outputFolder = javaProject.getOutputLocation();
        
        boolean foundContainer = false;

        for (int i = 0 ; i < entries.length ;) {
            // get the entry and kind
            IClasspathEntry entry = entries[i];
            int kind = entry.getEntryKind();

            if (kind == IClasspathEntry.CPE_SOURCE) {
                IPath path = entry.getPath();
                
                if (path.equals(outputFolder)) {
                    entries = ProjectHelper.removeEntryFromClasspath(entries, i);
                    
                    // continue, to skip the i++;
                    continue;
                }
            } else if (kind == IClasspathEntry.CPE_CONTAINER) {
                if (AndroidClasspathContainerInitializer.checkPath(entry.getPath())) {
                    foundContainer = true;
                }
            }
            
            i++;
        }

        // if the framework container is not there, we add it
        if (foundContainer == false) {
            // add the android container to the array
            entries = ProjectHelper.addEntryToClasspath(entries,
                    AndroidClasspathContainerInitializer.getContainerEntry());
        }

        // set the new list of entries to the project
        if (entries != oldEntries) {
            javaProject.setRawClasspath(entries, new NullProgressMonitor());
        }

        // If needed, check and fix compiler compliance and source compatibility
        ProjectHelper.checkAndFixCompilerCompliance(javaProject);
    
public static voidfixProjectNatureOrder(org.eclipse.core.resources.IProject project)

        IProjectDescription description = project.getDescription();
        String[] natures = description.getNatureIds();
        
        // if the android nature is not the first one, we reorder them
        if (AndroidConstants.NATURE.equals(natures[0]) == false) {
            // look for the index
            for (int i = 0 ; i < natures.length ; i++) {
                if (AndroidConstants.NATURE.equals(natures[i])) {
                    // if we try to just reorder the array in one pass, this doesn't do 
                    // anything. I guess JDT check that we are actually adding/removing nature.
                    // So, first we'll remove the android nature, and then add it back.

                    // remove the android nature
                    removeNature(project, AndroidConstants.NATURE);
                    
                    // now add it back at the first index.
                    description = project.getDescription();
                    natures = description.getNatureIds();
                    
                    String[] newNatures = new String[natures.length + 1];

                    // first one is android
                    newNatures[0] = AndroidConstants.NATURE;
                    
                    // next the rest that was before the android nature
                    System.arraycopy(natures, 0, newNatures, 1, natures.length);
                    
                    // set the new natures
                    description.setNatureIds(newNatures);
                    project.setDescription(description, null);

                    // and stop
                    break;
                }
            }
        }
    
public static java.util.ListgetAndroidProjectDependencies(org.eclipse.jdt.core.IJavaProject javaProject)
Find the list of projects on which this JavaProject is dependent on at the compilation level.

param
javaProject Java project that we are looking for the dependencies.
return
A list of Java projects for which javaProject depend on.
throws
JavaModelException

        String[] requiredProjectNames = javaProject.getRequiredProjectNames();
    
        // Go from java project name to JavaProject name
        IJavaModel javaModel = javaProject.getJavaModel();
    
        // loop through all dependent projects and keep only those that are Android projects
        List<IJavaProject> projectList = new ArrayList<IJavaProject>(requiredProjectNames.length);
        for (String javaProjectName : requiredProjectNames) {
            IJavaProject androidJavaProject = javaModel.getJavaProject(javaProjectName);
            
            //Verify that the project has also the Android Nature
            try {
                if (!androidJavaProject.getProject().hasNature(AndroidConstants.NATURE)) {
                    continue;
                }
            } catch (CoreException e) {
                continue;
            }
            
            projectList.add(androidJavaProject);
        }
        
        return projectList;
    
public static java.lang.StringgetApkFilename(org.eclipse.core.resources.IProject project, java.lang.String config)
Returns the apk filename for the given project

param
project The project.
param
config An optional config name. Can be null.

        if (config != null) {
            return project.getName() + "-" + config + AndroidConstants.DOT_ANDROID_PACKAGE; //$NON-NLS-1$ 
        }
        
        return project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
    
public static org.eclipse.core.resources.IFilegetApplicationPackage(org.eclipse.core.resources.IProject project)
Returns the android package file as an IFile object for the specified project.

param
project The project
return
The android package as an IFile object or null if not found.

        // get the output folder
        IFolder outputLocation = BaseProjectHelper.getOutputFolder(project);
    
        if (outputLocation == null) {
            AdtPlugin.printErrorToConsole(project,
                    "Failed to get the output location of the project. Check build path properties"
                    );
            return null;
        }
        
    
        // get the package path
        String packageName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
        IResource r = outputLocation.findMember(packageName);
    
        // check the package is present
        if (r instanceof IFile && r.exists()) {
            return (IFile)r;
        }
    
        String msg = String.format("Could not find %1$s!", packageName);
        AdtPlugin.printErrorToConsole(project, msg);
    
        return null;
    
public static java.lang.StringgetJavaDocPath(java.lang.String javaDocOSLocation)
Converts a OS specific path into a path valid for the java doc location attributes of a project.

param
javaDocOSLocation The OS specific path.
return
a valid path for the java doc location.

        // first thing we do is convert the \ into /
        String javaDoc = javaDocOSLocation.replaceAll("\\\\", //$NON-NLS-1$
                AndroidConstants.WS_SEP);

        // then we add file: at the beginning for unix path, and file:/ for non
        // unix path
        if (javaDoc.startsWith(AndroidConstants.WS_SEP)) {
            return "file:" + javaDoc; //$NON-NLS-1$
        }

        return "file:/" + javaDoc; //$NON-NLS-1$
    
public static org.eclipse.core.resources.IProject[]getReferencedProjects(org.eclipse.core.resources.IProject project)
Returns the list of referenced project that are opened and Java projects.

param
project
return
list of opened referenced java project.
throws
CoreException

        IProject[] projects = project.getReferencedProjects();
        
        ArrayList<IProject> list = new ArrayList<IProject>();
        
        for (IProject p : projects) {
            if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) {
                list.add(p);
            }
        }

        return list.toArray(new IProject[list.size()]);
    
public static booleanhasError(org.eclipse.core.resources.IProject project, boolean includeReferencedProjects)
Returns if the project has error level markers.

param
includeReferencedProjects flag to also test the referenced projects.
throws
CoreException

        IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
        if (markers != null && markers.length > 0) {
            // the project has marker(s). even though they are "problem" we
            // don't know their severity. so we loop on them and figure if they
            // are warnings or errors
            for (IMarker m : markers) {
                int s = m.getAttribute(IMarker.SEVERITY, -1);
                if (s == IMarker.SEVERITY_ERROR) {
                    return true;
                }
            }
        }
        
        // test the referenced projects if needed.
        if (includeReferencedProjects) {
            IProject[] projects = getReferencedProjects(project);
            
            for (IProject p : projects) {
                if (hasError(p, false)) {
                    return true;
                }
            }
        }

        return false;
    
public static booleanloadBooleanProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName, boolean defaultValue)
Loads a boolean property from the persistent storage of the project.

param
resource The resource from which the boolean value is loaded.
param
propertyName the name of the property. The id of the plugin is added to this string.
param
defaultValue The default value to return if the property was not found.
return
the property value or the default value if the property was not found.

        String value = loadStringProperty(resource, propertyName);
        if (value != null) {
            return Boolean.parseBoolean(value);
        }

        return defaultValue;
    
public static org.eclipse.core.resources.IResourceloadResourceProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName)
Loads the path of a resource from the persistent storage of the project, and returns the corresponding IResource object, if it exists in the same project as resource.

param
resource The resource from which the resource path is loaded.
param
propertyName the name of the property. The id of the plugin is added to this string.
return
The corresponding IResource object (or children interface) or null

        String value = loadStringProperty(resource, propertyName);

        if (value != null && value.length() > 0) {
            return resource.getProject().findMember(value);
        }

        return null;
    
public static java.lang.StringloadStringProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName)
Loads a String property from the persistent storage of a resource.

param
resource The resource from which the string value is loaded.
param
propertyName the name of the property. The id of the plugin is added to this string.
return
the property value or null if it was not found.

        QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID, propertyName);

        try {
            String value = resource.getPersistentProperty(qname);
            return value;
        } catch (CoreException e) {
            return null;
        }
    
public static org.eclipse.jdt.core.IClasspathEntry[]removeEntryFromClasspath(org.eclipse.jdt.core.IClasspathEntry[] entries, int index)
Remove a classpath entry from the array.

param
entries The class path entries to read. A copy will be returned
param
index The index to remove.
return
A new class path entries array.

        int n = entries.length;
        IClasspathEntry[] newEntries = new IClasspathEntry[n-1];

        // copy the entries before index
        System.arraycopy(entries, 0, newEntries, 0, index);

        // copy the entries after index
        System.arraycopy(entries, index + 1, newEntries, index,
                entries.length - index - 1);

        return newEntries;
    
public static voidremoveNature(org.eclipse.core.resources.IProject project, java.lang.String nature)
Removes a specific nature from a project.

param
project The project to remove the nature from.
param
nature The nature id to remove.
throws
CoreException

        IProjectDescription description = project.getDescription();
        String[] natures = description.getNatureIds();

        // check if the project already has the android nature.
        for (int i = 0; i < natures.length; ++i) {
            if (nature.equals(natures[i])) {
                String[] newNatures = new String[natures.length - 1];
                if (i > 0) {
                    System.arraycopy(natures, 0, newNatures, 0, i);
                }
                System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
                description.setNatureIds(newNatures);
                project.setDescription(description, null);

                return;
            }
        }

    
public static booleansaveBooleanProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName, boolean value)
Saves a property into the persistent storage of a resource.

param
resource The resource into which the boolean value is saved.
param
propertyName the name of the property. The id of the plugin is added to this string.
param
value the value to save
return
true if the save succeeded.

        return saveStringProperty(resource, propertyName, Boolean.toString(value));
    
public static booleansaveResourceProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName, org.eclipse.core.resources.IResource value)
Saves the path of a resource into the persistent storate of the project.

param
resource The resource into which the resource path is saved.
param
propertyName the name of the property. The id of the plugin is added to this string.
param
value The resource to save. It's its path that is actually stored. If null, an empty string is stored.
return
true if the save succeeded

        if (value != null) {
            IPath iPath = value.getProjectRelativePath();
            return saveStringProperty(resource, propertyName, iPath.toString());
        }

        return saveStringProperty(resource, propertyName, ""); //$NON-NLS-1$
    
public static booleansaveStringProperty(org.eclipse.core.resources.IResource resource, java.lang.String propertyName, java.lang.String value)
Saves a String property into the persistent storage of a resource.

param
resource The resource into which the string value is saved.
param
propertyName the name of the property. The id of the plugin is added to this string.
param
value the value to save
return
true if the save succeeded.

        QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID, propertyName);

        try {
            resource.setPersistentProperty(qname, value);
        } catch (CoreException e) {
            return false;
        }

        return true;