diff options
52 files changed, 918 insertions, 1007 deletions
diff --git a/anttasks/src/com/android/ant/MultiApkExportTask.java b/anttasks/src/com/android/ant/MultiApkExportTask.java index 50325a4..850004e 100644 --- a/anttasks/src/com/android/ant/MultiApkExportTask.java +++ b/anttasks/src/com/android/ant/MultiApkExportTask.java @@ -76,7 +76,11 @@ public class MultiApkExportTask extends Task { private final static int INDEX_MINOR = 2; private final static int INDEX_MINSDK = 3; private final static int INDEX_ABI = 4; - private final static int INDEX_MAX = 5; + private final static int INDEX_OPENGL = 5; + private final static int INDEX_SCREENSIZE = 6; + private final static int INDEX_LOCALES = 7; + private final static int INDEX_DENSITY = 8; + private final static int INDEX_MAX = 9; String outputName; String relativePath; @@ -565,6 +569,8 @@ public class MultiApkExportTask extends Task { dataList.add(data); data.minSdkVersion = minSdkVersion; + + // only look for more exports if the target is not clean. if (mTarget != Target.CLEAN) { // load the project properties diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF index 549bd90..aab1077 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF @@ -84,13 +84,13 @@ Export-Package: com.android.ide.eclipse.adt;x-friends:="com.android.ide.eclipse. com.android.ide.eclipse.adt.internal.resources;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.resources.configurations;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.resources.manager;x-friends:="com.android.ide.eclipse.tests", - com.android.ide.eclipse.adt.internal.resources.manager.files;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.sdk;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.ui;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.wizards.actions;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.wizards.export;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.wizards.newproject;x-friends:="com.android.ide.eclipse.tests", com.android.ide.eclipse.adt.internal.wizards.newxmlfile;x-friends:="com.android.ide.eclipse.tests", + com.android.ide.eclipse.adt.io;x-friends:="com.android.ide.eclipse.tests", com.android.jarutils;x-friends:="com.android.ide.eclipse.tests", com.android.layoutlib.api;x-friends:="com.android.ide.eclipse.tests", com.android.layoutlib.utils;x-friends:="com.android.ide.eclipse.tests", diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java index fc9715e..f7b735a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java @@ -88,9 +88,6 @@ public class AndroidConstants { /** Dot-Extension of aidl files, i.e. ".aidl" */ public final static String DOT_AIDL = DOT + EXT_AIDL; - /** Name of the manifest file, i.e. "AndroidManifest.xml". */ - public static final String FN_ANDROID_MANIFEST = "AndroidManifest.xml"; //$NON-NLS-1$ - /** Name of the android sources directory */ public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$ @@ -188,33 +185,6 @@ public class AndroidConstants { /** provider value for marker attribute "type" */ public final static String MARKER_ATTR_TYPE_PROVIDER = "provider"; //$NON-NLS-1$ - public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$ - public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$ - public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$ - public final static String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$ - public final static String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$ - public final static String CLASS_INSTRUMENTATION_RUNNER = - "android.test.InstrumentationTestRunner"; //$NON-NLS-1$ - public final static String CLASS_BUNDLE = "android.os.Bundle"; //$NON-NLS-1$ - public final static String CLASS_R = "android.R"; //$NON-NLS-1$ - public final static String CLASS_MANIFEST_PERMISSION = "android.Manifest$permission"; //$NON-NLS-1$ - public final static String CLASS_INTENT = "android.content.Intent"; //$NON-NLS-1$ - public final static String CLASS_CONTEXT = "android.content.Context"; //$NON-NLS-1$ - public final static String CLASS_VIEW = "android.view.View"; //$NON-NLS-1$ - public final static String CLASS_VIEWGROUP = "android.view.ViewGroup"; //$NON-NLS-1$ - public final static String CLASS_NAME_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$ - public final static String CLASS_VIEWGROUP_LAYOUTPARAMS = - CLASS_VIEWGROUP + "$" + CLASS_NAME_LAYOUTPARAMS; //$NON-NLS-1$ - public final static String CLASS_NAME_FRAMELAYOUT = "FrameLayout"; //$NON-NLS-1$ - public final static String CLASS_FRAMELAYOUT = - "android.widget." + CLASS_NAME_FRAMELAYOUT; //$NON-NLS-1$ - public final static String CLASS_PREFERENCE = "android.preference.Preference"; //$NON-NLS-1$ - public final static String CLASS_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$ - public final static String CLASS_PREFERENCES = - "android.preference." + CLASS_NAME_PREFERENCE_SCREEN; //$NON-NLS-1$ - public final static String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$ - public final static String CLASS_PARCELABLE = "android.os.Parcelable"; //$NON-NLS-1$ - public final static String CLASS_BRIDGE = "com.android.layoutlib.bridge.Bridge"; //$NON-NLS-1$ /** diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java index 449fe0d..76ae3c3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java @@ -18,9 +18,10 @@ package com.android.ide.eclipse.adt.internal.actions; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidManifest; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -175,18 +176,12 @@ public class RenamePackageAction implements IObjectActionDelegate { */ private void promptNewName(final IProject project) { - IFile manifestFile = AndroidManifestParser.getManifest(project.getProject()); - AndroidManifestParser parser = null; - try { - parser = AndroidManifestParser.parseForData(manifestFile); - } catch (CoreException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - if (parser == null) + ManifestData manifestData = AndroidManifestHelper.parseForData(project); + if (manifestData == null) { return; + } - final String old_package_name_string = parser.getPackage(); + final String old_package_name_string = manifestData.getPackage(); final AST ast_validator = AST.newAST(AST.JLS3); this.mOldPackageName = ast_validator.newName(old_package_name_string); @@ -521,7 +516,7 @@ public class RenamePackageAction implements IObjectActionDelegate { // its context. } else if (AndroidConstants.EXT_XML.equals(file.getFileExtension())) { - if (AndroidConstants.FN_ANDROID_MANIFEST.equals(file.getName())) { + if (SdkConstants.FN_ANDROID_MANIFEST_XML.equals(file.getName())) { TextFileChange manifest_change = editAndroidManifest(file); mChanges.add(manifest_change); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java index 4d19b4e..6f5f1a7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java @@ -458,12 +458,12 @@ public class ApkBuilder extends BaseBuilder { // but not the intermediary ones. if (mPackageResources || mConvertToDex || mBuildFinalPackage) { // resource to the AndroidManifest.xml file - IFile manifestFile = project.getFile(AndroidConstants.FN_ANDROID_MANIFEST); + IFile manifestFile = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); if (manifestFile == null || manifestFile.exists() == false) { // mark project and exit String msg = String.format(Messages.s_File_Missing, - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); markProject(AndroidConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR); return allRefProjects; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java index f48bd43..b01ab39 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java @@ -158,7 +158,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor // check the manifest. if (pathSegments.length == 2 && - AndroidConstants.FN_ANDROID_MANIFEST.equalsIgnoreCase(pathSegments[1])) { + SdkConstants.FN_ANDROID_MANIFEST_XML.equalsIgnoreCase(pathSegments[1])) { // if the manifest changed we have to repackage the // resources. mPackageResources = true; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java index 46ee68f..fd2b78f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java @@ -20,17 +20,20 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig; +import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectState; import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper; import com.android.ide.eclipse.adt.internal.sdk.Sdk; +import com.android.ide.eclipse.adt.io.IFileWrapper; +import com.android.ide.eclipse.adt.io.IFolderWrapper; import com.android.sdklib.AndroidVersion; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidManifest; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -315,11 +318,11 @@ public class PreCompilerBuilder extends BaseBuilder { // get the manifest file - IFile manifest = AndroidManifestParser.getManifest(project); + IFile manifestFile = ProjectHelper.getManifest(project); - if (manifest == null) { + if (manifestFile == null) { String msg = String.format(Messages.s_File_Missing, - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); AdtPlugin.printErrorToConsole(project, msg); markProject(AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR); @@ -334,7 +337,8 @@ public class PreCompilerBuilder extends BaseBuilder { // resource delta visitor yet. if (dv == null || dv.getCheckedManifestXml() == false) { BasicXmlErrorListener errorListener = new BasicXmlErrorListener(); - AndroidManifestParser parser = BaseProjectHelper.parseManifestForError(manifest, + ManifestData parser = AndroidManifestHelper.parse(new IFileWrapper(manifestFile), + true /*gather data*/, errorListener); if (errorListener.mHasXmlError == true) { @@ -342,7 +346,7 @@ public class PreCompilerBuilder extends BaseBuilder { // by the XmlErrorHandler. // We return; String msg = String.format(Messages.s_Contains_Xml_Error, - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg); // This interrupts the build. The next builders will not run. @@ -365,7 +369,7 @@ public class PreCompilerBuilder extends BaseBuilder { AndroidVersion projectVersion = projectTarget.getVersion(); // remove earlier marker from the manifest - removeMarkersFromFile(manifest, AndroidConstants.MARKER_ADT); + removeMarkersFromFile(manifestFile, AndroidConstants.MARKER_ADT); if (minSdkValue != -1) { String codename = projectVersion.getCodename(); @@ -375,8 +379,8 @@ public class PreCompilerBuilder extends BaseBuilder { "Platform %1$s is a preview and requires appication manifest to set %2$s to '%1$s'", codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, - IMarker.SEVERITY_ERROR); + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, + msg, IMarker.SEVERITY_ERROR); stopBuild(msg); } else if (minSdkValue < projectVersion.getApiLevel()) { // integer minSdk is not high enough for the target => warning @@ -385,8 +389,8 @@ public class PreCompilerBuilder extends BaseBuilder { AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkValue, projectVersion.getApiLevel()); AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, - IMarker.SEVERITY_WARNING); + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, + msg, IMarker.SEVERITY_WARNING); } else if (minSdkValue > projectVersion.getApiLevel()) { // integer minSdk is too high for the target => warning String msg = String.format( @@ -394,8 +398,8 @@ public class PreCompilerBuilder extends BaseBuilder { AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkValue, projectVersion.getApiLevel()); AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, - IMarker.SEVERITY_WARNING); + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, + msg, IMarker.SEVERITY_WARNING); } } else { // looks like the min sdk is a codename, check it matches the codename @@ -407,8 +411,8 @@ public class PreCompilerBuilder extends BaseBuilder { "Manifest attribute '%1$s' is set to '%2$s'. Integer is expected.", AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, - IMarker.SEVERITY_ERROR); + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, + msg, IMarker.SEVERITY_ERROR); stopBuild(msg); } else if (codename.equals(minSdkVersion) == false) { // platform and manifest codenames don't match => fatal error. @@ -416,8 +420,8 @@ public class PreCompilerBuilder extends BaseBuilder { "Value of manifest attribute '%1$s' does not match platform codename '%2$s'", AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, codename); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, - IMarker.SEVERITY_ERROR); + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, + msg, IMarker.SEVERITY_ERROR); stopBuild(msg); } } @@ -429,7 +433,7 @@ public class PreCompilerBuilder extends BaseBuilder { "Platform %1$s is a preview and requires appication manifests to set %2$s to '%1$s'", codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, msg, + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR); stopBuild(msg); } @@ -437,9 +441,9 @@ public class PreCompilerBuilder extends BaseBuilder { if (javaPackage == null || javaPackage.length() == 0) { // looks like the AndroidManifest file isn't valid. String msg = String.format(Messages.s_Doesnt_Declare_Package_Error, - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR); // This interrupts the build. The next builders will not run. @@ -449,9 +453,9 @@ public class PreCompilerBuilder extends BaseBuilder { // The application package name does not contain 2+ segments! String msg = String.format( "Application package '%1$s' must have a minimum of 2 segments.", - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); AdtPlugin.printErrorToConsole(project, msg); - BaseProjectHelper.markResource(manifest, AndroidConstants.MARKER_ADT, + BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR); // This interrupts the build. The next builders will not run. @@ -485,7 +489,7 @@ public class PreCompilerBuilder extends BaseBuilder { } if (mMustCompileResources) { - handleResources(project, javaPackage, projectTarget, manifest, libProjects); + handleResources(project, javaPackage, projectTarget, manifestFile, libProjects); } // now handle the aidl stuff. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java index 7d37f9a..aedbd6e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java @@ -21,9 +21,10 @@ import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.build.BaseBuilder.BaseDeltaVisitor; import com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder.AidlData; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; +import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -213,17 +214,27 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements mInRes = true; mSourceFolder = null; return true; - } else if (AndroidConstants.FN_ANDROID_MANIFEST.equalsIgnoreCase(segments[1])) { + } else if (SdkConstants.FN_ANDROID_MANIFEST_XML.equalsIgnoreCase(segments[1])) { // any change in the manifest could trigger a new R.java // class, so we don't need to check the delta kind if (delta.getKind() != IResourceDelta.REMOVED) { - // parse the manifest for errors - AndroidManifestParser parser = BaseProjectHelper.parseManifestForError( - (IFile)resource, this); + // clean the error markers on the file. + IFile manifestFile = (IFile)resource; + + if (manifestFile.exists()) { + manifestFile.deleteMarkers(AndroidConstants.MARKER_XML, true, + IResource.DEPTH_ZERO); + manifestFile.deleteMarkers(AndroidConstants.MARKER_ANDROID, true, + IResource.DEPTH_ZERO); + } + + // parse the manifest for data and error + ManifestData manifestData = AndroidManifestHelper.parse( + new IFileWrapper(manifestFile), true /*gatherData*/, this); - if (parser != null) { - mJavaPackage = parser.getPackage(); - mMinSdkVersion = parser.getApiLevelRequirement(); + if (manifestData != null) { + mJavaPackage = manifestData.getPackage(); + mMinSdkVersion = manifestData.getApiLevelRequirement(); } mCheckedManifestXml = true; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java index afcec39..2e6f8b1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java @@ -18,14 +18,13 @@ package com.android.ide.eclipse.adt.internal.editors.layout; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.resources.manager.ProjectClassLoader; import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.layoutlib.api.IProjectCallback; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; import java.lang.reflect.Constructor; import java.util.HashMap; @@ -91,12 +90,10 @@ public final class ProjectCallback implements IProjectCallback { */ public String getNamespace() { if (mNamespace == null) { - IFile manifestFile = AndroidManifestParser.getManifest(mProject); - try { - AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile); - String javaPackage = data.getPackage(); + ManifestData manifestData = AndroidManifestHelper.parseForData(mProject); + if (manifestData != null) { + String javaPackage = manifestData.getPackage(); mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage); - } catch (CoreException e) { } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java index 04ac833..ec00456 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java @@ -16,7 +16,6 @@ package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor; @@ -90,7 +89,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { for (ElementDescriptor desc : mViewDescriptors) { if (desc instanceof ViewElementDescriptor) { ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc; - if (AndroidConstants.CLASS_VIEW.equals(viewDesc.getFullClassName())) { + if (SdkConstants.CLASS_VIEW.equals(viewDesc.getFullClassName())) { mBaseViewDescriptor = viewDesc; break; } @@ -234,7 +233,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { if (need_separator) { String title; if (layoutParams.getShortClassName().equals( - AndroidConstants.CLASS_NAME_LAYOUTPARAMS)) { + SdkConstants.CLASS_NAME_LAYOUTPARAMS)) { title = String.format("Layout Attributes from %1$s", layoutParams.getViewLayoutClass().getShortClassName()); } else { @@ -302,7 +301,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { // Find View and inherit all its layout attributes AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes( - AndroidConstants.CLASS_VIEW, knownViews); + SdkConstants.CLASS_VIEW, knownViews); // Create the include descriptor ViewElementDescriptor desc = new ViewElementDescriptor(xml_name, // xml_name @@ -328,7 +327,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { // Find View and inherit all its layout attributes AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes( - AndroidConstants.CLASS_FRAMELAYOUT, knownLayouts); + SdkConstants.CLASS_FRAMELAYOUT, knownLayouts); // Create the include descriptor ViewElementDescriptor desc = new ViewElementDescriptor(xml_name, // xml_name diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java index b373a5b..a0fc40d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java @@ -46,12 +46,12 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; import com.android.ide.eclipse.adt.internal.sdk.LoadStatus; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge; import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener; +import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.layoutlib.api.ILayoutBridge; import com.android.layoutlib.api.ILayoutLog; import com.android.layoutlib.api.ILayoutResult; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java index 4cc3d62..cc120d2 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java @@ -38,12 +38,12 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; import com.android.ide.eclipse.adt.internal.sdk.LoadStatus; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge; import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener; +import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.layoutlib.api.ILayoutBridge; import com.android.layoutlib.api.ILayoutLog; import com.android.layoutlib.api.ILayoutResult; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java index 4af0233..fe42dea 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java @@ -16,7 +16,6 @@ package com.android.ide.eclipse.adt.internal.editors.layout.uimodel; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; @@ -83,7 +82,7 @@ public class UiViewElementNode extends UiElementNode { if (layoutDescriptors != null) { for (ElementDescriptor desc : layoutDescriptors) { if (desc instanceof ViewElementDescriptor && - desc.getXmlName().equals(AndroidConstants.CLASS_NAME_FRAMELAYOUT)) { + desc.getXmlName().equals(SdkConstants.CLASS_NAME_FRAMELAYOUT)) { layout_attrs = ((ViewElementDescriptor) desc).getLayoutAttributes(); need_xmlns = true; break; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java index 93a0f9b..85ed6e3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; @@ -201,11 +200,11 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { ListAttributeDescriptor.class); overrides.put("application/" + ANDROID_NAME_ATTR, ApplicationAttributeDescriptor.class); //$NON-NLS-1$ - overrideClassName(overrides, "activity", AndroidConstants.CLASS_ACTIVITY); //$NON-NLS-1$ - overrideClassName(overrides, "receiver", AndroidConstants.CLASS_BROADCASTRECEIVER); //$NON-NLS-1$ - overrideClassName(overrides, "service", AndroidConstants.CLASS_SERVICE); //$NON-NLS-1$ - overrideClassName(overrides, "provider", AndroidConstants.CLASS_CONTENTPROVIDER); //$NON-NLS-1$ - overrideClassName(overrides, "instrumentation", AndroidConstants.CLASS_INSTRUMENTATION); //$NON-NLS-1$ + overrideClassName(overrides, "activity", SdkConstants.CLASS_ACTIVITY); //$NON-NLS-1$ + overrideClassName(overrides, "receiver", SdkConstants.CLASS_BROADCASTRECEIVER); //$NON-NLS-1$ + overrideClassName(overrides, "service", SdkConstants.CLASS_SERVICE); //$NON-NLS-1$ + overrideClassName(overrides, "provider", SdkConstants.CLASS_CONTENTPROVIDER); //$NON-NLS-1$ + overrideClassName(overrides, "instrumentation", SdkConstants.CLASS_INSTRUMENTATION); //$NON-NLS-1$ // -- list element nodes already created -- // These elements are referenced by already opened editors, so we want to update them @@ -246,7 +245,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { public TextAttributeDescriptor create(String xmlName, String uiName, String nsUri, String tooltip) { uiName += "*"; //$NON-NLS-1$ - if (AndroidConstants.CLASS_ACTIVITY.equals(className)) { + if (SdkConstants.CLASS_ACTIVITY.equals(className)) { return new ClassAttributeDescriptor( className, PostActivityCreationAction.getAction(), @@ -256,7 +255,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { tooltip, true /*mandatory */, true /*defaultToProjectOnly*/); - } else if (AndroidConstants.CLASS_BROADCASTRECEIVER.equals(className)) { + } else if (SdkConstants.CLASS_BROADCASTRECEIVER.equals(className)) { return new ClassAttributeDescriptor( className, PostReceiverCreationAction.getAction(), @@ -266,7 +265,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { tooltip, true /*mandatory */, true /*defaultToProjectOnly*/); - } else if (AndroidConstants.CLASS_INSTRUMENTATION.equals(className)) { + } else if (SdkConstants.CLASS_INSTRUMENTATION.equals(className)) { return new ClassAttributeDescriptor( className, null, // no post action diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java index e10e0e7..6338a2f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java @@ -16,8 +16,8 @@ package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; +import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.ICompilationUnit; @@ -29,14 +29,14 @@ import org.eclipse.jdt.core.JavaModelException; * Action to be executed after an Activity class is created. */ class PostActivityCreationAction implements IPostTypeCreationAction { - + private final static PostActivityCreationAction sAction = new PostActivityCreationAction(); - + private PostActivityCreationAction() { // private constructor to enforce singleton. } - - + + /** * Returns the action. */ @@ -46,11 +46,11 @@ class PostActivityCreationAction implements IPostTypeCreationAction { /** * Processes a newly created Activity. - * + * */ public void processNewType(IType newType) { try { - String methodContent = + String methodContent = " /** Called when the activity is first created. */\n" + " @Override\n" + " public void onCreate(Bundle savedInstanceState) {\n" + @@ -71,15 +71,15 @@ class PostActivityCreationAction implements IPostTypeCreationAction { if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { compilationUnit = (ICompilationUnit)parentElement; } - + element = parentElement; } else { break; } } while (compilationUnit == null); - + if (compilationUnit != null) { - compilationUnit.createImport(AndroidConstants.CLASS_BUNDLE, + compilationUnit.createImport(SdkConstants.CLASS_BUNDLE, null /* sibling */, new NullProgressMonitor()); } } catch (JavaModelException e) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java index d16a7d6..834cd41 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java @@ -16,8 +16,8 @@ package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; +import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.ICompilationUnit; @@ -29,13 +29,13 @@ import org.eclipse.jdt.core.JavaModelException; * Action to be executed after an BroadcastReceiver class is created. */ class PostReceiverCreationAction implements IPostTypeCreationAction { - + private final static PostReceiverCreationAction sAction = new PostReceiverCreationAction(); - + private PostReceiverCreationAction() { // private constructor to enforce singleton. } - + /** * Returns the action. */ @@ -45,11 +45,11 @@ class PostReceiverCreationAction implements IPostTypeCreationAction { /** * Processes a newly created Activity. - * + * */ public void processNewType(IType newType) { try { - String methodContent = + String methodContent = " @Override\n" + " public void onReceive(Context context, Intent intent) {\n" + " // TODO Auto-generated method stub\n" + @@ -67,17 +67,17 @@ class PostReceiverCreationAction implements IPostTypeCreationAction { if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { compilationUnit = (ICompilationUnit)parentElement; } - + element = parentElement; } else { break; } } while (compilationUnit == null); - + if (compilationUnit != null) { - compilationUnit.createImport(AndroidConstants.CLASS_CONTEXT, + compilationUnit.createImport(SdkConstants.CLASS_CONTEXT, null /* sibling */, new NullProgressMonitor()); - compilationUnit.createImport(AndroidConstants.CLASS_INTENT, + compilationUnit.createImport(SdkConstants.CLASS_INTENT, null /* sibling */, new NullProgressMonitor()); } } catch (JavaModelException e) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java index d5abc09..522f28a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java @@ -26,6 +26,7 @@ import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidManifest; import org.eclipse.core.resources.IFile; @@ -309,7 +310,7 @@ public class UiClassAttributeNode extends UiTextAttributeNode { javaPackage, textValue); // only test the vilibility for activities. - boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals( + boolean testVisibility = SdkConstants.CLASS_ACTIVITY.equals( mReferenceClass); // test the class diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java index faf5dcc..2d3953b 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java @@ -23,13 +23,14 @@ import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction; import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IMessageProvider; @@ -239,24 +240,19 @@ public class UiManifestPkgAttrNode extends UiTextAttributeNode { // Look for the first project that uses this package name for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) { // check that there is indeed a manifest file. - IFile manifestFile = AndroidManifestParser.getManifest(project.getProject()); + IFile manifestFile = ProjectHelper.getManifest(project.getProject()); 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) { + ManifestData manifestData = AndroidManifestHelper.parseForData(manifestFile); + if (manifestData == null) { // skip this project. continue; } - if (package_name.equals(parser.getPackage())) { + if (package_name.equals(manifestData.getPackage())) { // Found the project. IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); @@ -312,24 +308,13 @@ public class UiManifestPkgAttrNode extends UiTextAttributeNode { for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) { // check that there is indeed a manifest file. - IFile manifestFile = AndroidManifestParser.getManifest(project.getProject()); - 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) { + ManifestData manifestData = AndroidManifestHelper.parseForData(project.getProject()); + if (manifestData == null) { // skip this project. continue; } - packages.add(parser.getPackage()); + packages.add(manifestData.getPackage()); } return packages.toArray(new String[packages.size()]); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java index 600db1b..81f3514 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java @@ -16,7 +16,6 @@ package com.android.ide.eclipse.adt.internal.editors.xml.descriptors; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor; @@ -45,41 +44,41 @@ public final class XmlDescriptors implements IDescriptorProvider { public static final String PREF_KEY_ATTR = "key"; //$NON-NLS-1$ /** The root document descriptor for both searchable and preferences. */ - private DocumentDescriptor mDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + private DocumentDescriptor mDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ /** The root document descriptor for searchable. */ - private DocumentDescriptor mSearchDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + private DocumentDescriptor mSearchDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ /** The root document descriptor for preferences. */ - private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ /** The root document descriptor for widget provider. */ - private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ /** @return the root descriptor for both searchable and preferences. */ public DocumentDescriptor getDescriptor() { return mDescriptor; } - + public ElementDescriptor[] getRootElementDescriptors() { return mDescriptor.getChildren(); } - + /** @return the root descriptor for searchable. */ public DocumentDescriptor getSearchableDescriptor() { return mSearchDescriptor; } - + /** @return the root descriptor for preferences. */ public DocumentDescriptor getPreferencesDescriptor() { return mPrefDescriptor; } - + /** @return the root descriptor for widget providers. */ public DocumentDescriptor getAppWidgetDescriptor() { return mAppWidgetDescriptor; } - + public IDescriptorProvider getSearchableProvider() { return new IDescriptorProvider() { public ElementDescriptor getDescriptor() { @@ -121,10 +120,10 @@ public final class XmlDescriptors implements IDescriptorProvider { * <p/> * It first computes the new children of the descriptor and then updates them * all at once. - * + * * @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file * @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file - * @param prefs The list of non-group preference descriptions + * @param prefs The list of non-group preference descriptions * @param prefGroups The list of preference group descriptions */ public synchronized void updateDescriptors( @@ -134,7 +133,7 @@ public final class XmlDescriptors implements IDescriptorProvider { XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor( "android", //$NON-NLS-1$ - SdkConstants.NS_RESOURCES); + SdkConstants.NS_RESOURCES); ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns); ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns); @@ -161,7 +160,7 @@ public final class XmlDescriptors implements IDescriptorProvider { //------------------------- // Creation of <searchable> //------------------------- - + /** * Returns the new ElementDescriptor for <searchable> */ @@ -188,7 +187,7 @@ public final class XmlDescriptors implements IDescriptorProvider { false /* mandatory */ ); return searchable; } - + /** * Returns the new ElementDescriptor for <appwidget-provider> */ @@ -199,7 +198,7 @@ public final class XmlDescriptors implements IDescriptorProvider { if (appWidgetStyleMap == null) { return null; } - + ElementDescriptor appWidget = createElement(appWidgetStyleMap, "AppWidgetProviderInfo", //$NON-NLS-1$ styleName "appwidget-provider", //$NON-NLS-1$ xmlName @@ -275,14 +274,14 @@ public final class XmlDescriptors implements IDescriptorProvider { } ElementDescriptor topPreferences = null; - + ArrayList<ElementDescriptor> newGroups = new ArrayList<ElementDescriptor>(); if (prefGroups != null) { for (ViewClassInfo info : prefGroups) { ElementDescriptor desc = convertPref(info); newGroups.add(desc); - - if (info.getFullClassName() == AndroidConstants.CLASS_PREFERENCES) { + + if (info.getFullClassName() == SdkConstants.CLASS_PREFERENCES) { topPreferences = desc; } } @@ -325,7 +324,7 @@ public final class XmlDescriptors implements IDescriptorProvider { private ElementDescriptor convertPref(ViewClassInfo info) { String xml_name = info.getShortClassName(); String tooltip = info.getJavaDoc(); - + // Process all Preference attributes ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>(); DescriptorsUtils.appendAttributes(attributes, @@ -334,14 +333,14 @@ public final class XmlDescriptors implements IDescriptorProvider { info.getAttributes(), null, // requiredAttributes null); // overrides - + for (ViewClassInfo link = info.getSuperClass(); link != null; link = link.getSuperClass()) { AttributeInfo[] attrList = link.getAttributes(); if (attrList.length > 0) { attributes.add(new SeparatorAttributeDescriptor( - String.format("Attributes from %1$s", link.getShortClassName()))); + String.format("Attributes from %1$s", link.getShortClassName()))); DescriptorsUtils.appendAttributes(attributes, null, // elementName SdkConstants.NS_RESOURCES, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java index 2f959ff..1054712 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java @@ -30,7 +30,7 @@ import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.Ta import com.android.ide.eclipse.adt.internal.launch.DelayedLaunchInfo.InstallRetryMode; import com.android.ide.eclipse.adt.internal.launch.DeviceChooserDialog.DeviceChooserResponse; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.ApkInstallManager; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; @@ -42,6 +42,7 @@ import com.android.sdklib.IAndroidTarget; import com.android.sdklib.NullSdkLog; import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.avd.AvdManager.AvdInfo; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -257,7 +258,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener ArrayList<IResource> array = new ArrayList<IResource>(2); array.add(project); - IFile manifest = AndroidManifestParser.getManifest(project); + IFile manifest = ProjectHelper.getManifest(project); if (manifest != null) { array.add(manifest); } @@ -933,16 +934,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener for (IJavaProject androidProject : androidProjectList) { // Parse the Manifest to get various required information // copied from LaunchConfigDelegate - AndroidManifestParser manifestParser; - try { - manifestParser = AndroidManifestParser.parse( - androidProject, null /* errorListener */, - true /* gatherData */, false /* markErrors */); - } catch (CoreException e) { - AdtPlugin.printErrorToConsole( - launchInfo.getProject(), - String.format("Error parsing manifest of %s", - androidProject.getElementName())); + ManifestData manifestData = AndroidManifestHelper.parseForData( + androidProject.getProject()); + + if (manifestData == null) { continue; } @@ -956,12 +951,12 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener // Create new launchInfo as an hybrid between parent and dependency information DelayedLaunchInfo delayedLaunchInfo = new DelayedLaunchInfo( androidProject.getProject(), - manifestParser.getPackage(), - manifestParser.getPackage(), + manifestData.getPackage(), + manifestData.getPackage(), launchInfo.getLaunchAction(), apk, - manifestParser.getDebuggable(), - manifestParser.getApiLevelRequirement(), + manifestData.getDebuggable(), + manifestData.getApiLevelRequirement(), launchInfo.getLaunch(), launchInfo.getMonitor()); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java index 4b91e12..fe52e0b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java @@ -20,10 +20,10 @@ import com.android.ddmlib.AndroidDebugBridge; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.TargetMode; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -222,24 +222,22 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { } // we need some information from the manifest - AndroidManifestParser manifestParser = AndroidManifestParser.parse( - BaseProjectHelper.getJavaProject(project), null /* errorListener */, - true /* gatherData */, false /* markErrors */); + ManifestData manifestData = AndroidManifestHelper.parseForData(project); - if (manifestParser == null) { + if (manifestData == null) { AdtPlugin.printErrorToConsole(project, "Failed to parse AndroidManifest: aborting!"); androidLaunch.stopLaunch(); return; } doLaunch(configuration, mode, monitor, project, androidLaunch, config, controller, - applicationPackage, manifestParser); + applicationPackage, manifestData); } protected void doLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor, IProject project, AndroidLaunch androidLaunch, AndroidLaunchConfiguration config, AndroidLaunchController controller, - IFile applicationPackage, AndroidManifestParser manifestParser) { + IFile applicationPackage, ManifestData manifestData) { String activityName = null; @@ -248,7 +246,7 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { activityName = getActivityName(configuration); // Get the full activity list and make sure the one we got matches. - Activity[] activities = manifestParser.getActivities(); + Activity[] activities = manifestData.getActivities(); // first we check that there are, in fact, activities. if (activities.length == 0) { @@ -262,7 +260,7 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { // if the activity we got is null, we look for the default one. AdtPlugin.printErrorToConsole(project, "No activity specified! Getting the launcher activity."); - Activity launcherActivity = manifestParser.getLauncherActivity(); + Activity launcherActivity = manifestData.getLauncherActivity(); if (launcherActivity != null) { activityName = launcherActivity.getName(); } @@ -286,7 +284,7 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { if (match == false) { AdtPlugin.printErrorToConsole(project, "The specified activity does not exist! Getting the launcher activity."); - Activity launcherActivity = manifestParser.getLauncherActivity(); + Activity launcherActivity = manifestData.getLauncherActivity(); if (launcherActivity != null) { activityName = launcherActivity.getName(); } else { @@ -296,7 +294,7 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { } } } else if (config.mLaunchAction == ACTION_DEFAULT) { - Activity launcherActivity = manifestParser.getLauncherActivity(); + Activity launcherActivity = manifestData.getLauncherActivity(); if (launcherActivity != null) { activityName = launcherActivity.getName(); } @@ -316,9 +314,9 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { // everything seems fine, we ask the launch controller to handle // the rest - controller.launch(project, mode, applicationPackage,manifestParser.getPackage(), - manifestParser.getPackage(), manifestParser.getDebuggable(), - manifestParser.getApiLevelRequirement(), launchAction, config, androidLaunch, + controller.launch(project, mode, applicationPackage,manifestData.getPackage(), + manifestData.getPackage(), manifestData.getDebuggable(), + manifestData.getApiLevelRequirement(), launchAction, config, androidLaunch, monitor); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java index 1374dc7..cc73ed5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java @@ -17,11 +17,11 @@ package com.android.ide.eclipse.adt.internal.launch; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.NonLibraryProjectOnlyFilter; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -405,42 +405,34 @@ public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab { */ private void loadActivities(IProject project) { if (project != null) { - try { - // parse the manifest for the list of activities. - AndroidManifestParser manifestParser = AndroidManifestParser.parse( - BaseProjectHelper.getJavaProject(project), null /* errorListener */, - true /* gatherData */, false /* markErrors */); - if (manifestParser != null) { - Activity[] activities = manifestParser.getActivities(); - - mActivities.clear(); - mActivityCombo.removeAll(); - - for (Activity activity : activities) { - if (activity.isExported() && activity.hasAction()) { - mActivities.add(activity); - mActivityCombo.add(activity.getName()); - } + // parse the manifest for the list of activities. + ManifestData manifestData = AndroidManifestHelper.parseForData(project); + if (manifestData != null) { + Activity[] activities = manifestData.getActivities(); + + mActivities.clear(); + mActivityCombo.removeAll(); + + for (Activity activity : activities) { + if (activity.isExported() && activity.hasAction()) { + mActivities.add(activity); + mActivityCombo.add(activity.getName()); } + } - if (mActivities.size() > 0) { - if (mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY) { - mActivityCombo.setEnabled(true); - } - } else { - mActivityCombo.setEnabled(false); + if (mActivities.size() > 0) { + if (mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY) { + mActivityCombo.setEnabled(true); } - - // the selection will be set when we update the ui from the current - // config object. - mActivityCombo.clearSelection(); - - return; + } else { + mActivityCombo.setEnabled(false); } - } catch (CoreException e) { - // The AndroidManifest parsing failed. The builders must have reported the errors - // already so there's nothing to do. + // the selection will be set when we update the ui from the current + // config object. + mActivityCombo.clearSelection(); + + return; } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java index 6ad67ad..677b190 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java @@ -25,9 +25,10 @@ import com.android.ide.eclipse.adt.internal.launch.IAndroidLaunchAction; import com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate; import com.android.ide.eclipse.adt.internal.launch.LaunchMessages; import com.android.ide.eclipse.adt.internal.launch.junit.runtime.AndroidJUnitLaunchInfo; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Instrumentation; +import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.Instrumentation; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -60,9 +61,9 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { protected void doLaunch(final ILaunchConfiguration configuration, final String mode, IProgressMonitor monitor, IProject project, final AndroidLaunch androidLaunch, AndroidLaunchConfiguration config, AndroidLaunchController controller, - IFile applicationPackage, AndroidManifestParser manifestParser) { + IFile applicationPackage, ManifestData manifestData) { - String runner = getRunner(project, configuration, manifestParser); + String runner = getRunner(project, configuration, manifestData); if (runner == null) { AdtPlugin.displayError(LaunchMessages.LaunchDialogTitle, String.format(LaunchMessages.AndroidJUnitDelegate_NoRunnerMsg_s, @@ -71,37 +72,37 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { return; } // get the target app's package - String targetAppPackage = getTargetPackage(manifestParser, runner); + String targetAppPackage = getTargetPackage(manifestData, runner); if (targetAppPackage == null) { AdtPlugin.displayError(LaunchMessages.LaunchDialogTitle, String.format(LaunchMessages.AndroidJUnitDelegate_NoTargetMsg_3s, - project.getName(), runner, AndroidConstants.FN_ANDROID_MANIFEST)); + project.getName(), runner, SdkConstants.FN_ANDROID_MANIFEST_XML)); androidLaunch.stopLaunch(); - return; + return; } - String testAppPackage = manifestParser.getPackage(); - AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project, + String testAppPackage = manifestData.getPackage(); + AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project, testAppPackage, runner); junitLaunchInfo.setTestClass(getTestClass(configuration)); junitLaunchInfo.setTestPackage(getTestPackage(configuration)); junitLaunchInfo.setTestMethod(getTestMethod(configuration)); junitLaunchInfo.setLaunch(androidLaunch); IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(junitLaunchInfo); - + controller.launch(project, mode, applicationPackage, testAppPackage, targetAppPackage, - manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(), + manifestData.getDebuggable(), manifestData.getApiLevelRequirement(), junitLaunch, config, androidLaunch, monitor); } /** - * Get the target Android application's package for the given instrumentation runner, or + * Get the target Android application's package for the given instrumentation runner, or * <code>null</code> if it could not be found. * - * @param manifestParser the {@link AndroidManifestParser} for the test project + * @param manifestParser the {@link ManifestData} for the test project * @param runner the instrumentation runner class name * @return the target package or <code>null</code> */ - private String getTargetPackage(AndroidManifestParser manifestParser, String runner) { + private String getTargetPackage(ManifestData manifestParser, String runner) { for (Instrumentation instr : manifestParser.getInstrumentations()) { if (instr.getName().equals(runner)) { return instr.getTargetPackage(); @@ -111,9 +112,9 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { } /** - * Returns the test package stored in the launch configuration, or <code>null</code> if not + * Returns the test package stored in the launch configuration, or <code>null</code> if not * specified. - * + * * @param configuration the {@link ILaunchConfiguration} to retrieve the test package info from * @return the test package or <code>null</code>. */ @@ -141,7 +142,7 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { return getStringLaunchAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, configuration); } - + /** * Returns the test method stored in the launch configuration. * @@ -154,29 +155,29 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { } /** - * Gets a instrumentation runner for the launch. + * Gets a instrumentation runner for the launch. * <p/> * If a runner is stored in the given <code>configuration</code>, will return that. * Otherwise, will try to find the first valid runner for the project. * If a runner can still not be found, will return <code>null</code>, and will log an error * to the console. - * - * @param project the {@link IProject} for the app + * + * @param project the {@link IProject} for the app * @param configuration the {@link ILaunchConfiguration} for the launch - * @param manifestParser the {@link AndroidManifestParser} for the project - * + * @param manifestData the {@link ManifestData} for the project + * * @return <code>null</code> if no instrumentation runner can be found, otherwise return * the fully qualified runner name. */ private String getRunner(IProject project, ILaunchConfiguration configuration, - AndroidManifestParser manifestParser) { + ManifestData manifestData) { try { String runner = getRunnerFromConfig(configuration); if (runner != null) { return runner; } final InstrumentationRunnerValidator instrFinder = new InstrumentationRunnerValidator( - BaseProjectHelper.getJavaProject(project), manifestParser); + BaseProjectHelper.getJavaProject(project), manifestData); runner = instrFinder.getValidInstrumentationTestRunner(); if (runner != null) { AdtPlugin.printErrorToConsole(project, String.format( @@ -186,24 +187,24 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { AdtPlugin.printErrorToConsole(project, String.format( LaunchMessages.AndroidJUnitDelegate_NoRunnerConsoleMsg_4s, project.getName(), - AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, + SdkConstants.CLASS_INSTRUMENTATION_RUNNER, AndroidConstants.LIBRARY_TEST_RUNNER, - AndroidConstants.FN_ANDROID_MANIFEST)); + SdkConstants.FN_ANDROID_MANIFEST_XML)); return null; } catch (CoreException e) { - AdtPlugin.log(e, "Error when retrieving instrumentation info"); //$NON-NLS-1$ + AdtPlugin.log(e, "Error when retrieving instrumentation info"); //$NON-NLS-1$ } - return null; + return null; } private String getRunnerFromConfig(ILaunchConfiguration configuration) throws CoreException { return getStringLaunchAttribute(ATTR_INSTR_NAME, configuration); } - + /** * Helper method to retrieve a string attribute from the launch configuration - * + * * @param attributeName name of the launch attribute * @param configuration the {@link ILaunchConfiguration} to retrieve the attribute from * @return the attribute's value. <code>null</code> if not found. @@ -225,12 +226,12 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate { /** * Helper method to set JUnit-related attributes expected by JDT JUnit runner - * + * * @param config the launch configuration to modify */ static void setJUnitDefaults(ILaunchConfigurationWorkingCopy config) { // set the test runner to JUnit3 to placate JDT JUnit runner logic - config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, + config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, TestKindRegistry.JUNIT3_TEST_KIND_ID); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java index 305e703..381b037 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java @@ -21,6 +21,7 @@ import com.android.ide.eclipse.adt.internal.launch.LaunchMessages; import com.android.ide.eclipse.adt.internal.launch.MainLaunchConfigTab; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -971,7 +972,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat } catch (CoreException e) { AdtPlugin.logAndPrintError(e, project.getName(), LaunchMessages.AndroidJUnitTab_LoadInstrError_s, - AndroidConstants.FN_ANDROID_MANIFEST); + SdkConstants.FN_ANDROID_MANIFEST_XML); } // if we reach this point, either project is null, or we got an exception during // the parsing. In either case, we empty the instrumentation list. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java index cadb7c1..e3f1a93 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java @@ -15,47 +15,42 @@ */ package com.android.ide.eclipse.adt.internal.launch.junit; -import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.launch.LaunchMessages; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Instrumentation; +import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.Instrumentation; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; /** - * Provides validation for Android instrumentation test runner + * Provides validation for Android instrumentation test runner */ class InstrumentationRunnerValidator { private final IJavaProject mJavaProject; private String[] mInstrumentationNames = null; private boolean mHasRunnerLibrary = false; - + static final String INSTRUMENTATION_OK = null; /** * Initializes the InstrumentationRunnerValidator. - * + * * @param javaProject the {@link IJavaProject} for the Android project to validate */ InstrumentationRunnerValidator(IJavaProject javaProject) { mJavaProject = javaProject; - try { - AndroidManifestParser manifestParser = AndroidManifestParser.parse(javaProject, - null /* errorListener */, true /* gatherData */, false /* markErrors */); - init(manifestParser); - } catch (CoreException e) { - AdtPlugin.printErrorToConsole(javaProject.getProject(), LaunchMessages.ParseFileFailure_s, - AndroidConstants.FN_ANDROID_MANIFEST); - } + ManifestData manifestData = AndroidManifestHelper.parseForData(javaProject.getProject()); + init(manifestData); } /** * Initializes the InstrumentationRunnerValidator. - * + * * @param project the {@link IProject} for the Android project to validate * @throws CoreException if a fatal error occurred in initialization */ @@ -64,34 +59,34 @@ class InstrumentationRunnerValidator { } /** - * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestParser} - * + * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestHelper} + * * @param javaProject the {@link IJavaProject} for the Android project to validate - * @param manifestParser the {@link AndroidManifestParser} for the Android project + * @param manifestData the {@link ManifestData} for the Android project */ - InstrumentationRunnerValidator(IJavaProject javaProject, AndroidManifestParser manifestParser) { + InstrumentationRunnerValidator(IJavaProject javaProject, ManifestData manifestData) { mJavaProject = javaProject; - init(manifestParser); + init(manifestData); } - - private void init(AndroidManifestParser manifestParser) { - Instrumentation[] instrumentations = manifestParser.getInstrumentations(); + + private void init(ManifestData manifestData) { + Instrumentation[] instrumentations = manifestData.getInstrumentations(); mInstrumentationNames = new String[instrumentations.length]; for (int i = 0; i < instrumentations.length; i++) { mInstrumentationNames[i] = instrumentations[i].getName(); } - mHasRunnerLibrary = hasTestRunnerLibrary(manifestParser); + mHasRunnerLibrary = hasTestRunnerLibrary(manifestData); } - + /** * Helper method to determine if given manifest has a <code>AndroidConstants.LIBRARY_TEST_RUNNER * </code> library reference * - * @param manifestParser the {@link AndroidManifestParser} to search + * @param manifestParser the {@link ManifestData} to search * @return true if test runner library found, false otherwise */ - private boolean hasTestRunnerLibrary(AndroidManifestParser manifestParser) { - for (String lib : manifestParser.getUsesLibraries()) { + private boolean hasTestRunnerLibrary(ManifestData manifestData) { + for (String lib : manifestData.getUsesLibraries()) { if (lib.equals(AndroidConstants.LIBRARY_TEST_RUNNER)) { return true; } @@ -101,7 +96,7 @@ class InstrumentationRunnerValidator { /** * Return the set of instrumentation names for the Android project. - * + * * @return <code>null</code if error occurred parsing instrumentations, otherwise returns array * of instrumentation class names */ @@ -111,7 +106,7 @@ class InstrumentationRunnerValidator { /** * Helper method to get the first instrumentation that can be used as a test runner. - * + * * @return fully qualified instrumentation class name. <code>null</code> if no valid * instrumentation can be found. */ @@ -126,7 +121,7 @@ class InstrumentationRunnerValidator { /** * Helper method to determine if specified instrumentation can be used as a test runner - * + * * @param instrumentation the instrumentation class name to validate. Assumes this * instrumentation is one of {@link #getInstrumentationNames()} * @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message @@ -137,14 +132,14 @@ class InstrumentationRunnerValidator { AndroidConstants.LIBRARY_TEST_RUNNER); } // check if this instrumentation is the standard test runner - if (!instrumentation.equals(AndroidConstants.CLASS_INSTRUMENTATION_RUNNER)) { + if (!instrumentation.equals(SdkConstants.CLASS_INSTRUMENTATION_RUNNER)) { // check if it extends the standard test runner String result = BaseProjectHelper.testClassForManifest(mJavaProject, - instrumentation, AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, true); + instrumentation, SdkConstants.CLASS_INSTRUMENTATION_RUNNER, true); if (result != BaseProjectHelper.TEST_CLASS_OK) { return String.format( LaunchMessages.InstrValidator_WrongRunnerTypeMsg_s, - AndroidConstants.CLASS_INSTRUMENTATION_RUNNER); + SdkConstants.CLASS_INSTRUMENTATION_RUNNER); } } return INSTRUMENTATION_OK; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestHelper.java new file mode 100644 index 0000000..f8a9b4b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestHelper.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.project; + +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener; +import com.android.ide.eclipse.adt.io.IFileWrapper; +import com.android.sdklib.io.FileWrapper; +import com.android.sdklib.io.IAbstractFile; +import com.android.sdklib.io.StreamException; +import com.android.sdklib.xml.AndroidManifestParser; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.jdt.core.IJavaProject; +import org.xml.sax.SAXException; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +public class AndroidManifestHelper { + + /** + * Parses the Android Manifest, and returns an object containing the result of the parsing. + * <p/> + * This method can also gather XML error during the parsing. This is done by using an + * {@link XmlErrorHandler} to mark the files in case of error, as well as a given + * {@link XmlErrorListener}. To use a different error handler, consider using + * {@link AndroidManifestParser#parse(IAbstractFile, boolean, com.android.sdklib.xml.AndroidManifestParser.ManifestErrorHandler)} + * directly. + * + * @param manifestFile the {@link IFile} representing the manifest file. + * @param gatherData indicates whether the parsing will extract data from the manifest. If null, + * the method will always return null. + * @param errorListener an optional error listener. If non null, then the parser will also + * look for XML errors. + * @return an {@link ManifestData} or null if the parsing failed. + */ + public static ManifestData parse( + IAbstractFile manifestFile, + boolean gatherData, + XmlErrorListener errorListener) { + try { + if (manifestFile != null) { + IFile eclipseFile = null; + if (manifestFile instanceof IFileWrapper) { + eclipseFile = ((IFileWrapper)manifestFile).getIFile(); + } + XmlErrorHandler errorHandler = null; + if (errorListener != null) { + errorHandler = new XmlErrorHandler(eclipseFile, errorListener); + } + + return AndroidManifestParser.parse(manifestFile, gatherData, errorHandler); + } + } catch (ParserConfigurationException e) { + AdtPlugin.logAndPrintError(e, AndroidManifestHelper.class.getCanonicalName(), + "Bad parser configuration for %s: %s", + manifestFile.getOsLocation(), + e.getMessage()); + } catch (SAXException e) { + AdtPlugin.logAndPrintError(e, AndroidManifestHelper.class.getCanonicalName(), + "Parser exception for %s: %s", + manifestFile.getOsLocation(), + e.getMessage()); + } catch (IOException e) { + // Don't log a console error when failing to read a non-existing file + if (!(e instanceof FileNotFoundException)) { + AdtPlugin.logAndPrintError(e, AndroidManifestHelper.class.getCanonicalName(), + "I/O error for %s: %s", + manifestFile.getOsLocation(), + e.getMessage()); + } + } catch (StreamException e) { + AdtPlugin.logAndPrintError(e, AndroidManifestHelper.class.getCanonicalName(), + "Unable to read %s: %s", + manifestFile.getOsLocation(), + e.getMessage()); + } + + return null; + } + + /** + * Parses the Android Manifest for a given project, and returns an object containing + * the result of the parsing. + * <p/> + * This method can also gather XML error during the parsing. This is done by using an + * {@link XmlErrorHandler} to mark the files in case of error, as well as a given + * {@link XmlErrorListener}. To use a different error handler, consider using + * {@link AndroidManifestParser#parse(IAbstractFile, boolean, com.android.sdklib.xml.AndroidManifestParser.ManifestErrorHandler)} + * directly. + * + * @param javaProject the project containing the manifest to parse. + * @param gatherData indicates whether the parsing will extract data from the manifest. If null, + * the method will always return null. + * @param errorListener an optional error listener. If non null, then the parser will also + * look for XML errors. + * @return an {@link ManifestData} or null if the parsing failed. + */ + public static ManifestData parse( + IJavaProject javaProject, + boolean gatherData, + XmlErrorListener errorListener) { + + IFile manifestFile = ProjectHelper.getManifest(javaProject.getProject()); + if (manifestFile != null) { + return parse(new IFileWrapper(manifestFile), gatherData, errorListener); + } + + return null; + } + + /** + * Parses the manifest file only for error check. + * @param manifestFile The manifest file to parse. + * @param errorListener the {@link XmlErrorListener} object being notified of the presence + * of errors. + */ + public static void parseForError(IFile manifestFile, XmlErrorListener errorListener) { + parse(new IFileWrapper(manifestFile), false, errorListener); + } + + /** + * Parses the manifest file, and collects data. + * @param manifestFile The manifest file to parse. + * @return an {@link ManifestData} or null if the parsing failed. + */ + public static ManifestData parseForData(IFile manifestFile) { + return parse(new IFileWrapper(manifestFile), true, null); + } + + /** + * Parses the manifest file, and collects data. + * @param project the project containing the manifest. + * @return an {@link AndroidManifestHelper} or null if the parsing failed. + */ + public static ManifestData parseForData(IProject project) { + IFile manifestFile = ProjectHelper.getManifest(project); + if (manifestFile != null) { + return parse(new IFileWrapper(manifestFile), true, null); + } + + return null; + } + + /** + * Parses the manifest file, and collects data. + * + * @param osManifestFilePath The OS path of the manifest file to parse. + * @return an {@link AndroidManifestHelper} or null if the parsing failed. + */ + public static ManifestData parseForData(String osManifestFilePath) { + return parse(new FileWrapper(osManifestFilePath), true, null); + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java index 3712dc4..0aff5c9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java @@ -18,9 +18,7 @@ package com.android.ide.eclipse.adt.internal.project; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -275,29 +273,6 @@ public final class BaseProjectHelper { } /** - * Parses the manifest file for errors. - * <p/> - * This starts by removing the current XML marker, and then parses the xml for errors, both - * of XML type and of Android type (checking validity of class files). - * @param manifestFile - * @param errorListener - * @throws CoreException - */ - public static AndroidManifestParser parseManifestForError(IFile manifestFile, - XmlErrorListener errorListener) throws CoreException { - // remove previous markers - if (manifestFile.exists()) { - manifestFile.deleteMarkers(AndroidConstants.MARKER_XML, true, IResource.DEPTH_ZERO); - manifestFile.deleteMarkers(AndroidConstants.MARKER_ANDROID, true, IResource.DEPTH_ZERO); - } - - // and parse - return AndroidManifestParser.parseForError( - BaseProjectHelper.getJavaProject(manifestFile.getProject()), - manifestFile, errorListener); - } - - /** * Returns the {@link IJavaProject} for a {@link IProject} object. * <p/> * This checks if the project has the Java Nature first. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java index 49a75dc..21c0d8e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java @@ -18,6 +18,8 @@ package com.android.ide.eclipse.adt.internal.project; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; +import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -72,7 +74,7 @@ public final class ProjectHelper { * * @param javaProject The java project of which path entries to update. * @param new_entry The parent source folder to remove. - * @throws JavaModelException + * @throws JavaModelException */ public static void addEntryToClasspath( IJavaProject javaProject, IClasspathEntry new_entry) @@ -203,7 +205,7 @@ public final class ProjectHelper { AdtPlugin.printToConsole(project, "Unknown SDK Location, project not fixed."); return; } - + // get a java project IJavaProject javaProject = JavaCore.create(project); fixProjectClasspathEntries(javaProject); @@ -237,7 +239,7 @@ public final class ProjectHelper { // get the output folder IPath outputFolder = javaProject.getOutputLocation(); - + boolean foundContainer = false; for (int i = 0 ; i < entries.length ;) { @@ -247,10 +249,10 @@ public final class ProjectHelper { if (kind == IClasspathEntry.CPE_SOURCE) { IPath path = entry.getPath(); - + if (path.equals(outputFolder)) { entries = ProjectHelper.removeEntryFromClasspath(entries, i); - + // continue, to skip the i++; continue; } @@ -259,7 +261,7 @@ public final class ProjectHelper { foundContainer = true; } } - + i++; } @@ -278,8 +280,8 @@ public final class ProjectHelper { // If needed, check and fix compiler compliance and source compatibility ProjectHelper.checkAndFixCompilerCompliance(javaProject); } - - + + /** * Checks the project compiler compliance level is supported. * @param javaProject The project to check @@ -393,7 +395,7 @@ public final class ProjectHelper { // 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) { @@ -409,24 +411,19 @@ public final class ProjectHelper { } // check that there is indeed a manifest file. - IFile manifestFile = AndroidManifestParser.getManifest(p); + IFile manifestFile = 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) { + ManifestData data = AndroidManifestHelper.parseForData(manifestFile); + if (data == null) { // skip this project. continue; } - String manifestPackage = parser.getPackage(); + String manifestPackage = data.getPackage(); if (manifestPackage != null && manifestPackage.equals(applicationName)) { // this is the project we were looking for! @@ -434,7 +431,7 @@ public final class ProjectHelper { } 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(); + String[] processes = data.getProcesses(); for (String process : processes) { if (process.equals(applicationName)) { return p; @@ -451,31 +448,31 @@ public final class ProjectHelper { public static void fixProjectNatureOrder(IProject project) throws CoreException { 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 + // 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); @@ -534,11 +531,11 @@ public final class ProjectHelper { } } } - + // test the referenced projects if needed. if (includeReferencedProjects) { IProject[] projects = getReferencedProjects(project); - + for (IProject p : projects) { if (hasError(p, false)) { return true; @@ -649,7 +646,7 @@ public final class ProjectHelper { return null; } - + /** * Returns the list of referenced project that are opened and Java projects. * @param project @@ -658,9 +655,9 @@ public final class ProjectHelper { */ public static IProject[] getReferencedProjects(IProject 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); @@ -685,7 +682,7 @@ public final class ProjectHelper { return false; } - + /** * Returns the apk filename for the given project * @param project The project. @@ -693,31 +690,31 @@ public final class ProjectHelper { */ public static String getApkFilename(IProject project, String config) { if (config != null) { - return project.getName() + "-" + config + AndroidConstants.DOT_ANDROID_PACKAGE; //$NON-NLS-1$ + return project.getName() + "-" + config + AndroidConstants.DOT_ANDROID_PACKAGE; //$NON-NLS-1$ } - + return project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE; } /** * 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 */ - public static List<IJavaProject> getAndroidProjectDependencies(IJavaProject javaProject) + public static List<IJavaProject> getAndroidProjectDependencies(IJavaProject javaProject) 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)) { @@ -726,10 +723,10 @@ public final class ProjectHelper { } catch (CoreException e) { continue; } - + projectList.add(androidJavaProject); } - + return projectList; } @@ -742,27 +739,44 @@ public final class ProjectHelper { public static IFile getApplicationPackage(IProject project) { // 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; } + + /** + * Returns an {@link IFile} object representing the manifest for the given project. + * + * @param project The project containing the manifest file. + * @return An IFile object pointing to the manifest or null if the manifest + * is missing. + */ + public static IFile getManifest(IProject project) { + IResource r = project.findMember(AndroidConstants.WS_SEP + + SdkConstants.FN_ANDROID_MANIFEST_XML); + + if (r == null || r.exists() == false || (r instanceof IFile) == false) { + return null; + } + return (IFile) r; + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java index ab00225..d5f6f15 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java @@ -17,9 +17,13 @@ package com.android.ide.eclipse.adt.internal.project; import com.android.ide.eclipse.adt.AndroidConstants; +import com.android.sdklib.xml.AndroidManifestParser.ManifestErrorHandler; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IJavaProject; +import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; @@ -27,13 +31,13 @@ import org.xml.sax.helpers.DefaultHandler; /** * XML error handler used by the parser to report errors/warnings. */ -public class XmlErrorHandler extends DefaultHandler { +public class XmlErrorHandler extends DefaultHandler implements ManifestErrorHandler { + private final IJavaProject mJavaProject; /** file being parsed */ - private IFile mFile; - + private final IFile mFile; /** link to the delta visitor, to set the xml error flag */ - private XmlErrorListener mErrorListener; + private final XmlErrorListener mErrorListener; /** * Classes which implement this interface provide a method that deals @@ -54,11 +58,16 @@ public class XmlErrorHandler extends DefaultHandler { } } - public XmlErrorHandler(IFile file, XmlErrorListener errorListener) { + public XmlErrorHandler(IJavaProject javaProject, IFile file, XmlErrorListener errorListener) { + mJavaProject = javaProject; mFile = file; mErrorListener = errorListener; } + public XmlErrorHandler(IFile file, XmlErrorListener errorListener) { + this(null, file, errorListener); + } + /** * Xml Error call back * @param exception the parsing exception @@ -104,7 +113,7 @@ public class XmlErrorHandler extends DefaultHandler { * @param exception * @param lineNumber */ - protected void handleError(Exception exception, int lineNumber) { + public void handleError(Exception exception, int lineNumber) { if (mErrorListener != null) { mErrorListener.errorFound(); } @@ -122,4 +131,42 @@ public class XmlErrorHandler extends DefaultHandler { IMarker.SEVERITY_ERROR); } } + + /** + * Checks that a class is valid and can be used in the Android Manifest. + * <p/> + * Errors are put as {@link IMarker} on the manifest file. + * @param locator + * @param className the fully qualified name of the class to test. + * @param superClassName the fully qualified name of the class it is supposed to extend. + * @param testVisibility if <code>true</code>, the method will check the visibility of + * the class or of its constructors. + */ + public void checkClass(Locator locator, String className, String superClassName, + boolean testVisibility) { + if (mJavaProject == null) { + return; + } + // we need to check the validity of the activity. + String result = BaseProjectHelper.testClassForManifest(mJavaProject, + className, superClassName, testVisibility); + if (result != BaseProjectHelper.TEST_CLASS_OK) { + // get the line number + int line = locator.getLineNumber(); + + // mark the file + IMarker marker = BaseProjectHelper.markResource(getFile(), + AndroidConstants.MARKER_ANDROID, result, line, IMarker.SEVERITY_ERROR); + + // add custom attributes to be used by the manifest editor. + if (marker != null) { + try { + marker.setAttribute(AndroidConstants.MARKER_ATTR_TYPE, + AndroidConstants.MARKER_ATTR_TYPE_ACTIVITY); + marker.setAttribute(AndroidConstants.MARKER_ATTR_CLASS, className); + } catch (CoreException e) { + } + } + } + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java index 20ef355..2c43854 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java @@ -22,10 +22,11 @@ import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescrip import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.resources.ResourceType; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -1259,23 +1260,18 @@ public class ExtractStringRefactoring extends Refactoring { // the FQCN of the R class. String packageName = null; String error = null; - IResource manifestFile = mProject.findMember(AndroidConstants.FN_ANDROID_MANIFEST); + IResource manifestFile = mProject.findMember(SdkConstants.FN_ANDROID_MANIFEST_XML); if (manifestFile == null || manifestFile.getType() != IResource.FILE) { error = "File not found"; } else { - try { - AndroidManifestParser manifest = AndroidManifestParser.parseForData( - (IFile) manifestFile); - if (manifest == null) { - error = "Invalid content"; - } else { - packageName = manifest.getPackage(); - if (packageName == null) { - error = "Missing package definition"; - } + ManifestData manifestData = AndroidManifestHelper.parseForData((IFile) manifestFile); + if (manifestData == null) { + error = "Invalid content"; + } else { + packageName = manifestData.getPackage(); + if (packageName == null) { + error = "Missing package definition"; } - } catch (CoreException e) { - error = e.getLocalizedMessage(); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java index 7037a39..f05cf30 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java @@ -18,10 +18,12 @@ package com.android.ide.eclipse.adt.internal.resources.manager; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; +import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.resources.ResourceType; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarkerDelta; @@ -221,23 +223,13 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi * @return A class name (e.g. "my.app.R") or null if there's no valid package in the manifest. */ private String getRClassName(IProject project) { - try { - IFile manifestFile = AndroidManifestParser.getManifest(project); - if (manifestFile != null && manifestFile.isSynchronized(IResource.DEPTH_ZERO)) { - AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile); - if (data != null) { - String javaPackage = data.getPackage(); - return javaPackage + ".R"; //$NON-NLS-1$ - } + IFile manifestFile = ProjectHelper.getManifest(project); + if (manifestFile != null && manifestFile.isSynchronized(IResource.DEPTH_ZERO)) { + ManifestData data = AndroidManifestHelper.parseForData(manifestFile); + if (data != null) { + String javaPackage = data.getPackage(); + return javaPackage + ".R"; //$NON-NLS-1$ } - } catch (CoreException e) { - // This will typically happen either because the manifest file is not present - // and/or the workspace needs to be refreshed. - AdtPlugin.logAndPrintError(e, - "Android Resources", - "Failed to find the package of the AndroidManifest of project %1$s. Reason: %2$s", - project.getName(), - e.getMessage()); } return null; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java index b568f31..ef2e950 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java @@ -24,8 +24,8 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfi import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper; import com.android.ide.eclipse.adt.internal.sdk.Sdk; +import com.android.ide.eclipse.adt.io.IFolderWrapper; import com.android.layoutlib.api.IResourceValue; import com.android.layoutlib.utils.ResourceValue; import com.android.sdklib.io.IAbstractFolder; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java index c814f4b..b04000f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java @@ -19,7 +19,7 @@ package com.android.ide.eclipse.adt.internal.resources.manager; import com.android.ide.eclipse.adt.internal.resources.ResourceItem; import com.android.ide.eclipse.adt.internal.resources.ResourceType; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; +import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.sdklib.io.IAbstractFile; import com.android.sdklib.io.IAbstractFolder; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java index 3bf6a17..90c5ca0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java @@ -24,8 +24,8 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQua import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFolderListener; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper; +import com.android.ide.eclipse.adt.io.IFileWrapper; +import com.android.ide.eclipse.adt.io.IFolderWrapper; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import com.android.sdklib.io.FolderWrapper; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java index 848636c..4bbad4f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java @@ -33,6 +33,7 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge; import com.android.layoutlib.api.ILayoutBridge; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -312,7 +313,7 @@ public final class AndroidTargetParser { private IResourceRepository collectResourceIds( AndroidJarLoader classLoader) { try { - Class<?> r = classLoader.loadClass(AndroidConstants.CLASS_R); + Class<?> r = classLoader.loadClass(SdkConstants.CLASS_R); if (r != null) { Map<ResourceType, List<ResourceItem>> map = parseRClass(r); @@ -323,7 +324,7 @@ public final class AndroidTargetParser { } catch (ClassNotFoundException e) { AdtPlugin.logAndPrintError(e, TAG, "Collect resource IDs failed, class %1$s not found in %2$s", //$NON-NLS-1$ - AndroidConstants.CLASS_R, + SdkConstants.CLASS_R, mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR)); } @@ -378,7 +379,7 @@ public final class AndroidTargetParser { private String[] collectPermissions(AndroidJarLoader classLoader) { try { Class<?> permissionClass = - classLoader.loadClass(AndroidConstants.CLASS_MANIFEST_PERMISSION); + classLoader.loadClass(SdkConstants.CLASS_MANIFEST_PERMISSION); if (permissionClass != null) { ArrayList<String> list = new ArrayList<String>(); @@ -411,7 +412,7 @@ public final class AndroidTargetParser { } catch (ClassNotFoundException e) { AdtPlugin.logAndPrintError(e, TAG, "Collect permissions failed, class %1$s not found in %2$s", //$NON-NLS-1$ - AndroidConstants.CLASS_MANIFEST_PERMISSION, + SdkConstants.CLASS_MANIFEST_PERMISSION, mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR)); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java index d095e36..41f5a35 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java @@ -17,11 +17,11 @@ package com.android.ide.eclipse.adt.internal.sdk; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.resources.AttrsXmlParser; import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo; import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo.LayoutParamsInfo; import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor; +import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; @@ -131,15 +131,15 @@ public class LayoutParamsParser { */ public void parseLayoutClasses(IProgressMonitor monitor) { parseClasses(monitor, - AndroidConstants.CLASS_VIEW, - AndroidConstants.CLASS_VIEWGROUP, - AndroidConstants.CLASS_VIEWGROUP_LAYOUTPARAMS); + SdkConstants.CLASS_VIEW, + SdkConstants.CLASS_VIEWGROUP, + SdkConstants.CLASS_VIEWGROUP_LAYOUTPARAMS); } public void parsePreferencesClasses(IProgressMonitor monitor) { parseClasses(monitor, - AndroidConstants.CLASS_PREFERENCE, - AndroidConstants.CLASS_PREFERENCEGROUP, + SdkConstants.CLASS_PREFERENCE, + SdkConstants.CLASS_PREFERENCEGROUP, null /* paramsClassName */ ); } @@ -352,7 +352,7 @@ public class LayoutParamsParser { private IClassDescriptor findLayoutParams(IClassDescriptor groupClass) { IClassDescriptor[] innerClasses = groupClass.getDeclaredClasses(); for (IClassDescriptor innerClass : innerClasses) { - if (innerClass.getSimpleName().equals(AndroidConstants.CLASS_NAME_LAYOUTPARAMS)) { + if (innerClass.getSimpleName().equals(SdkConstants.CLASS_NAME_LAYOUTPARAMS)) { return innerClass; } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java index b1f5b60..5dcc25e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java @@ -16,7 +16,7 @@ package com.android.ide.eclipse.adt.internal.sdk; -import com.android.ide.eclipse.adt.AndroidConstants; +import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.IProgressMonitor; @@ -42,12 +42,12 @@ import javax.management.InvalidAttributeValueException; * are the fully qualified name of the classes. */ public final class WidgetClassLoader implements IAndroidClassLoader { - + /** - * Basic class containing the class descriptions found in the text file. + * Basic class containing the class descriptions found in the text file. */ private final static class ClassDescriptor implements IClassDescriptor { - + private String mFqcn; private String mSimpleName; private ClassDescriptor mSuperClass; @@ -80,14 +80,14 @@ public final class WidgetClassLoader implements IAndroidClassLoader { public IClassDescriptor getEnclosingClass() { return mEnclosingClass; } - + void setEnclosingClass(ClassDescriptor enclosingClass) { // set the enclosing class. mEnclosingClass = enclosingClass; - + // add this to the list of declared class in the enclosing class. mEnclosingClass.addDeclaredClass(this); - + // finally change the name of declared class to make sure it uses the // convention: package.enclosing$declared instead of package.enclosing.declared mFqcn = enclosingClass.mFqcn + "$" + mFqcn.substring(enclosingClass.mFqcn.length() + 1); @@ -96,11 +96,11 @@ public final class WidgetClassLoader implements IAndroidClassLoader { public IClassDescriptor getSuperclass() { return mSuperClass; } - + void setSuperClass(ClassDescriptor superClass) { mSuperClass = superClass; } - + @Override public boolean equals(Object clazz) { if (clazz instanceof ClassDescriptor) { @@ -108,20 +108,20 @@ public final class WidgetClassLoader implements IAndroidClassLoader { } return super.equals(clazz); } - + @Override public int hashCode() { return mFqcn.hashCode(); } - + public boolean isInstantiable() { return mIsInstantiable; } - + void setInstantiable(boolean state) { mIsInstantiable = state; } - + private String getSimpleName(String fqcn) { String[] segments = fqcn.split("\\."); return segments[segments.length-1]; @@ -155,7 +155,7 @@ public final class WidgetClassLoader implements IAndroidClassLoader { public String getSource() { return mOsFilePath; } - + /** * Parses the text file and return true if the file was successfully parsed. * @param monitor @@ -200,10 +200,10 @@ public final class WidgetClassLoader implements IAndroidClassLoader { } } } - + // reconciliate the layout and their layout params postProcess(); - + return true; } catch (IOException e) { } finally { @@ -212,10 +212,10 @@ public final class WidgetClassLoader implements IAndroidClassLoader { } catch (IOException e) { } } - + return false; } - + /** * Parses a View class and adds a ViewClassInfo for it in mWidgetMap. * It calls itself recursively to handle super classes which are also Views. @@ -228,9 +228,9 @@ public final class WidgetClassLoader implements IAndroidClassLoader { if (index >= classes.length) { return null; } - + String fqcn = classes[index]; - + if ("java.lang.Object".equals(fqcn)) { //$NON-NLS-1$ return null; } @@ -246,16 +246,16 @@ public final class WidgetClassLoader implements IAndroidClassLoader { if (map != null) { map.put(fqcn, clazz); } - + // get the super class ClassDescriptor superClass = processClass(classes, index+1, map); if (superClass != null) { clazz.setSuperClass(superClass); } - + return clazz; } - + /** * Goes through the layout params and look for the enclosed class. If the layout params * has no known enclosed type it is dropped. @@ -265,17 +265,17 @@ public final class WidgetClassLoader implements IAndroidClassLoader { for (ClassDescriptor param : params) { String fqcn = param.getFullClassName(); - + // get the enclosed name. String enclosed = getEnclosedName(fqcn); - + // look for a match in the layouts. We don't use the layout map as it only contains the // end classes, but in this case we also need to process the layout params for the base // layout classes. ClassDescriptor enclosingType = mMap.get(enclosed); if (enclosingType != null) { param.setEnclosingClass(enclosingType); - + // remove the class from the map, and put it back with the fixed name mMap.remove(fqcn); mMap.put(param.getFullClassName(), param); @@ -290,13 +290,13 @@ public final class WidgetClassLoader implements IAndroidClassLoader { /** * Finds and loads all classes that derive from a given set of super classes. - * + * * @param rootPackage Root package of classes to find. Use an empty string to find everyting. - * @param superClasses The super classes of all the classes to find. + * @param superClasses The super classes of all the classes to find. * @return An hash map which keys are the super classes looked for and which values are * ArrayList of the classes found. The array lists are always created for all the * valid keys, they are simply empty if no deriving class is found for a given - * super class. + * super class. * @throws IOException * @throws InvalidAttributeValueException * @throws ClassFormatError @@ -306,18 +306,18 @@ public final class WidgetClassLoader implements IAndroidClassLoader { ClassFormatError { HashMap<String, ArrayList<IClassDescriptor>> map = new HashMap<String, ArrayList<IClassDescriptor>>(); - + ArrayList<IClassDescriptor> list = new ArrayList<IClassDescriptor>(); list.addAll(mWidgetMap.values()); - map.put(AndroidConstants.CLASS_VIEW, list); - + map.put(SdkConstants.CLASS_VIEW, list); + list = new ArrayList<IClassDescriptor>(); list.addAll(mLayoutMap.values()); - map.put(AndroidConstants.CLASS_VIEWGROUP, list); + map.put(SdkConstants.CLASS_VIEWGROUP, list); list = new ArrayList<IClassDescriptor>(); list.addAll(mLayoutParamsMap.values()); - map.put(AndroidConstants.CLASS_VIEWGROUP_LAYOUTPARAMS, list); + map.put(SdkConstants.CLASS_VIEWGROUP_LAYOUTPARAMS, list); return map; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java index 1cb023b..7ec3934 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java @@ -23,7 +23,7 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IResourceEventListener; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; +import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.sdklib.io.IAbstractFile; import org.eclipse.core.resources.IFile; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java index aa65e6e..7155ceb 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java @@ -18,12 +18,13 @@ package com.android.ide.eclipse.adt.internal.wizards.export; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.NonLibraryProjectOnlyFilter; import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -189,11 +190,11 @@ final class ProjectCheckPage extends ExportWizardPage { // project is an android project, we check the debuggable attribute. - AndroidManifestParser manifestParser = AndroidManifestParser.parse( - BaseProjectHelper.getJavaProject(project), null /* errorListener */, - true /* gatherData */, false /* markErrors */); - - Boolean debuggable = manifestParser.getDebuggable(); + ManifestData manifestData = AndroidManifestHelper.parseForData(project); + Boolean debuggable = null; + if (manifestData != null) { + debuggable = manifestData.getDebuggable(); + } if (debuggable != null && debuggable == Boolean.TRUE) { addWarning(mErrorComposite, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java index aaa48a3..e74f679 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java @@ -24,8 +24,7 @@ package com.android.ide.eclipse.adt.internal.wizards.newproject; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener; import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage.TestInfo; @@ -34,6 +33,8 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.internal.project.ProjectProperties.PropertyType; import com.android.sdklib.xml.AndroidManifest; +import com.android.sdklib.xml.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import com.android.sdkuilib.internal.widgets.SdkTargetSelector; import org.eclipse.core.filesystem.URIUtil; @@ -990,9 +991,9 @@ public class NewProjectCreationPage extends WizardPage { } Path path = new Path(f.getPath()); - String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString(); + String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString(); - AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath); + ManifestData manifestData = AndroidManifestHelper.parseForData(osPath); if (manifestData == null) { return; } @@ -1377,17 +1378,17 @@ public class NewProjectCreationPage extends WizardPage { } // Check there's an android manifest in the directory - String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString(); + String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString(); File manifestFile = new File(osPath); if (!manifestFile.isFile()) { return setStatus( String.format("File %1$s not found in %2$s.", - AndroidConstants.FN_ANDROID_MANIFEST, f.getName()), + SdkConstants.FN_ANDROID_MANIFEST_XML, f.getName()), MSG_ERROR); } // Parse it and check the important fields. - AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath); + ManifestData manifestData = AndroidManifestHelper.parseForData(osPath); if (manifestData == null) { return setStatus( String.format("File %1$s could not be parsed.", osPath), diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java index 517ffa0..d30a812 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java @@ -751,7 +751,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { throws CoreException, IOException { // get IFile to the manifest and check if it's not already there. - IFile file = project.getFile(AndroidConstants.FN_ANDROID_MANIFEST); + IFile file = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); if (!file.exists()) { // Read manifest template diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java index df5a39b..608b002 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java @@ -23,7 +23,7 @@ package com.android.ide.eclipse.adt.internal.wizards.newproject; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener; @@ -31,15 +31,14 @@ import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreatio import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.MainInfo; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import com.android.sdkuilib.internal.widgets.SdkTargetSelector; import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; @@ -830,16 +829,7 @@ public class NewTestProjectCreationPage extends WizardPage { !mSdkTargetModifiedByUser || !mMinSdkVersionModifiedByUser)) { - IFile file = AndroidManifestParser.getManifest(project); - AndroidManifestParser manifestData = null; - if (file != null) { - try { - manifestData = AndroidManifestParser.parseForData(file); - } catch (CoreException e) { - // pass - } - } - + ManifestData manifestData = AndroidManifestHelper.parseForData(project); if (manifestData != null) { String appName = String.format("%1$sTest", project.getName()); String packageName = manifestData.getPackage(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java index 81a9952..8f5fd12 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java @@ -239,7 +239,7 @@ class NewXmlFileCreationPage extends WizardPage { "An XML file that describes preferences.", // tooltip ResourceFolderType.XML, // folder type AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed - AndroidConstants.CLASS_NAME_PREFERENCE_SCREEN, // default root + SdkConstants.CLASS_NAME_PREFERENCE_SCREEN, // default root SdkConstants.NS_RESOURCES, // xmlns null, // default attributes 1 // target API level diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java index 5073367..4b96789 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.ide.eclipse.adt.internal.resources.manager.files; +package com.android.ide.eclipse.adt.io; import com.android.sdklib.io.IAbstractFile; import com.android.sdklib.io.StreamException; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java index 2c386c5..158fd8b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.ide.eclipse.adt.internal.resources.manager.files; +package com.android.ide.eclipse.adt.io; import com.android.sdklib.io.IAbstractFile; import com.android.sdklib.io.IAbstractFolder; diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java index 495c3be..365df56 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java @@ -15,7 +15,7 @@ */ package com.android.ide.eclipse.tests.functests.sampleProjects; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidManifest; @@ -108,7 +108,7 @@ class AndroidManifestWriter { * Parses the manifest file, and collects data. * * @param osManifestFilePath The OS path of the manifest file to parse. - * @return an {@link AndroidManifestParser} or null if parsing failed + * @return an {@link AndroidManifestHelper} or null if parsing failed */ public static AndroidManifestWriter parse(String osManifestFilePath) { try { diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java index d33b939..3deb3b2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java @@ -15,10 +15,10 @@ */ package com.android.ide.eclipse.tests.functests.sampleProjects; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.wizards.newproject.StubProjectWizard; import com.android.ide.eclipse.tests.SdkTestCase; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -122,7 +122,7 @@ public class SampleProjectTest extends SdkTestCase { if (target.getVersion().isPreview()) { // need to explicitly set preview's version in manifest for project to compile final String manifestPath = path + File.separatorChar + - AndroidConstants.FN_ANDROID_MANIFEST; + SdkConstants.FN_ANDROID_MANIFEST_XML; AndroidManifestWriter manifestWriter = AndroidManifestWriter.parse(manifestPath); assertNotNull(String.format("could not read manifest %s", manifestPath), diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java index e4a352d..4ce011e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java @@ -29,8 +29,8 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.ide.eclipse.adt.internal.resources.manager.SingleResourceFile; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper; -import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper; +import com.android.ide.eclipse.adt.io.IFileWrapper; +import com.android.ide.eclipse.adt.io.IFolderWrapper; import com.android.ide.eclipse.mock.FileMock; import com.android.ide.eclipse.mock.FolderMock; import com.android.sdklib.IAndroidTarget; diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java index e05391c..e8571ee 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java @@ -16,18 +16,19 @@ package com.android.ide.eclipse.adt.internal.project; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.tests.AdtTestData; +import com.android.sdklib.xml.AndroidManifestParser.Activity; +import com.android.sdklib.xml.AndroidManifestParser.ManifestData; import junit.framework.TestCase; /** - * Tests for {@link AndroidManifestParser} + * Tests for {@link AndroidManifestHelper} */ public class AndroidManifestParserTest extends TestCase { - private AndroidManifestParser mManifestTestApp; - private AndroidManifestParser mManifestInstrumentation; + private ManifestData mManifestTestApp; + private ManifestData mManifestInstrumentation; private static final String TESTDATA_PATH = "com/android/ide/eclipse/testdata/"; //$NON-NLS-1$ @@ -46,11 +47,11 @@ public class AndroidManifestParserTest extends TestCase { super.setUp(); String testFilePath = AdtTestData.getInstance().getTestFilePath(TESTAPP_XML); - mManifestTestApp = AndroidManifestParser.parseForData(testFilePath); + mManifestTestApp = AndroidManifestHelper.parseForData(testFilePath); assertNotNull(mManifestTestApp); testFilePath = AdtTestData.getInstance().getTestFilePath(INSTRUMENTATION_XML); - mManifestInstrumentation = AndroidManifestParser.parseForData(testFilePath); + mManifestInstrumentation = AndroidManifestHelper.parseForData(testFilePath); assertNotNull(mManifestInstrumentation); } @@ -68,7 +69,7 @@ public class AndroidManifestParserTest extends TestCase { public void testGetActivities() { assertEquals(1, mManifestTestApp.getActivities().length); - AndroidManifestParser.Activity activity = mManifestTestApp.getActivities()[0]; + Activity activity = mManifestTestApp.getActivities()[0]; assertEquals(ACTIVITY_NAME, activity.getName()); assertTrue(activity.hasAction()); assertTrue(activity.isHomeActivity()); diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/testdata/AndroidManifest-testapp.xml b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/testdata/AndroidManifest-testapp.xml index 8ae7012..cf58934 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/testdata/AndroidManifest-testapp.xml +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/testdata/AndroidManifest-testapp.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.testapp"> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testapp" + android:versionCode="42" + android:versionName="1.42"> <application android:icon="@drawable/icon"> <activity android:name="com.android.testapp.MainActivity" android:label="@string/app_name"> @@ -11,6 +14,14 @@ </activity> <uses-library android:name="android.test.runner"/> </application>" + <uses-sdk android:minSdkVersion="7"/> + <supports-screens android:resizeable="true" android:smallScreens="true" + android:anyDensity="true" android:largeScreens="true" android:normalScreens="true"/> + <uses-configuration android:reqKeyboardType="twelvekey" + android:reqTouchScreen="finger" android:reqFiveWayNav="true" android:reqHardKeyboard="true" + android:reqNavigation="nonav"/> + <uses-feature android:glEsVersion="1"/> + <uses-feature android:name="com.foo.feature"/> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.android.apis" android:label="Tests for Api Demos."/> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java index d6cf0fc..aa70cfb 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -285,6 +285,36 @@ public final class SdkConstants { public final static String PROP_SDK_ANT_TEMPLATES_REVISION = "sdk.ant.templates.revision"; //$NON-NLS-1$ + /* Android Class Constants */ + public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$ + public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$ + public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$ + public final static String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$ + public final static String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$ + public final static String CLASS_INSTRUMENTATION_RUNNER = + "android.test.InstrumentationTestRunner"; //$NON-NLS-1$ + public final static String CLASS_BUNDLE = "android.os.Bundle"; //$NON-NLS-1$ + public final static String CLASS_R = "android.R"; //$NON-NLS-1$ + public final static String CLASS_MANIFEST_PERMISSION = "android.Manifest$permission"; //$NON-NLS-1$ + public final static String CLASS_INTENT = "android.content.Intent"; //$NON-NLS-1$ + public final static String CLASS_CONTEXT = "android.content.Context"; //$NON-NLS-1$ + public final static String CLASS_VIEW = "android.view.View"; //$NON-NLS-1$ + public final static String CLASS_VIEWGROUP = "android.view.ViewGroup"; //$NON-NLS-1$ + public final static String CLASS_NAME_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$ + public final static String CLASS_VIEWGROUP_LAYOUTPARAMS = + CLASS_VIEWGROUP + "$" + CLASS_NAME_LAYOUTPARAMS; //$NON-NLS-1$ + public final static String CLASS_NAME_FRAMELAYOUT = "FrameLayout"; //$NON-NLS-1$ + public final static String CLASS_FRAMELAYOUT = + "android.widget." + CLASS_NAME_FRAMELAYOUT; //$NON-NLS-1$ + public final static String CLASS_PREFERENCE = "android.preference.Preference"; //$NON-NLS-1$ + public final static String CLASS_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$ + public final static String CLASS_PREFERENCES = + "android.preference." + CLASS_NAME_PREFERENCE_SCREEN; //$NON-NLS-1$ + public final static String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$ + public final static String CLASS_PARCELABLE = "android.os.Parcelable"; //$NON-NLS-1$ + + + /** Returns the appropriate name for the 'android' command, which is 'android.bat' for * Windows and 'android' for all other platforms. */ public static String androidCmdName() { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidManifestParser.java index 8bbd018..5c89cc6 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidManifestParser.java @@ -1,11 +1,11 @@ /* * Copyright (C) 2007 The Android Open Source Project * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.eclipse.org/org/documents/epl-v10.php + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,29 +14,23 @@ * limitations under the License. */ -package com.android.ide.eclipse.adt.internal.project; +package com.android.sdklib.xml; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener; import com.android.sdklib.SdkConstants; -import com.android.sdklib.xml.AndroidManifest; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jdt.core.IJavaProject; +import com.android.sdklib.io.IAbstractFile; +import com.android.sdklib.io.IAbstractFolder; +import com.android.sdklib.io.StreamException; +import com.sun.rowset.internal.XmlErrorHandler; + import org.xml.sax.Attributes; +import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; -import java.io.File; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Set; @@ -58,6 +52,106 @@ public class AndroidManifestParser { private final static String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; //$NON-NLS-1$ /** + * Class containing the manifest info obtained during the parsing. + */ + public static class ManifestData { + + /** Application package */ + private String mPackage; + /** List of all activities */ + private final ArrayList<Activity> mActivities = new ArrayList<Activity>(); + /** Launcher activity */ + private Activity mLauncherActivity = null; + /** list of process names declared by the manifest */ + private Set<String> mProcesses = null; + /** debuggable attribute value. If null, the attribute is not present. */ + private Boolean mDebuggable = null; + /** API level requirement. if null the attribute was not present. */ + private String mApiLevelRequirement = null; + /** List of all instrumentations declared by the manifest */ + private final ArrayList<Instrumentation> mInstrumentations = + new ArrayList<Instrumentation>(); + /** List of all libraries in use declared by the manifest */ + private final ArrayList<String> mLibraries = new ArrayList<String>(); + + /** + * Returns the package defined in the manifest, if found. + * @return The package name or null if not found. + */ + public String getPackage() { + return mPackage; + } + + /** + * Returns the list of activities found in the manifest. + * @return An array of fully qualified class names, or empty if no activity were found. + */ + public Activity[] getActivities() { + return mActivities.toArray(new Activity[mActivities.size()]); + } + + /** + * Returns the name of one activity found in the manifest, that is configured to show + * up in the HOME screen. + * @return the fully qualified name of a HOME activity or null if none were found. + */ + public Activity getLauncherActivity() { + return mLauncherActivity; + } + + /** + * Returns the list of process names declared by the manifest. + */ + public String[] getProcesses() { + if (mProcesses != null) { + return mProcesses.toArray(new String[mProcesses.size()]); + } + + return new String[0]; + } + + /** + * Returns the <code>debuggable</code> attribute value or null if it is not set. + */ + public Boolean getDebuggable() { + return mDebuggable; + } + + /** + * Returns the <code>minSdkVersion</code> attribute, or null if it's not set. + */ + public String getApiLevelRequirement() { + return mApiLevelRequirement; + } + + /** + * Returns the list of instrumentations found in the manifest. + * @return An array of {@link Instrumentation}, or empty if no instrumentations were + * found. + */ + public Instrumentation[] getInstrumentations() { + return mInstrumentations.toArray(new Instrumentation[mInstrumentations.size()]); + } + + /** + * Returns the list of libraries in use found in the manifest. + * @return An array of library names, or empty if no libraries were found. + */ + public String[] getUsesLibraries() { + return mLibraries.toArray(new String[mLibraries.size()]); + } + + private void addProcessName(String processName) { + if (mProcesses == null) { + mProcesses = new TreeSet<String>(); + } + + mProcesses.add(processName); + } + + } + + /** * Instrumentation info obtained from manifest */ public static class Instrumentation { @@ -138,38 +232,39 @@ public class AndroidManifestParser { } } + public interface ManifestErrorHandler extends ErrorHandler { + /** + * Handles a parsing error and an optional line number. + * @param exception + * @param lineNumber + */ + void handleError(Exception exception, int lineNumber); + + /** + * Checks that a class is valid and can be used in the Android Manifest. + * <p/> + * Errors are put as {@link IMarker} on the manifest file. + * @param locator + * @param className the fully qualified name of the class to test. + * @param superClassName the fully qualified name of the class it is supposed to extend. + * @param testVisibility if <code>true</code>, the method will check the visibility of + * the class or of its constructors. + */ + void checkClass(Locator locator, String className, String superClassName, + boolean testVisibility); + } + /** * XML error & data handler used when parsing the AndroidManifest.xml file. * <p/> * This serves both as an {@link XmlErrorHandler} to report errors and as a data repository * to collect data from the manifest. */ - private static class ManifestHandler extends XmlErrorHandler { - - //--- data read from the parsing - - /** Application package */ - private String mPackage; - /** List of all activities */ - private final ArrayList<Activity> mActivities = new ArrayList<Activity>(); - /** Launcher activity */ - private Activity mLauncherActivity = null; - /** list of process names declared by the manifest */ - private Set<String> mProcesses = null; - /** debuggable attribute value. If null, the attribute is not present. */ - private Boolean mDebuggable = null; - /** API level requirement. if null the attribute was not present. */ - private String mApiLevelRequirement = null; - /** List of all instrumentations declared by the manifest */ - private final ArrayList<Instrumentation> mInstrumentations = - new ArrayList<Instrumentation>(); - /** List of all libraries in use declared by the manifest */ - private final ArrayList<String> mLibraries = new ArrayList<String>(); + private static class ManifestHandler extends DefaultHandler { //--- temporary data/flags used during parsing - private IJavaProject mJavaProject; - private boolean mGatherData = false; - private boolean mMarkErrors = false; + private final ManifestData mManifestData; + private final ManifestErrorHandler mErrorHandler; private int mCurrentLevel = 0; private int mValidLevel = 0; private Activity mCurrentActivity = null; @@ -184,80 +279,13 @@ public class AndroidManifestParser { * @param javaProject The java project holding the manifest file. Can be null. * @param markErrors True if errors should be marked as Eclipse Markers on the resource. */ - ManifestHandler(IFile manifestFile, XmlErrorListener errorListener, - boolean gatherData, IJavaProject javaProject, boolean markErrors) { - super(manifestFile, errorListener); - mGatherData = gatherData; - mJavaProject = javaProject; - mMarkErrors = markErrors; - } - - /** - * Returns the package defined in the manifest, if found. - * @return The package name or null if not found. - */ - String getPackage() { - return mPackage; - } - - /** - * Returns the list of activities found in the manifest. - * @return An array of fully qualified class names, or empty if no activity were found. - */ - Activity[] getActivities() { - return mActivities.toArray(new Activity[mActivities.size()]); - } - - /** - * Returns the name of one activity found in the manifest, that is configured to show - * up in the HOME screen. - * @return the fully qualified name of a HOME activity or null if none were found. - */ - Activity getLauncherActivity() { - return mLauncherActivity; - } - - /** - * Returns the list of process names declared by the manifest. - */ - String[] getProcesses() { - if (mProcesses != null) { - return mProcesses.toArray(new String[mProcesses.size()]); - } - - return new String[0]; - } - - /** - * Returns the <code>debuggable</code> attribute value or null if it is not set. - */ - Boolean getDebuggable() { - return mDebuggable; - } - - /** - * Returns the <code>minSdkVersion</code> attribute, or null if it's not set. - */ - String getApiLevelRequirement() { - return mApiLevelRequirement; - } - - /** - * Returns the list of instrumentations found in the manifest. - * @return An array of {@link Instrumentation}, or empty if no instrumentations were - * found. - */ - Instrumentation[] getInstrumentations() { - return mInstrumentations.toArray(new Instrumentation[mInstrumentations.size()]); + ManifestHandler(IAbstractFile manifestFile, ManifestData manifestData, + ManifestErrorHandler errorHandler) { + super(); + mManifestData = manifestData; + mErrorHandler = errorHandler; } - /** - * Returns the list of libraries in use found in the manifest. - * @return An array of library names, or empty if no libraries were found. - */ - String[] getUsesLibraries() { - return mLibraries.toArray(new String[mLibraries.size()]); - } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator) @@ -276,7 +304,7 @@ public class AndroidManifestParser { public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { try { - if (mGatherData == false) { + if (mManifestData == null) { return; } @@ -287,7 +315,7 @@ public class AndroidManifestParser { case LEVEL_MANIFEST: if (AndroidManifest.NODE_MANIFEST.equals(localName)) { // lets get the package name. - mPackage = getAttributeValue(attributes, + mManifestData.mPackage = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PACKAGE, false /* hasNamespace */); mValidLevel++; @@ -299,19 +327,19 @@ public class AndroidManifestParser { AndroidManifest.ATTRIBUTE_PROCESS, true /* hasNamespace */); if (value != null) { - addProcessName(value); + mManifestData.addProcessName(value); } value = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_DEBUGGABLE, true /* hasNamespace*/); if (value != null) { - mDebuggable = Boolean.parseBoolean(value); + mManifestData.mDebuggable = Boolean.parseBoolean(value); } mValidLevel++; } else if (AndroidManifest.NODE_USES_SDK.equals(localName)) { - mApiLevelRequirement = getAttributeValue(attributes, + mManifestData.mApiLevelRequirement = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, true /* hasNamespace */); } else if (AndroidManifest.NODE_INSTRUMENTATION.equals(localName)) { @@ -323,20 +351,20 @@ public class AndroidManifestParser { processActivityNode(attributes); mValidLevel++; } else if (AndroidManifest.NODE_SERVICE.equals(localName)) { - processNode(attributes, AndroidConstants.CLASS_SERVICE); + processNode(attributes, SdkConstants.CLASS_SERVICE); mValidLevel++; } else if (AndroidManifest.NODE_RECEIVER.equals(localName)) { - processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER); + processNode(attributes, SdkConstants.CLASS_BROADCASTRECEIVER); mValidLevel++; } else if (AndroidManifest.NODE_PROVIDER.equals(localName)) { - processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER); + processNode(attributes, SdkConstants.CLASS_CONTENTPROVIDER); mValidLevel++; } else if (AndroidManifest.NODE_USES_LIBRARY.equals(localName)) { value = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME, true /* hasNamespace */); if (value != null) { - mLibraries.add(value); + mManifestData.mLibraries.add(value); } } break; @@ -389,7 +417,7 @@ public class AndroidManifestParser { @Override public void endElement(String uri, String localName, String name) throws SAXException { try { - if (mGatherData == false) { + if (mManifestData == null) { return; } @@ -409,11 +437,11 @@ public class AndroidManifestParser { case LEVEL_INTENT_FILTER: // if we found both a main action and a launcher category, this is our // launcher activity! - if (mLauncherActivity == null && + if (mManifestData.mLauncherActivity == null && mCurrentActivity != null && mCurrentActivity.isHomeActivity() && mCurrentActivity.isExported()) { - mLauncherActivity = mCurrentActivity; + mManifestData.mLauncherActivity = mCurrentActivity; } break; default: @@ -431,8 +459,8 @@ public class AndroidManifestParser { */ @Override public void error(SAXParseException e) { - if (mMarkErrors) { - handleError(e, e.getLineNumber()); + if (mErrorHandler != null) { + mErrorHandler.handleError(e, e.getLineNumber()); } } @@ -441,8 +469,8 @@ public class AndroidManifestParser { */ @Override public void fatalError(SAXParseException e) { - if (mMarkErrors) { - handleError(e, e.getLineNumber()); + if (mErrorHandler != null) { + mErrorHandler.handleError(e, e.getLineNumber()); } } @@ -451,8 +479,8 @@ public class AndroidManifestParser { */ @Override public void warning(SAXParseException e) throws SAXException { - if (mMarkErrors) { - super.warning(e); + if (mErrorHandler != null) { + mErrorHandler.warning(e); } } @@ -465,7 +493,8 @@ public class AndroidManifestParser { String activityName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME, true /* hasNamespace */); if (activityName != null) { - activityName = AndroidManifest.combinePackageAndClassName(mPackage, activityName); + activityName = AndroidManifest.combinePackageAndClassName(mManifestData.mPackage, + activityName); // get the exported flag. String exportedStr = getAttributeValue(attributes, @@ -473,10 +502,10 @@ public class AndroidManifestParser { boolean exported = exportedStr == null || exportedStr.toLowerCase().equals("true"); // $NON-NLS-1$ mCurrentActivity = new Activity(activityName, exported); - mActivities.add(mCurrentActivity); + mManifestData.mActivities.add(mCurrentActivity); - if (mMarkErrors) { - checkClass(activityName, AndroidConstants.CLASS_ACTIVITY, + if (mErrorHandler != null) { + mErrorHandler.checkClass(mLocator, activityName, SdkConstants.CLASS_ACTIVITY, true /* testVisibility */); } } else { @@ -488,7 +517,7 @@ public class AndroidManifestParser { String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS, true /* hasNamespace */); if (processName != null) { - addProcessName(processName); + mManifestData.addProcessName(processName); } } @@ -503,17 +532,19 @@ public class AndroidManifestParser { String serviceName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME, true /* hasNamespace */); if (serviceName != null) { - serviceName = AndroidManifest.combinePackageAndClassName(mPackage, serviceName); + serviceName = AndroidManifest.combinePackageAndClassName(mManifestData.mPackage, + serviceName); - if (mMarkErrors) { - checkClass(serviceName, superClassName, false /* testVisibility */); + if (mErrorHandler != null) { + mErrorHandler.checkClass(mLocator, serviceName, superClassName, + false /* testVisibility */); } } String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS, true /* hasNamespace */); if (processName != null) { - addProcessName(processName); + mManifestData.addProcessName(processName); } } @@ -528,51 +559,16 @@ public class AndroidManifestParser { AndroidManifest.ATTRIBUTE_NAME, true /* hasNamespace */); if (instrumentationName != null) { - String instrClassName = AndroidManifest.combinePackageAndClassName(mPackage, - instrumentationName); + String instrClassName = AndroidManifest.combinePackageAndClassName( + mManifestData.mPackage, instrumentationName); String targetPackage = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_TARGET_PACKAGE, true /* hasNamespace */); - mInstrumentations.add(new Instrumentation(instrClassName, targetPackage)); - if (mMarkErrors) { - checkClass(instrClassName, AndroidConstants.CLASS_INSTRUMENTATION, - true /* testVisibility */); - } - } - } - - /** - * Checks that a class is valid and can be used in the Android Manifest. - * <p/> - * Errors are put as {@link IMarker} on the manifest file. - * @param className the fully qualified name of the class to test. - * @param superClassName the fully qualified name of the class it is supposed to extend. - * @param testVisibility if <code>true</code>, the method will check the visibility of - * the class or of its constructors. - */ - private void checkClass(String className, String superClassName, boolean testVisibility) { - if (mJavaProject == null) { - return; - } - // we need to check the validity of the activity. - String result = BaseProjectHelper.testClassForManifest(mJavaProject, - className, superClassName, testVisibility); - if (result != BaseProjectHelper.TEST_CLASS_OK) { - // get the line number - int line = mLocator.getLineNumber(); - - // mark the file - IMarker marker = BaseProjectHelper.markResource(getFile(), - AndroidConstants.MARKER_ANDROID, result, line, IMarker.SEVERITY_ERROR); - - // add custom attributes to be used by the manifest editor. - if (marker != null) { - try { - marker.setAttribute(AndroidConstants.MARKER_ATTR_TYPE, - AndroidConstants.MARKER_ATTR_TYPE_ACTIVITY); - marker.setAttribute(AndroidConstants.MARKER_ATTR_CLASS, className); - } catch (CoreException e) { - } + mManifestData.mInstrumentations.add( + new Instrumentation(instrClassName, targetPackage)); + if (mErrorHandler != null) { + mErrorHandler.checkClass(mLocator, instrClassName, + SdkConstants.CLASS_INSTRUMENTATION, true /* testVisibility */); } } } @@ -600,25 +596,9 @@ public class AndroidManifestParser { return null; } - private void addProcessName(String processName) { - if (mProcesses == null) { - mProcesses = new TreeSet<String>(); - } - - mProcesses.add(processName); - } } - private static SAXParserFactory sParserFactory; - - private final String mJavaPackage; - private final Activity[] mActivities; - private final Activity mLauncherActivity; - private final String[] mProcesses; - private final Boolean mDebuggable; - private final String mApiLevelRequirement; - private final Instrumentation[] mInstrumentations; - private final String[] mLibraries; + private final static SAXParserFactory sParserFactory; static { sParserFactory = SAXParserFactory.newInstance(); @@ -626,330 +606,82 @@ public class AndroidManifestParser { } /** - * Parses the Android Manifest, and returns an object containing the result of the parsing. - * <p/> - * This method is useful to parse a specific {@link IFile} in a Java project. - * <p/> - * If you only want to gather data, consider {@link #parseForData(IFile)} instead. - * - * @param javaProject The java project. - * @param manifestFile the {@link IFile} representing the manifest file. - * @param errorListener - * @param gatherData indicates whether the parsing will extract data from the manifest. - * @param markErrors indicates whether the error found during parsing should put a - * marker on the file. For class validation errors to put a marker, <code>gatherData</code> - * must be set to <code>true</code> - * @return an {@link AndroidManifestParser} or null if the parsing failed. - * @throws CoreException - */ - public static AndroidManifestParser parse( - IJavaProject javaProject, - IFile manifestFile, - XmlErrorListener errorListener, - boolean gatherData, - boolean markErrors) - throws CoreException { - try { - if (manifestFile != null) { - SAXParser parser = sParserFactory.newSAXParser(); - - ManifestHandler manifestHandler = new ManifestHandler(manifestFile, - errorListener, gatherData, javaProject, markErrors); - parser.parse(new InputSource(manifestFile.getContents()), manifestHandler); - - // get the result from the handler - return new AndroidManifestParser(manifestHandler.getPackage(), - manifestHandler.getActivities(), - manifestHandler.getLauncherActivity(), - manifestHandler.getProcesses(), - manifestHandler.getDebuggable(), - manifestHandler.getApiLevelRequirement(), - manifestHandler.getInstrumentations(), - manifestHandler.getUsesLibraries()); - } - } catch (ParserConfigurationException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Bad parser configuration for %s: %s", - manifestFile.getFullPath(), - e.getMessage()); - } catch (SAXException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Parser exception for %s: %s", - manifestFile.getFullPath(), - e.getMessage()); - } catch (IOException e) { - // Don't log a console error when failing to read a non-existing file - if (!(e instanceof FileNotFoundException)) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "I/O error for %s: %s", - manifestFile.getFullPath(), - e.getMessage()); - } - } - - return null; - } - - /** - * Parses the Android Manifest, and returns an object containing the result of the parsing. - * <p/> - * This version parses a real {@link File} file given by an actual path, which is useful for - * parsing a file that is not part of an Eclipse Java project. - * <p/> - * It assumes errors cannot be marked on the file and that data gathering is enabled. + * Parses the Android Manifest, and returns a {@link ManifestData} object containing the + * result of the parsing. * - * @param manifestFile the manifest file to parse. - * @return an {@link AndroidManifestParser} or null if the parsing failed. - * @throws CoreException + * @param manifestFile the {@link IAbstractFile} representing the manifest file. + * @param gatherData indicates whether the parsing will extract data from the manifest. If false + * the method will always return null. + * @param errorHandler an optional errorHandler. + * @return + * @throws StreamException + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException */ - private static AndroidManifestParser parse(File manifestFile) - throws CoreException { - try { + public static ManifestData parse( + IAbstractFile manifestFile, + boolean gatherData, + ManifestErrorHandler errorHandler) + throws SAXException, IOException, StreamException, ParserConfigurationException { + if (manifestFile != null) { SAXParser parser = sParserFactory.newSAXParser(); - ManifestHandler manifestHandler = new ManifestHandler( - null, //manifestFile - null, //errorListener - true, //gatherData - null, //javaProject - false //markErrors - ); - - parser.parse(new InputSource(new FileReader(manifestFile)), manifestHandler); - - // get the result from the handler - - return new AndroidManifestParser(manifestHandler.getPackage(), - manifestHandler.getActivities(), - manifestHandler.getLauncherActivity(), - manifestHandler.getProcesses(), - manifestHandler.getDebuggable(), - manifestHandler.getApiLevelRequirement(), - manifestHandler.getInstrumentations(), - manifestHandler.getUsesLibraries()); - } catch (ParserConfigurationException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Bad parser configuration for %s: %s", - manifestFile.getAbsolutePath(), - e.getMessage()); - } catch (SAXException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Parser exception for %s: %s", - manifestFile.getAbsolutePath(), - e.getMessage()); - } catch (IOException e) { - // Don't log a console error when failing to read a non-existing file - if (!(e instanceof FileNotFoundException)) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "I/O error for %s: %s", - manifestFile.getAbsolutePath(), - e.getMessage()); + ManifestData data = null; + if (gatherData) { + data = new ManifestData(); } - } - - return null; - } - - /** - * Parses the Android Manifest for the specified project, and returns an object containing - * the result of the parsing. - * @param javaProject The java project. Required if <var>markErrors</var> is <code>true</code> - * @param errorListener the {@link XmlErrorListener} object being notified of the presence - * of errors. Optional. - * @param gatherData indicates whether the parsing will extract data from the manifest. - * @param markErrors indicates whether the error found during parsing should put a - * marker on the file. For class validation errors to put a marker, <code>gatherData</code> - * must be set to <code>true</code> - * @return an {@link AndroidManifestParser} or null if the parsing failed. - * @throws CoreException - */ - public static AndroidManifestParser parse( - IJavaProject javaProject, - XmlErrorListener errorListener, - boolean gatherData, - boolean markErrors) - throws CoreException { - - IFile manifestFile = getManifest(javaProject.getProject()); - - try { - SAXParser parser = sParserFactory.newSAXParser(); - - if (manifestFile != null) { - ManifestHandler manifestHandler = new ManifestHandler(manifestFile, - errorListener, gatherData, javaProject, markErrors); - parser.parse(new InputSource(manifestFile.getContents()), manifestHandler); + ManifestHandler manifestHandler = new ManifestHandler(manifestFile, + data, errorHandler); + parser.parse(new InputSource(manifestFile.getContents()), manifestHandler); - // get the result from the handler - return new AndroidManifestParser(manifestHandler.getPackage(), - manifestHandler.getActivities(), manifestHandler.getLauncherActivity(), - manifestHandler.getProcesses(), manifestHandler.getDebuggable(), - manifestHandler.getApiLevelRequirement(), - manifestHandler.getInstrumentations(), manifestHandler.getUsesLibraries()); - } - } catch (ParserConfigurationException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Bad parser configuration for %s", manifestFile.getFullPath()); - } catch (SAXException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "Parser exception for %s", manifestFile.getFullPath()); - } catch (IOException e) { - AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(), - "I/O error for %s", manifestFile.getFullPath()); + return data; } return null; } /** - * Parses the manifest file, collects data, and checks for errors. - * @param javaProject The java project. Required. - * @param manifestFile The manifest file to parse. - * @param errorListener the {@link XmlErrorListener} object being notified of the presence - * of errors. Optional. - * @return an {@link AndroidManifestParser} or null if the parsing failed. - * @throws CoreException - */ - public static AndroidManifestParser parseForError(IJavaProject javaProject, IFile manifestFile, - XmlErrorListener errorListener) throws CoreException { - return parse(javaProject, manifestFile, errorListener, true, true); - } - - /** - * Parses the manifest file, and collects data. - * @param manifestFile The manifest file to parse. - * @return an {@link AndroidManifestParser} or null if the parsing failed. - * @throws CoreException for example the file does not exist in the workspace or - * the workspace needs to be refreshed. - */ - public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException { - return parse(null /* javaProject */, manifestFile, null /* errorListener */, - true /* gatherData */, false /* markErrors */); - } - - /** - * Parses the manifest file, and collects data. + * Parses the Android Manifest, and returns an object containing the result of the parsing. * - * @param osManifestFilePath The OS path of the manifest file to parse. - * @return an {@link AndroidManifestParser} or null if the parsing failed. - */ - public static AndroidManifestParser parseForData(String osManifestFilePath) { - try { - return parse(new File(osManifestFilePath)); - } catch (CoreException e) { - // Ignore workspace errors (unlikely to happen since this parses an actual file, - // not a workspace resource). - return null; - } - } - - /** - * Returns the package defined in the manifest, if found. - * @return The package name or null if not found. - */ - public String getPackage() { - return mJavaPackage; - } - - /** - * Returns the list of activities found in the manifest. - * @return An array of {@link Activity}, or empty if no activity were found. - */ - public Activity[] getActivities() { - return mActivities; - } - - /** - * Returns the name of one activity found in the manifest, that is configured to show - * up in the HOME screen. - * @return The {@link Activity} representing a HOME activity or null if none were found. - */ - public Activity getLauncherActivity() { - return mLauncherActivity; - } - - /** - * Returns the list of process names declared by the manifest. - */ - public String[] getProcesses() { - return mProcesses; - } - - /** - * Returns the debuggable attribute value or <code>null</code> if it is not set. - */ - public Boolean getDebuggable() { - return mDebuggable; - } - - /** - * Returns the <code>minSdkVersion</code> attribute, or null if it's not set. - */ - public String getApiLevelRequirement() { - return mApiLevelRequirement; - } - - /** - * Returns the list of instrumentations found in the manifest. - * @return An array of {@link Instrumentation}, or empty if no instrumentations were found. - */ - public Instrumentation[] getInstrumentations() { - return mInstrumentations; - } - - /** - * Returns the list of libraries in use found in the manifest. - * @return An array of library names, or empty if no uses-library declarations were found. + * <p/> + * This is the equivalent of calling <pre>parse(manifestFile, true, null)</pre> + * + * @param manifestFile the manifest file to parse. + * @throws ParserConfigurationException + * @throws StreamException + * @throws IOException + * @throws SAXException */ - public String[] getUsesLibraries() { - return mLibraries; + public static ManifestData parse(IAbstractFile manifestFile) + throws SAXException, IOException, StreamException, ParserConfigurationException { + return parse(manifestFile, true, null); } + public static ManifestData parse(IAbstractFolder projectFolder) + throws SAXException, IOException, StreamException, ParserConfigurationException { + IAbstractFile manifestFile = getManifest(projectFolder); + if (manifestFile == null) { + throw new FileNotFoundException(); + } - /** - * Private constructor to enforce using - * {@link #parse(IJavaProject, XmlErrorListener, boolean, boolean)}, - * {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)}, - * or {@link #parseForError(IJavaProject, IFile, XmlErrorListener)} to get an - * {@link AndroidManifestParser} object. - * @param javaPackage the package parsed from the manifest. - * @param activities the list of activities parsed from the manifest. - * @param launcherActivity the launcher activity parser from the manifest. - * @param processes the list of custom processes declared in the manifest. - * @param debuggable the debuggable attribute, or null if not set. - * @param apiLevelRequirement the minSdkVersion attribute value or null if not set. - * @param instrumentations the list of instrumentations parsed from the manifest. - * @param libraries the list of libraries in use parsed from the manifest. - */ - private AndroidManifestParser(String javaPackage, Activity[] activities, - Activity launcherActivity, String[] processes, Boolean debuggable, - String apiLevelRequirement, Instrumentation[] instrumentations, String[] libraries) { - mJavaPackage = javaPackage; - mActivities = activities; - mLauncherActivity = launcherActivity; - mProcesses = processes; - mDebuggable = debuggable; - mApiLevelRequirement = apiLevelRequirement; - mInstrumentations = instrumentations; - mLibraries = libraries; + return parse(manifestFile, true, null); } /** - * Returns an IFile object representing the manifest for the specified - * project. + * Returns an {@link IAbstractFile} object representing the manifest for the given project. * * @param project The project containing the manifest file. - * @return An IFile object pointing to the manifest or null if the manifest + * @return An IAbstractFile object pointing to the manifest or null if the manifest * is missing. */ - public static IFile getManifest(IProject project) { - IResource r = project.findMember(AndroidConstants.WS_SEP - + AndroidConstants.FN_ANDROID_MANIFEST); - - if (r == null || r.exists() == false || (r instanceof IFile) == false) { - return null; + public static IAbstractFile getManifest(IAbstractFolder projectFolder) { + IAbstractFile file = projectFolder.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); + if (file.exists()) { + return file; } - return (IFile) r; + + return null; } } |