FileDocCategorySizeDatePackage
Sdk.javaAPI DocAndroid 1.5 API19377Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.adt.sdk

Sdk

public class Sdk extends Object implements com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener
Central point to load, manipulate and deal with the Android SDK. Only one SDK can be used at the same time. To start using an SDK, call {@link #loadSdk(String)} which returns the instance of the Sdk object. To get the list of platforms or add-ons present in the SDK, call {@link #getTargets()}.

Fields Summary
private static Sdk
sCurrentSdk
private final com.android.sdklib.SdkManager
mManager
private final com.android.sdklib.avd.AvdManager
mAvdManager
private final HashMap
mProjectTargetMap
private final HashMap
mTargetDataMap
private final HashMap
mProjectApkConfigMap
private final String
mDocBaseUrl
Constructors Summary
private Sdk(com.android.sdklib.SdkManager manager, com.android.sdklib.avd.AvdManager avdManager)

        mManager = manager;
        mAvdManager = avdManager;
        
        // listen to projects closing
        ResourceMonitor monitor = ResourceMonitor.getMonitor();
        monitor.addProjectListener(this);
        
        // pre-compute some paths
        mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
                SdkConstants.OS_SDK_DOCS_FOLDER);
    
Methods Summary
private voiddispose()
Cleans and unloads the SDK.

        ResourceMonitor.getMonitor().removeProjectListener(this);
    
public com.android.sdklib.avd.AvdManagergetAvdManager()
Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could be null.

        return mAvdManager;
    
public static com.android.ide.eclipse.adt.sdk.SdkgetCurrent()
Returns the current {@link Sdk} object.

        return sCurrentSdk;
    
private java.lang.StringgetDocumentationBaseUrl(java.lang.String osDocsPath)
Returns the URL to the local documentation. Can return null if no documentation is found in the current SDK.

param
osDocsPath Path to the documentation folder in the current SDK. The folder may not actually exist.
return
A file:// URL on the local documentation folder if it exists or null.

        File f = new File(osDocsPath);

        if (f.isDirectory()) {
            try {
                // Note: to create a file:// URL, one would typically use something like
                // f.toURI().toURL().toString(). However this generates a broken path on
                // Windows, namely "C:\\foo" is converted to "file:/C:/foo" instead of
                // "file:///C:/foo" (i.e. there should be 3 / after "file:"). So we'll
                // do the correct thing manually.
                
                String path = f.getAbsolutePath();
                if (File.separatorChar != '/") {
                    path = path.replace(File.separatorChar, '/");
                }
                
                // For some reason the URL class doesn't add the mandatory "//" after
                // the "file:" protocol name, so it has to be hacked into the path.
                URL url = new URL("file", null, "//" + path);  //$NON-NLS-1$ //$NON-NLS-2$
                String result = url.toString();
                return result;
            } catch (MalformedURLException e) {
                // ignore malformed URLs
            }
        }

        return null;
    
public java.lang.StringgetDocumentationBaseUrl()
Returns the URL to the local documentation. Can return null if no documentation is found in the current SDK.

return
A file:// URL on the local documentation folder if it exists or null.

        return mDocBaseUrl;
    
public java.util.MapgetProjectApkConfigs(org.eclipse.core.resources.IProject project)
Returns the configuration map for a given project.

The Map key are name to be used in the apk filename, while the values are comma separated config values. The config value can be passed directly to aapt through the -c option.

        return mProjectApkConfigMap.get(project);
    
public static java.lang.StringgetProjectTargetHashString(org.eclipse.core.resources.IProject project)
Returns the hash string uniquely identifying the target of a project.

This methods reads the content of the default.properties file present in the root folder of the project.

The string is equivalent to the return of {@link IAndroidTarget#hashString()}.

param
project The project for which to return the target hash string.
return
the hash string or null if the project does not have a target set.

        return loadProjectProperties(project, null /*storeConfigs*/);
    
public java.lang.StringgetSdkLocation()
Returns the location (OS path) of the current SDK.

        return mManager.getLocation();
    
public com.android.sdklib.IAndroidTargetgetTarget(org.eclipse.core.resources.IProject project)
Returns the {@link IAndroidTarget} object associated with the given {@link IProject}.

        synchronized (mProjectTargetMap) {
            IAndroidTarget target = mProjectTargetMap.get(project);
            if (target == null) {
                // get the value from the project persistent property.
                String targetHashString = loadProjectProperties(project, this);

                if (targetHashString != null) {
                    target = mManager.getTargetFromHashString(targetHashString);
                }
            }

            return target;
        }
    
public AndroidTargetDatagetTargetData(com.android.sdklib.IAndroidTarget target)
Return the {@link AndroidTargetData} for a given {@link IAndroidTarget}.

        synchronized (mTargetDataMap) {
            return mTargetDataMap.get(target);
        }
    
public com.android.sdklib.IAndroidTargetgetTargetFromHashString(java.lang.String hash)
Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.

param
hash the {@link IAndroidTarget} hash string.
return
The matching {@link IAndroidTarget} or null.

        return mManager.getTargetFromHashString(hash);
    
public com.android.sdklib.IAndroidTarget[]getTargets()
Returns the list of targets that are available in the SDK.

        return mManager.getTargets();
    
private static java.lang.StringloadProjectProperties(org.eclipse.core.resources.IProject project, com.android.ide.eclipse.adt.sdk.Sdk sdkStorage)
Parses the project properties and returns the hash string uniquely identifying the target of the given project.

This methods reads the content of the default.properties file present in the root folder of the project.

The returned string is equivalent to the return of {@link IAndroidTarget#hashString()}.

param
project The project for which to return the target hash string.
param
sdkStorage The sdk in which to store the Apk Configs. Can be null.
return
the hash string or null if the project does not have a target set.

        // load the default.properties from the project folder.
        IPath location = project.getLocation();
        if (location == null) {  // can return null when the project is being deleted.
            // do nothing and return null;
            return null;
        }
        ProjectProperties properties = ProjectProperties.load(location.toOSString(),
                PropertyType.DEFAULT);
        if (properties == null) {
            AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'",
                    project.getName());
            return null;
        }
        
        if (sdkStorage != null) {
            Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
            
            if (configMap != null) {
                sdkStorage.mProjectApkConfigMap.put(project, configMap);
            }
        }
        
        return properties.getProperty(ProjectProperties.PROPERTY_TARGET);
    
public static com.android.ide.eclipse.adt.sdk.SdkloadSdk(java.lang.String sdkLocation)
Loads an SDK and returns an {@link Sdk} object if success.

param
sdkLocation the OS path to the SDK.

    
                    
       
                        
          
        
                                    
         
    
    
                            
         
        if (sCurrentSdk != null) {
            sCurrentSdk.dispose();
            sCurrentSdk = null;
        }

        final ArrayList<String> logMessages = new ArrayList<String>();
        ISdkLog log = new ISdkLog() {
            public void error(Throwable throwable, String errorFormat, Object... arg) {
                if (errorFormat != null) {
                    logMessages.add(String.format("Error: " + errorFormat, arg));
                }
                
                if (throwable != null) {
                    logMessages.add(throwable.getMessage());
                }
            }

            public void warning(String warningFormat, Object... arg) {
                logMessages.add(String.format("Warning: " + warningFormat, arg));
            }
            
            public void printf(String msgFormat, Object... arg) {
                logMessages.add(String.format(msgFormat, arg));
            }
        };

        // get an SdkManager object for the location
        SdkManager manager = SdkManager.createManager(sdkLocation, log);
        if (manager != null) {
            AvdManager avdManager = null;
            try {
                avdManager = new AvdManager(manager, log);
            } catch (AndroidLocationException e) {
                log.error(e, "Error parsing the AVDs");
            }
            sCurrentSdk = new Sdk(manager, avdManager);
            return sCurrentSdk;
        } else {
            StringBuilder sb = new StringBuilder("Error Loading the SDK:\n");
            for (String msg : logMessages) {
                sb.append('\n");
                sb.append(msg);
            }
            AdtPlugin.displayError("Android SDK", sb.toString());
        }
        return null;
    
public voidprojectClosed(org.eclipse.core.resources.IProject project)

        // get the target project
        synchronized (mProjectTargetMap) {
            IAndroidTarget target = mProjectTargetMap.get(project);
            if (target != null) {
                // get the bridge for the target, and clear the cache for this project.
                AndroidTargetData data = mTargetDataMap.get(target);
                if (data != null) {
                    LayoutBridge bridge = data.getLayoutBridge();
                    if (bridge != null && bridge.status == LoadStatus.LOADED) {
                        bridge.bridge.clearCaches(project);
                    }
                }
            }
            
            // now remove the project for the maps.
            mProjectTargetMap.remove(project);
            mProjectApkConfigMap.remove(project);
        }
    
public voidprojectDeleted(org.eclipse.core.resources.IProject project)

        projectClosed(project);
    
public voidprojectOpened(org.eclipse.core.resources.IProject project)

        // ignore this. The project will be added to the map the first time the target needs
        // to be resolved.
    
public voidprojectOpenedWithWorkspace(org.eclipse.core.resources.IProject project)

        // ignore this. The project will be added to the map the first time the target needs
        // to be resolved.
    
public voidsetProject(org.eclipse.core.resources.IProject project, com.android.sdklib.IAndroidTarget target, java.util.Map apkConfigMap)
Sets a new target and a new list of Apk configuration for a given project.

param
project the project to receive the new apk configurations
param
target The new target to set, or null to not change the current target.
param
apkConfigMap a map of apk configurations. The map contains (name, filter) where name is the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of resource configuration to include in the apk (see aapt -c). Can be null if the apk configurations should not be updated.

        synchronized (mProjectTargetMap) {
            boolean resolveProject = false;
            boolean compileProject = false;
            boolean cleanProject = false;

            ProjectProperties properties = ProjectProperties.load(
                    project.getLocation().toOSString(), PropertyType.DEFAULT);
            if (properties == null) {
                // doesn't exist yet? we create it.
                properties = ProjectProperties.create(project.getLocation().toOSString(),
                        PropertyType.DEFAULT);
            }

            if (target != null) {
                // look for the current target of the project
                IAndroidTarget previousTarget = mProjectTargetMap.get(project);

                if (target != previousTarget) {
                    // save the target hash string in the project persistent property
                    properties.setAndroidTarget(target);
                    
                    // put it in a local map for easy access.
                    mProjectTargetMap.put(project, target);
                    
                    resolveProject = true;
                }
            }
            
            if (apkConfigMap != null) {
                // save the apk configs in the project persistent property
                cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap);

                // put it in a local map for easy access.
                mProjectApkConfigMap.put(project, apkConfigMap);
                
                compileProject = true;
            }

            // we are done with the modification. Save the property file.
            try {
                properties.save();
            } catch (IOException e) {
                AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
                        project.getName());
            }
            
            if (resolveProject) {
                // force a resolve of the project by updating the classpath container.
                IJavaProject javaProject = JavaCore.create(project);
                AndroidClasspathContainerInitializer.updateProjects(
                        new IJavaProject[] { javaProject });
            } else if (compileProject) {
                // If there was removed configs, we clean instead of build
                // (to remove the obsolete ap_ and apk file from removed configs).
                try {
                    project.build(cleanProject ?
                                IncrementalProjectBuilder.CLEAN_BUILD :
                                IncrementalProjectBuilder.FULL_BUILD,
                            null);
                } catch (CoreException e) {
                    // failed to build? force resolve instead.
                    IJavaProject javaProject = JavaCore.create(project);
                    AndroidClasspathContainerInitializer.updateProjects(
                            new IJavaProject[] { javaProject });
                }
            }
            
            // finally, update the opened editors.
            if (resolveProject) {
                AdtPlugin.getDefault().updateTargetListener(project);
            }
        }
    
public static voidsetProjectTargetHashString(org.eclipse.core.resources.IProject project, java.lang.String targetHashString)
Sets a target hash string in given project's default.properties file.

param
project The project in which to save the hash string.
param
targetHashString The target hash string to save. This must be the result from {@link IAndroidTarget#hashString()}.

        // because we don't want to erase other properties from default.properties, we first load
        // them
        ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
                PropertyType.DEFAULT);
        if (properties == null) {
            // doesn't exist yet? we create it.
            properties = ProjectProperties.create(project.getLocation().toOSString(),
                    PropertyType.DEFAULT);
        }
        
        // add/change the target hash string.
        properties.setProperty(ProjectProperties.PROPERTY_TARGET, targetHashString);
        
        // and rewrite the file.
        try {
            properties.save();
        } catch (IOException e) {
            AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
                    project.getName());
        }
    
voidsetTargetData(com.android.sdklib.IAndroidTarget target, AndroidTargetData data)

        synchronized (mTargetDataMap) {
            mTargetDataMap.put(target, data);
        }