From 3b0c290370e679d007c2b93d26254f82df46df35 Mon Sep 17 00:00:00 2001 From: Raphael Moll Date: Tue, 5 Oct 2010 17:09:38 -0700 Subject: [PATCH] SDK Manager: support separate addon.xml schema This splits sdk-repository-3.xsd into 2 XML schemas, one for the sdk-repository and one for the sdk-addon. The SDK Manager is then modified to only load and from the sdk-addon whils the supports everything (including if the old v1 or v2 schemas are being used). Change-Id: I30b263f2ab48dd3ea7b70d3006fb6516291736d0 --- .../ide/eclipse/adt/annotations/Nullable.java | 3 + .../eclipse/adt/annotations/VisibleForTesting.java | 3 + .../app/src/com/android/sdkmanager/Main.java | 6 +- .../src/com/android/sdkmanager/SdkCommandLine.java | 4 +- .../sdkmanager/internal/repository/AboutPage.java | 4 +- .../com/android/sdklib/annotations/Nullable.java | 35 ++ .../sdklib/annotations/VisibleForTesting.java | 50 +++ .../sdklib/internal/repository/AddonPackage.java | 29 +- .../sdklib/internal/repository/Archive.java | 4 +- .../sdklib/internal/repository/DocPackage.java | 19 +- .../sdklib/internal/repository/ExtraPackage.java | 19 +- .../repository/IMinApiLevelDependency.java | 4 +- .../repository/IMinPlatformToolsDependency.java | 4 +- .../internal/repository/IMinToolsDependency.java | 6 +- .../sdklib/internal/repository/LocalSdkParser.java | 7 + .../internal/repository/MinToolsPackage.java | 18 +- .../sdklib/internal/repository/Package.java | 55 ++- .../internal/repository/PlatformPackage.java | 19 +- .../internal/repository/PlatformToolPackage.java | 14 +- .../sdklib/internal/repository/SamplePackage.java | 19 +- .../sdklib/internal/repository/SdkAddonSource.java | 99 +++++ .../sdklib/internal/repository/SdkRepoSource.java | 470 +++++++++++++++++++++ .../repository/{RepoSource.java => SdkSource.java} | 419 +++++------------- .../{RepoSources.java => SdkSources.java} | 28 +- .../sdklib/internal/repository/ToolPackage.java | 45 +- .../{SdkRepository.java => CommonConstants.java} | 79 +--- .../sdklib/repository/SdkAddonConstants.java | 84 ++++ .../sdklib/repository/SdkRepoConstants.java | 96 +++++ .../com/android/sdklib/repository/sdk-addon-1.xsd | 287 +++++++++++++ .../android/sdklib/repository/sdk-repository-3.xsd | 65 +-- ...RepoSourceTest.java => SdkAddonSourceTest.java} | 140 +++++- .../internal/repository/SdkRepoSourceTest.java | 342 +++++++++++++++ .../sdklib/repository/SdkRepositoryTest.java | 18 +- .../com/android/sdklib/testdata/addon_sample_1.xml | 144 +++++++ .../sdklib/testdata/repository_sample_3.xml | 74 ---- .../internal/repository/LocalSdkAdapter.java | 4 +- .../internal/repository/RemotePackagesPage.java | 19 +- .../internal/repository/RepoSourcesAdapter.java | 30 +- .../internal/repository/UpdateNoWindow.java | 4 +- .../sdkuilib/internal/repository/UpdaterData.java | 36 +- .../sdkuilib/internal/repository/UpdaterLogic.java | 30 +- .../internal/repository/icons/ImageFactory.java | 6 +- .../internal/repository/UpdaterLogicTest.java | 10 +- 43 files changed, 2114 insertions(+), 737 deletions(-) create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/Nullable.java create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/VisibleForTesting.java create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkAddonSource.java create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkRepoSource.java rename sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/{RepoSource.java => SdkSource.java} (61%) rename sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/{RepoSources.java => SdkSources.java} (83%) rename sdkmanager/libs/sdklib/src/com/android/sdklib/repository/{SdkRepository.java => CommonConstants.java} (61%) create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java create mode 100755 sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd rename sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/{RepoSourceTest.java => SdkAddonSourceTest.java} (50%) create mode 100755 sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkRepoSourceTest.java create mode 100755 sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/addon_sample_1.xml diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/Nullable.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/Nullable.java index 6ea5b3608..ca0f3747a 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/Nullable.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/Nullable.java @@ -29,7 +29,10 @@ import java.lang.annotation.RetentionPolicy; * When decorating a method, this denotes the method might legitimately return null. *

* This is a marker annotation and it has no specific attributes. + * + * @deprecated TODO use the version moved into sdklib instead */ +@Deprecated @Retention(RetentionPolicy.SOURCE) public @interface Nullable { } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/VisibleForTesting.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/VisibleForTesting.java index b495692b0..9e26bdfe4 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/VisibleForTesting.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/annotations/VisibleForTesting.java @@ -26,7 +26,10 @@ import java.lang.annotation.RetentionPolicy; * The visibility argument can be used to specific what the original * visibility should have been if it had not been made public or package-private for testing. * The default is to consider the element private. + * + * @deprecated TODO use the version moved into sdklib instead */ +@Deprecated @Retention(RetentionPolicy.SOURCE) public @interface VisibleForTesting { /** diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java index 222cd4096..0066b6ce4 100644 --- a/sdkmanager/app/src/com/android/sdkmanager/Main.java +++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java @@ -32,7 +32,7 @@ import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.internal.project.ProjectCreator.OutputLevel; import com.android.sdklib.internal.project.ProjectProperties.PropertyType; import com.android.sdklib.io.FileWrapper; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import com.android.sdklib.xml.AndroidXPathFactory; import com.android.sdkmanager.internal.repository.AboutPage; import com.android.sdkmanager.internal.repository.SettingsPage; @@ -332,7 +332,7 @@ public class Main { t = t.trim(); if (t.length() > 0) { boolean found = false; - for (String t2 : SdkRepository.NODES) { + for (String t2 : SdkRepoConstants.NODES) { if (t2.equals(t)) { pkgFilter.add(t2); found = true; @@ -343,7 +343,7 @@ public class Main { errorAndExit( "Unknown package filter type '%1$s'.\nAccepted values are: %2$s", t, - Arrays.toString(SdkRepository.NODES)); + Arrays.toString(SdkRepoConstants.NODES)); return; } } diff --git a/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java index b0c0e504d..2cc721d50 100644 --- a/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java +++ b/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java @@ -18,7 +18,7 @@ package com.android.sdkmanager; import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkManager; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import java.util.Arrays; @@ -207,7 +207,7 @@ class SdkCommandLine extends CommandLineProcessor { define(Mode.STRING, false, VERB_UPDATE, OBJECT_SDK, "t", KEY_FILTER, "A filter that limits the update to the specified types of packages in the form of\n" + - " a comma-separated list of " + Arrays.toString(SdkRepository.NODES), + " a comma-separated list of " + Arrays.toString(SdkRepoConstants.NODES), null); define(Mode.BOOLEAN, false, diff --git a/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java b/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java index fa05b2915..114aa22d8 100755 --- a/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java +++ b/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java @@ -19,7 +19,7 @@ package com.android.sdkmanager.internal.repository; import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import com.android.sdkmanager.*; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; @@ -70,7 +70,7 @@ public class AboutPage extends Composite { "Repository XML Schema #%2$d\n" + "Copyright (C) 2009-2010 The Android Open Source Project.", getRevision(), - SdkRepository.NS_LATEST_VERSION)); + SdkRepoConstants.NS_LATEST_VERSION)); } @Override diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/Nullable.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/Nullable.java new file mode 100755 index 000000000..3b5e9553b --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/Nullable.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 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.sdklib.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Denotes a parameter or field can be null. + *

+ * When decorating a method call parameter, this denotes the parameter can + * legitimately be null and the method will gracefully deal with it. Typically used + * on optional parameters. + *

+ * When decorating a method, this denotes the method might legitimately return null. + *

+ * This is a marker annotation and it has no specific attributes. + */ +@Retention(RetentionPolicy.SOURCE) +public @interface Nullable { +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/VisibleForTesting.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/VisibleForTesting.java new file mode 100755 index 000000000..86d1c9961 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/annotations/VisibleForTesting.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 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.sdklib.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Denotes that the class, method or field has its visibility relaxed so + * that unit tests can access it. + *

+ * The visibility argument can be used to specific what the original + * visibility should have been if it had not been made public or package-private for testing. + * The default is to consider the element private. + */ +@Retention(RetentionPolicy.SOURCE) +public @interface VisibleForTesting { + /** + * Intended visibility if the element had not been made public or package-private for + * testing. + */ + enum Visibility { + /** The element should be considered protected. */ + PROTECTED, + /** The element should be considered package-private. */ + PACKAGE, + /** The element should be considered private. */ + PRIVATE + } + + /** + * Intended visibility if the element had not been made public or package-private for testing. + * If not specified, one should assume the element originally intended to be private. + */ + Visibility visibility() default Visibility.PRIVATE; +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java index ae630e324..39750d474 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java @@ -23,7 +23,7 @@ import com.android.sdklib.SdkManager; import com.android.sdklib.IAndroidTarget.IOptionalLibrary; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -68,21 +68,26 @@ public class AddonPackage extends Package /** * Creates a new add-on package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - AddonPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); - mVendor = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_VENDOR); - mName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_NAME); - int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0); - String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME); + AddonPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); + mVendor = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_VENDOR); + mName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_NAME); + int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); + String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); if (codeName.length() == 0) { codeName = null; } mVersion = new AndroidVersion(apiLevel, codeName); - mLibs = parseLibs(XmlParserUtils.getFirstChild(packageNode, SdkRepository.NODE_LIBS)); + mLibs = parseLibs(XmlParserUtils.getFirstChild(packageNode, SdkRepoConstants.NODE_LIBS)); } /** @@ -151,7 +156,7 @@ public class AddonPackage extends Package if (child.getNodeType() == Node.ELEMENT_NODE && nsUri.equals(child.getNamespaceURI()) && - SdkRepository.NODE_LIB.equals(child.getLocalName())) { + SdkRepoConstants.NODE_LIB.equals(child.getLocalName())) { libs.add(parseLib(child)); } } @@ -164,8 +169,8 @@ public class AddonPackage extends Package * Parses a element from a container. */ private Lib parseLib(Node libNode) { - return new Lib(XmlParserUtils.getXmlString(libNode, SdkRepository.NODE_NAME), - XmlParserUtils.getXmlString(libNode, SdkRepository.NODE_DESCRIPTION)); + return new Lib(XmlParserUtils.getXmlString(libNode, SdkRepoConstants.NODE_NAME), + XmlParserUtils.getXmlString(libNode, SdkRepoConstants.NODE_DESCRIPTION)); } /** Returns the vendor, a string, for add-on packages. */ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java index 21cae7ae6..86f041ca4 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java @@ -42,7 +42,7 @@ import java.util.Properties; * A package has some attributes (revision, description) and a list of archives * which represent the downloadable bits. *

- * Packages are offered by a {@link RepoSource} (a download site). + * Packages are offered by a {@link SdkSource} (a download site). */ public class Archive implements IDescription { @@ -434,7 +434,7 @@ public class Archive implements IDescription { && !link.startsWith("ftp://")) { //$NON-NLS-1$ // Make the URL absolute by prepending the source Package pkg = getParentPackage(); - RepoSource src = pkg.getParentSource(); + SdkSource src = pkg.getParentSource(); if (src == null) { monitor.setResult("Internal error: no source for archive %1$s", name); return null; diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java index 6980bac80..3bfd63987 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java @@ -21,7 +21,7 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -42,14 +42,19 @@ public class DocPackage extends Package implements IPackageVersion { /** * Creates a new doc package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - DocPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + DocPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); - int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0); - String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME); + int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); + String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); if (codeName.length() == 0) { codeName = null; } @@ -63,7 +68,7 @@ public class DocPackage extends Package implements IPackageVersion { *

* By design, this creates a package with one and only one archive. */ - DocPackage(RepoSource source, + DocPackage(SdkSource source, Properties props, int apiLevel, String codename, diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java index 4b7950899..622b8ba63 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java @@ -20,7 +20,7 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -53,15 +53,20 @@ public class ExtraPackage extends MinToolsPackage /** * Creates a new tool package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - ExtraPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + ExtraPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); - mPath = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_PATH); + mPath = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_PATH); - mMinApiLevel = XmlParserUtils.getXmlInt(packageNode, SdkRepository.NODE_MIN_API_LEVEL, + mMinApiLevel = XmlParserUtils.getXmlInt(packageNode, SdkRepoConstants.NODE_MIN_API_LEVEL, MIN_API_LEVEL_NOT_SPECIFIED); } @@ -72,7 +77,7 @@ public class ExtraPackage extends MinToolsPackage *

* By design, this creates a package with one and only one archive. */ - ExtraPackage(RepoSource source, + ExtraPackage(SdkSource source, Properties props, String path, int revision, diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinApiLevelDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinApiLevelDependency.java index 76c1955cf..14e674409 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinApiLevelDependency.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinApiLevelDependency.java @@ -16,7 +16,7 @@ package com.android.sdklib.internal.repository; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; /** * Interface used to decorate a {@link Package} that has a dependency @@ -28,7 +28,7 @@ import com.android.sdklib.repository.SdkRepository; public interface IMinApiLevelDependency { /** - * The value of {@link #getMinApiLevel()} when the {@link SdkRepository#NODE_MIN_API_LEVEL} + * The value of {@link #getMinApiLevel()} when the {@link SdkRepoConstants#NODE_MIN_API_LEVEL} * was not specified in the XML source. */ public static final int MIN_API_LEVEL_NOT_SPECIFIED = 0; diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinPlatformToolsDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinPlatformToolsDependency.java index 7bdfba43d..c536b3e54 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinPlatformToolsDependency.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinPlatformToolsDependency.java @@ -16,7 +16,7 @@ package com.android.sdklib.internal.repository; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; /** * Interface used to decorate a {@link Package} that has a dependency @@ -30,7 +30,7 @@ public interface IMinPlatformToolsDependency { /** * The value of {@link #getMinPlatformToolsRevision()} when the - * {@link SdkRepository#NODE_MIN_PLATFORM_TOOLS_REV} was not specified in the XML source. + * {@link SdkRepoConstants#NODE_MIN_PLATFORM_TOOLS_REV} was not specified in the XML source. * Since this is a required attribute in the XML schema, it can only happen when dealing * with an invalid repository XML. */ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinToolsDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinToolsDependency.java index 669806b2a..2f0b8fa47 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinToolsDependency.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IMinToolsDependency.java @@ -16,7 +16,7 @@ package com.android.sdklib.internal.repository; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; /** * Interface used to decorate a {@link Package} that has a dependency @@ -28,8 +28,8 @@ import com.android.sdklib.repository.SdkRepository; public interface IMinToolsDependency { /** - * The value of {@link #getMinToolsRevision()} when the {@link SdkRepository#NODE_MIN_TOOLS_REV} - * was not specified in the XML source. + * The value of {@link #getMinToolsRevision()} when the + * {@link SdkRepoConstants#NODE_MIN_TOOLS_REV} was not specified in the XML source. */ public static final int MIN_TOOLS_REV_NOT_SPECIFIED = 0; diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java index e4a96e595..51549f320 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java @@ -278,6 +278,13 @@ public class LocalSdkParser { // We're not going to check that all tools are present. At the very least // we should expect to find adb, aidl, aapt and dx (adapted to the current OS). + + if (platformToolsFolder.listFiles() == null) { + // ListFiles is null if the directory doesn't even exist. + // Not going to find anything in there... + return null; + } + Set names = new HashSet(); for (File file : platformToolsFolder.listFiles()) { names.add(file.getName()); diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java index 22011738f..a95e69cd7 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java @@ -18,7 +18,7 @@ package com.android.sdklib.internal.repository; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -40,13 +40,19 @@ public abstract class MinToolsPackage extends Package implements IMinToolsDepend /** * Creates a new package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - MinToolsPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + MinToolsPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); - mMinToolsRevision = XmlParserUtils.getXmlInt(packageNode, SdkRepository.NODE_MIN_TOOLS_REV, + mMinToolsRevision = XmlParserUtils.getXmlInt(packageNode, + SdkRepoConstants.NODE_MIN_TOOLS_REV, MIN_TOOLS_REV_NOT_SPECIFIED); } @@ -60,7 +66,7 @@ public abstract class MinToolsPackage extends Package implements IMinToolsDepend * By design, this creates a package with one and only one archive. */ public MinToolsPackage( - RepoSource source, + SdkSource source, Properties props, int revision, String license, diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java index 2046bf960..1bcac3fd6 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java @@ -20,7 +20,7 @@ import com.android.sdklib.AndroidVersion; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -36,7 +36,7 @@ import java.util.Properties; * A package has some attributes (revision, description) and a list of archives * which represent the downloadable bits. *

- * Packages are contained by a {@link RepoSource} (a download site). + * Packages are contained by a {@link SdkSource} (a download site). *

* Derived classes must implement the {@link IDescription} methods. */ @@ -60,7 +60,7 @@ public abstract class Package implements IDescription, Comparable { private final String mReleaseNote; private final String mReleaseUrl; private final Archive[] mArchives; - private final RepoSource mSource; + private final SdkSource mSource; /** * Enum for the result of {@link Package#canBeUpdatedBy(Package)}. This used so that we can @@ -79,22 +79,27 @@ public abstract class Package implements IDescription, Comparable { /** * Creates a new package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - Package(RepoSource source, Node packageNode, Map licenses) { + Package(SdkSource source, Node packageNode, String nsUri, Map licenses) { mSource = source; - mRevision = XmlParserUtils.getXmlInt (packageNode, SdkRepository.NODE_REVISION, 0); - mDescription = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION); - mDescUrl = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_DESC_URL); - mReleaseNote = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_RELEASE_NOTE); - mReleaseUrl = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_RELEASE_URL); + mRevision = XmlParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_REVISION, 0); + mDescription = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_DESCRIPTION); + mDescUrl = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_DESC_URL); + mReleaseNote = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_RELEASE_NOTE); + mReleaseUrl = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_RELEASE_URL); mObsolete = XmlParserUtils.getOptionalXmlString( - packageNode, SdkRepository.NODE_OBSOLETE); + packageNode, SdkRepoConstants.NODE_OBSOLETE); mLicense = parseLicense(packageNode, licenses); mArchives = parseArchives(XmlParserUtils.getFirstChild( - packageNode, SdkRepository.NODE_ARCHIVES)); + packageNode, SdkRepoConstants.NODE_ARCHIVES)); } /** @@ -107,7 +112,7 @@ public abstract class Package implements IDescription, Comparable { * By design, this creates a package with one and only one archive. */ public Package( - RepoSource source, + SdkSource source, Properties props, int revision, String license, @@ -139,7 +144,11 @@ public abstract class Package implements IDescription, Comparable { if (props != null && source == null && srcUrl != null) { boolean isUser = Boolean.parseBoolean(props.getProperty(PROP_USER_SOURCE, Boolean.TRUE.toString())); - source = new RepoSource(srcUrl, isUser); + if (isUser || (this instanceof AddonPackage)) { + source = new SdkAddonSource(srcUrl, isUser); + } else { + source = new SdkRepoSource(srcUrl); + } } mSource = source; @@ -202,9 +211,9 @@ public abstract class Package implements IDescription, Comparable { */ private String parseLicense(Node packageNode, Map licenses) { Node usesLicense = XmlParserUtils.getFirstChild( - packageNode, SdkRepository.NODE_USES_LICENSE); + packageNode, SdkRepoConstants.NODE_USES_LICENSE); if (usesLicense != null) { - Node ref = usesLicense.getAttributes().getNamedItem(SdkRepository.ATTR_REF); + Node ref = usesLicense.getAttributes().getNamedItem(SdkRepoConstants.ATTR_REF); if (ref != null) { String licenseRef = ref.getNodeValue(); return licenses.get(licenseRef); @@ -227,7 +236,7 @@ public abstract class Package implements IDescription, Comparable { if (child.getNodeType() == Node.ELEMENT_NODE && nsUri.equals(child.getNamespaceURI()) && - SdkRepository.NODE_ARCHIVE.equals(child.getLocalName())) { + SdkRepoConstants.NODE_ARCHIVE.equals(child.getLocalName())) { archives.add(parseArchive(child)); } } @@ -242,13 +251,13 @@ public abstract class Package implements IDescription, Comparable { private Archive parseArchive(Node archiveNode) { Archive a = new Archive( this, - (Os) XmlParserUtils.getEnumAttribute(archiveNode, SdkRepository.ATTR_OS, + (Os) XmlParserUtils.getEnumAttribute(archiveNode, SdkRepoConstants.ATTR_OS, Os.values(), null), - (Arch) XmlParserUtils.getEnumAttribute(archiveNode, SdkRepository.ATTR_ARCH, + (Arch) XmlParserUtils.getEnumAttribute(archiveNode, SdkRepoConstants.ATTR_ARCH, Arch.values(), Arch.ANY), - XmlParserUtils.getXmlString(archiveNode, SdkRepository.NODE_URL), - XmlParserUtils.getXmlLong (archiveNode, SdkRepository.NODE_SIZE, 0), - XmlParserUtils.getXmlString(archiveNode, SdkRepository.NODE_CHECKSUM) + XmlParserUtils.getXmlString(archiveNode, SdkRepoConstants.NODE_URL), + XmlParserUtils.getXmlLong (archiveNode, SdkRepoConstants.NODE_SIZE, 0), + XmlParserUtils.getXmlString(archiveNode, SdkRepoConstants.NODE_CHECKSUM) ); return a; @@ -257,7 +266,7 @@ public abstract class Package implements IDescription, Comparable { /** * Returns the source that created (and owns) this package. Can be null. */ - public RepoSource getParentSource() { + public SdkSource getParentSource() { return mSource; } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java index 4ca5f3f94..1032e032c 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java @@ -22,7 +22,7 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -45,15 +45,20 @@ public class PlatformPackage extends MinToolsPackage implements IPackageVersion /** * Creates a new platform package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - PlatformPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + PlatformPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); - mVersionName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_VERSION); - int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0); - String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME); + mVersionName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_VERSION); + int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); + String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); if (codeName.length() == 0) { codeName = null; } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformToolPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformToolPackage.java index 19296369b..cfd88e916 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformToolPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformToolPackage.java @@ -34,11 +34,17 @@ public class PlatformToolPackage extends Package { /** * Creates a new platform-tool package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - PlatformToolPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + PlatformToolPackage(SdkSource source, Node packageNode, + String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); } /** @@ -49,7 +55,7 @@ public class PlatformToolPackage extends Package { * By design, this creates a package with one and only one archive. */ PlatformToolPackage( - RepoSource source, + SdkSource source, Properties props, int revision, String license, diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SamplePackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SamplePackage.java index 0d215e8d1..d60cbaf55 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SamplePackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SamplePackage.java @@ -23,7 +23,7 @@ import com.android.sdklib.SdkManager; import com.android.sdklib.AndroidVersion.AndroidVersionException; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -56,20 +56,25 @@ public class SamplePackage extends MinToolsPackage /** * Creates a new sample package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - SamplePackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + SamplePackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); - int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0); - String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME); + int apiLevel = XmlParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); + String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); if (codeName.length() == 0) { codeName = null; } mVersion = new AndroidVersion(apiLevel, codeName); - mMinApiLevel = XmlParserUtils.getXmlInt(packageNode, SdkRepository.NODE_MIN_API_LEVEL, + mMinApiLevel = XmlParserUtils.getXmlInt(packageNode, SdkRepoConstants.NODE_MIN_API_LEVEL, MIN_API_LEVEL_NOT_SPECIFIED); } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkAddonSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkAddonSource.java new file mode 100755 index 000000000..ab245871f --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkAddonSource.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * 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.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, + * 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.sdklib.internal.repository; + +import com.android.sdklib.annotations.Nullable; +import com.android.sdklib.repository.SdkAddonConstants; + +import org.w3c.dom.Document; + +import java.io.InputStream; + + +/** + * An sdk-addon source, i.e. a download site for addons and extra packages. + * A repository describes one or more {@link Package}s available for download. + */ +public class SdkAddonSource extends SdkSource { + + /** + * Constructs a new source for the given repository URL. + * @param url The source URL. Cannot be null. If the URL ends with a /, the default + * repository.xml filename will be appended automatically. + * @param userSource True if this a user source (add-ons & packages only.) + */ + public SdkAddonSource(String url, boolean userSource) { + super(url, false); + } + + /** + * Returns true if this is an addon source. + * We only load addons and extras from these sources. + */ + @Override + public boolean isAddonSource() { + return true; + } + + @Override + protected String getUrlDefaultXmlFile() { + return SdkAddonConstants.URL_DEFAULT_XML_FILE; + } + + @Override + protected int getNsLatestVersion() { + return SdkAddonConstants.NS_LATEST_VERSION; + } + + @Override + protected String getNsUri() { + return SdkAddonConstants.NS_URI; + } + + @Override + protected String getNsPattern() { + return SdkAddonConstants.NS_PATTERN; + } + + @Override + protected String getSchemaUri(int version) { + return SdkAddonConstants.getSchemaUri(version); + } + + @Override + protected String getRootElementName() { + return SdkAddonConstants.NODE_SDK_ADDON; + } + + @Override + protected InputStream getXsdStream(int version) { + return SdkAddonConstants.getXsdStream(version); + } + + /** + * There is no support forward evolution of the sdk-addon schema yet since we + * currently have only one version. + * + * @param xml The input XML stream. Can be null. + * @return Always null. + * @null This implementation always return null. + */ + @Override + protected Document findAlternateToolsXml(@Nullable InputStream xml) { + return null; + } +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkRepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkRepoSource.java new file mode 100755 index 000000000..d28b2b327 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkRepoSource.java @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * 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.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, + * 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.sdklib.internal.repository; + +import com.android.sdklib.annotations.Nullable; +import com.android.sdklib.internal.repository.Archive.Arch; +import com.android.sdklib.internal.repository.Archive.Os; +import com.android.sdklib.repository.CommonConstants; +import com.android.sdklib.repository.SdkRepoConstants; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.Text; + +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + + +/** + * An sdk-repository source, i.e. a download site. + * A repository describes one or more {@link Package}s available for download. + */ +public class SdkRepoSource extends SdkSource { + + /** + * Constructs a new source for the given repository URL. + * @param url The source URL. Cannot be null. If the URL ends with a /, the default + * repository.xml filename will be appended automatically. + */ + public SdkRepoSource(String url) { + super(url, false); + } + + /** + * Returns true if this is an addon source. + * We only load addons and extras from these sources. + */ + @Override + public boolean isAddonSource() { + return false; + } + + @Override + protected String getUrlDefaultXmlFile() { + return SdkRepoConstants.URL_DEFAULT_XML_FILE; + } + + @Override + protected int getNsLatestVersion() { + return SdkRepoConstants.NS_LATEST_VERSION; + } + + @Override + protected String getNsUri() { + return SdkRepoConstants.NS_URI; + } + + @Override + protected String getNsPattern() { + return SdkRepoConstants.NS_PATTERN; + } + + @Override + protected String getSchemaUri(int version) { + return SdkRepoConstants.getSchemaUri(version); + } + + @Override + protected String getRootElementName() { + return SdkRepoConstants.NODE_SDK_REPOSITORY; + } + + @Override + protected InputStream getXsdStream(int version) { + return SdkRepoConstants.getXsdStream(version); + } + + + /** + * The purpose of this method is to support forward evolution of our schema. + *

+ * At this point, we know that xml does not point to any schema that this version of + * the tool knows how to process, so it's not one of the possible 1..N versions of our + * XSD schema. + *

+ * We thus try to interpret the byte stream as a possible XML stream. It may not be + * one at all in the first place. If it looks anything line an XML schema, we try to + * find its <tool> and the <platform-tools> elements. If we find any, + * we recreate a suitable document that conforms to what we expect from our XSD schema + * with only those elements. + *

+ * To be valid, the <tool> and the <platform-tools> elements must have at + * least one <archive> compatible with this platform. + *

+ * Starting the sdk-repository schema v3, <tools> has a <min-platform-tools-rev> + * node, so technically the corresponding XML schema will be usable only if there's a + * <platform-tools> with the request revision number. We don't enforce that here, as + * this is done at install time. + *

+ * If we don't find anything suitable, we drop the whole thing. + * + * @param xml The input XML stream. Can be null. + * @return Either a new XML document conforming to our schema with at least one <tool> + * and <platform-tools> element or null. + * @throws IOException if InputStream.reset() fails + * @null Can return null on failure. + */ + @Override + protected Document findAlternateToolsXml(@Nullable InputStream xml) throws IOException { + if (xml == null) { + return null; + } + + // Reset the stream if it supports that operation. + xml.reset(); + + // Get an XML document + + Document oldDoc = null; + Document newDoc = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(false); + factory.setValidating(false); + + // Parse the old document using a non namespace aware builder + factory.setNamespaceAware(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + oldDoc = builder.parse(xml); + + // Prepare a new document using a namespace aware builder + factory.setNamespaceAware(true); + builder = factory.newDocumentBuilder(); + newDoc = builder.newDocument(); + + } catch (Exception e) { + // Failed to get builder factor + // Failed to create XML document builder + // Failed to parse XML document + // Failed to read XML document + } + + if (oldDoc == null || newDoc == null) { + return null; + } + + + // Check the root element is an XML with at least the following properties: + // + // + // Note that we don't have namespace support enabled, we just do it manually. + + Pattern nsPattern = Pattern.compile(getNsPattern()); + + Node oldRoot = null; + String prefix = null; + for (Node child = oldDoc.getFirstChild(); child != null; child = child.getNextSibling()) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + prefix = null; + String name = child.getNodeName(); + int pos = name.indexOf(':'); + if (pos > 0 && pos < name.length() - 1) { + prefix = name.substring(0, pos); + name = name.substring(pos + 1); + } + if (SdkRepoConstants.NODE_SDK_REPOSITORY.equals(name)) { + NamedNodeMap attrs = child.getAttributes(); + String xmlns = "xmlns"; //$NON-NLS-1$ + if (prefix != null) { + xmlns += ":" + prefix; //$NON-NLS-1$ + } + Node attr = attrs.getNamedItem(xmlns); + if (attr != null) { + String uri = attr.getNodeValue(); + if (uri != null && nsPattern.matcher(uri).matches()) { + oldRoot = child; + break; + } + } + } + } + } + + // we must have found the root node, and it must have an XML namespace prefix. + if (oldRoot == null || prefix == null || prefix.length() == 0) { + return null; + } + + final String ns = getNsUri(); + Element newRoot = newDoc.createElementNS(ns, getRootElementName()); + newRoot.setPrefix(prefix); + newDoc.appendChild(newRoot); + int numTool = 0; + + // Find any inner or nodes and extract their required parameters + + String[] elementNames = { + SdkRepoConstants.NODE_TOOL, + SdkRepoConstants.NODE_PLATFORM_TOOL, + SdkRepoConstants.NODE_LICENSE + }; + + Element element = null; + while ((element = findChild(oldRoot, element, prefix, elementNames)) != null) { + boolean isElementValid = false; + + String name = element.getLocalName(); + if (name == null) { + name = element.getNodeName(); + + int pos = name.indexOf(':'); + if (pos > 0 && pos < name.length() - 1) { + name = name.substring(pos + 1); + } + } + + // To be valid, the tool or platform-tool element must have: + // - a element with a number + // - a element with a number for a element + // - an element with one or more elements inside + // - one of the elements must have an "os" and "arch" attributes + // compatible with the current platform. Only keep the first such element found. + // - the element must contain a , a and a . + // - none of the above for a license element + + if (SdkRepoConstants.NODE_LICENSE.equals(name)) { + isElementValid = true; + + } else { + try { + Node revision = findChild(element, null, prefix, CommonConstants.NODE_REVISION); + Node archives = findChild(element, null, prefix, CommonConstants.NODE_ARCHIVES); + + if (revision == null || archives == null) { + continue; + } + + // check revision contains a number + try { + String content = revision.getTextContent(); + content = content.trim(); + int rev = Integer.parseInt(content); + if (rev < 1) { + continue; + } + } catch (NumberFormatException ignore) { + continue; + } + + if (SdkRepoConstants.NODE_TOOL.equals(name)) { + Node minPTRev = findChild(element, null, prefix, + CommonConstants.NODE_MIN_PLATFORM_TOOLS_REV); + + if (minPTRev == null) { + continue; + } + + // check min-platform-tools-rev contains a number + try { + String content = minPTRev.getTextContent(); + content = content.trim(); + int rev = Integer.parseInt(content); + if (rev < 1) { + continue; + } + } catch (NumberFormatException ignore) { + continue; + } + } + + Node archive = null; + while ((archive = findChild(archives, + archive, + prefix, + CommonConstants.NODE_ARCHIVE)) != null) { + try { + Os os = (Os) XmlParserUtils.getEnumAttribute(archive, + CommonConstants.ATTR_OS, + Os.values(), + null /*default*/); + Arch arch = (Arch) XmlParserUtils.getEnumAttribute(archive, + CommonConstants.ATTR_ARCH, + Arch.values(), + Arch.ANY); + if (os == null || !os.isCompatible() || + arch == null || !arch.isCompatible()) { + continue; + } + + Node node = findChild(archive, null, prefix, CommonConstants.NODE_URL); + String url = node == null ? null : node.getTextContent().trim(); + if (url == null || url.length() == 0) { + continue; + } + + node = findChild(archive, null, prefix, CommonConstants.NODE_SIZE); + long size = 0; + try { + size = Long.parseLong(node.getTextContent()); + } catch (Exception e) { + // pass + } + if (size < 1) { + continue; + } + + node = findChild(archive, null, prefix, CommonConstants.NODE_CHECKSUM); + // double check that the checksum element contains a type=sha1 attribute + if (node == null) { + continue; + } + NamedNodeMap attrs = node.getAttributes(); + Node typeNode = attrs.getNamedItem(CommonConstants.ATTR_TYPE); + if (typeNode == null || + !CommonConstants.ATTR_TYPE.equals(typeNode.getNodeName()) || + !CommonConstants.SHA1_TYPE.equals(typeNode.getNodeValue())) { + continue; + } + String sha1 = node == null ? null : node.getTextContent().trim(); + if (sha1 == null || + sha1.length() != CommonConstants.SHA1_CHECKSUM_LEN) { + continue; + } + + isElementValid = true; + + } catch (Exception ignore1) { + // pass + } + } // while + } catch (Exception ignore2) { + // For debugging it is useful to re-throw the exception. + // For end-users, not so much. It would be nice to make it + // happen automatically during unit tests. + if (System.getenv("TESTING") != null) { + throw new RuntimeException(ignore2); + } + } + } + + if (isElementValid) { + duplicateNode(newRoot, element, SdkRepoConstants.NS_URI, prefix); + numTool++; + } + } // while + + return numTool > 0 ? newDoc : null; + } + + /** + * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given + * element child in a root XML node. + */ + private Element findChild(Node rootNode, Node after, String prefix, String[] nodeNames) { + for (int i = 0; i < nodeNames.length; i++) { + if (nodeNames[i].indexOf(':') < 0) { + nodeNames[i] = prefix + ":" + nodeNames[i]; + } + } + Node child = after == null ? rootNode.getFirstChild() : after.getNextSibling(); + for(; child != null; child = child.getNextSibling()) { + if (child.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + for (String nodeName : nodeNames) { + if (nodeName.equals(child.getNodeName())) { + return (Element) child; + } + } + } + return null; + } + + /** + * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given + * element child in a root XML node. + */ + private Node findChild(Node rootNode, Node after, String prefix, String nodeName) { + return findChild(rootNode, after, prefix, new String[] { nodeName }); + } + + /** + * Helper method used by {@link #findAlternateToolsXml(InputStream)} to duplicate a node + * and attach it to the given root in the new document. + */ + private Element duplicateNode(Element newRootNode, Element oldNode, + String namespaceUri, String prefix) { + // The implementation here is more or less equivalent to + // + // newRoot.appendChild(newDoc.importNode(oldNode, deep=true)) + // + // except we can't just use importNode() since we need to deal with the fact + // that the old document is not namespace-aware yet the new one is. + + Document newDoc = newRootNode.getOwnerDocument(); + Element newNode = null; + + String nodeName = oldNode.getNodeName(); + int pos = nodeName.indexOf(':'); + if (pos > 0 && pos < nodeName.length() - 1) { + nodeName = nodeName.substring(pos + 1); + newNode = newDoc.createElementNS(namespaceUri, nodeName); + newNode.setPrefix(prefix); + } else { + newNode = newDoc.createElement(nodeName); + } + + newRootNode.appendChild(newNode); + + // Merge in all the attributes + NamedNodeMap attrs = oldNode.getAttributes(); + for (int i = 0; i < attrs.getLength(); i++) { + Attr attr = (Attr) attrs.item(i); + Attr newAttr = null; + + String attrName = oldNode.getNodeName(); + pos = attrName.indexOf(':'); + if (pos > 0 && pos < attrName.length() - 1) { + attrName = attrName.substring(pos + 1); + newAttr = newDoc.createAttributeNS(namespaceUri, attrName); + newAttr.setPrefix(prefix); + } else { + newAttr = newDoc.createAttribute(attrName); + } + + newAttr.setNodeValue(attr.getNodeValue()); + + if (pos > 0) { + newNode.getAttributes().setNamedItemNS(newAttr); + } else { + newNode.getAttributes().setNamedItem(newAttr); + } + } + + // Merge all child elements and texts + for (Node child = oldNode.getFirstChild(); child != null; child = child.getNextSibling()) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + duplicateNode(newNode, (Element) child, namespaceUri, prefix); + + } else if (child.getNodeType() == Node.TEXT_NODE) { + Text newText = newDoc.createTextNode(child.getNodeValue()); + newNode.appendChild(newText); + } + } + + return newNode; + } +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSource.java similarity index 61% rename from sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java rename to sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSource.java index e20d5a499..623e312cb 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSource.java @@ -16,12 +16,14 @@ package com.android.sdklib.internal.repository; -import com.android.sdklib.internal.repository.Archive.Arch; -import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.annotations.Nullable; +import com.android.sdklib.annotations.VisibleForTesting; +import com.android.sdklib.annotations.VisibleForTesting.Visibility; +import com.android.sdklib.repository.CommonConstants; +import com.android.sdklib.repository.SdkAddonConstants; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.InputSource; @@ -50,11 +52,11 @@ import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; /** - * An sdk-repository source, i.e. a download site. + * An sdk-addon or sdk-repository source, i.e. a download site. * It may be a full repository or an add-on only repository. * A repository describes one or {@link Package}s available for download. */ -public class RepoSource implements IDescription { +public abstract class SdkSource implements IDescription { private String mUrl; private final boolean mUserSource; @@ -69,14 +71,14 @@ public class RepoSource implements IDescription { * repository.xml filename will be appended automatically. * @param userSource True if this a user source (add-ons & packages only.) */ - public RepoSource(String url, boolean userSource) { + public SdkSource(String url, boolean userSource) { // if the URL ends with a /, it must be "directory" resource, // in which case we automatically add the default file that will // looked for. This way it will be obvious to the user which // resource we are actually trying to fetch. if (url.endsWith("/")) { //$NON-NLS-1$ - url += SdkRepository.URL_DEFAULT_XML_FILE; + url += getUrlDefaultXmlFile(); } mUrl = url; @@ -85,12 +87,52 @@ public class RepoSource implements IDescription { } /** + * Returns true if this is an addon source. + * We only load addons and extras from these sources. + */ + public abstract boolean isAddonSource(); + + /** Returns SdkRepoConstants.URL_DEFAULT_XML_FILE or SdkAddonConstants.URL_DEFAULT_XML_FILE */ + protected abstract String getUrlDefaultXmlFile(); + + /** Returns SdkRepoConstants.NS_LATEST_VERSION or SdkAddonConstants.NS_LATEST_VERSION. */ + protected abstract int getNsLatestVersion(); + + /** Returns SdkRepoConstants.NS_URI or SdkAddonConstants.NS_URI. */ + protected abstract String getNsUri(); + + /** Returns SdkRepoConstants.NS_PATTERN or SdkAddonConstants.NS_PATTERN. */ + protected abstract String getNsPattern(); + + /** Returns SdkRepoConstants.getSchemaUri() or SdkAddonConstants.getSchemaUri(). */ + protected abstract String getSchemaUri(int version); + + /* Returns SdkRepoConstants.NODE_SDK_REPOSITORY or SdkAddonConstants.NODE_SDK_ADDON. */ + protected abstract String getRootElementName(); + + /** Returns SdkRepoConstants.getXsdStream() or SdkAddonConstants.getXsdStream(). */ + protected abstract InputStream getXsdStream(int version); + + /** + * In case we fail to load an XML, examine the XML to see if it matches a future + * schema that as at least a tools node that we could load to update the + * SDK Manager. + * + * @param xml The input XML stream. Can be null. + * @return Null on failure, otherwise returns an XML DOM with just the tools we + * need to update this SDK Manager. + * @null Can return null on failure. + */ + protected abstract Document findAlternateToolsXml(@Nullable InputStream xml) + throws IOException; + + /** * Two repo source are equal if they have the same userSource flag and the same URL. */ @Override public boolean equals(Object obj) { - if (obj instanceof RepoSource) { - RepoSource rs = (RepoSource) obj; + if (obj instanceof SdkSource) { + SdkSource rs = (SdkSource) obj; return rs.isUserSource() == this.isUserSource() && rs.getUrl().equals(this.getUrl()); } return false; @@ -101,13 +143,12 @@ public class RepoSource implements IDescription { return mUrl.hashCode() ^ Boolean.valueOf(mUserSource).hashCode(); } - /** Returns true if this is a user source. We only load addon and extra packages - * from a user source and ignore the rest. */ + /** Returns true if this is a user source. */ public boolean isUserSource() { return mUserSource; } - /** Returns the URL of the repository.xml file for this source. */ + /** Returns the URL of the XML file for this source. */ public String getUrl() { return mUrl; } @@ -173,11 +214,11 @@ public class RepoSource implements IDescription { // If the original URL can't be fetched and the URL doesn't explicitly end with // our filename, make another tentative after changing the URL. - if (xml == null && !url.endsWith(SdkRepository.URL_DEFAULT_XML_FILE)) { + if (xml == null && !url.endsWith(getUrlDefaultXmlFile())) { if (!url.endsWith("/")) { //$NON-NLS-1$ url += "/"; //$NON-NLS-1$ } - url += SdkRepository.URL_DEFAULT_XML_FILE; + url += getUrlDefaultXmlFile(); xml = fetchUrl(url, exception); usingAlternateUrl = true; @@ -190,7 +231,7 @@ public class RepoSource implements IDescription { // Explore the XML to find the potential XML schema version int version = getXmlSchemaVersion(xml); - if (version >= 1 && version <= SdkRepository.NS_LATEST_VERSION) { + if (version >= 1 && version <= getNsLatestVersion()) { // This should be a version we can handle. Try to validate it // and report any error as invalid XML syntax, @@ -216,15 +257,19 @@ public class RepoSource implements IDescription { // what looks like a suitable root element with a suitable XMLNS // so it must be a genuine error of an XML not conforming to the schema. } - } else if (version > SdkRepository.NS_LATEST_VERSION) { + } else if (version > getNsLatestVersion()) { // The schema used is more recent than what is supported by this tool. // Tell the user to upgrade, pointing him to the right version of the tool // package. - validatedDoc = findAlternateToolsXml(xml); + try { + validatedDoc = findAlternateToolsXml(xml); + } catch (IOException e) { + // Failed, will be handled below. + } if (validatedDoc != null) { validationError[0] = null; // remove error from XML validation - validatedUri = SdkRepository.NS_SDK_REPOSITORY; + validatedUri = getNsUri(); usingAlternateXml = true; } @@ -237,11 +282,11 @@ public class RepoSource implements IDescription { // If we haven't already tried the alternate URL, let's do it now. // We don't capture any fetch exception that happen during the second // fetch in order to avoid hidding any previous fetch errors. - if (!url.endsWith(SdkRepository.URL_DEFAULT_XML_FILE)) { + if (!url.endsWith(getUrlDefaultXmlFile())) { if (!url.endsWith("/")) { //$NON-NLS-1$ url += "/"; //$NON-NLS-1$ } - url += SdkRepository.URL_DEFAULT_XML_FILE; + url += getUrlDefaultXmlFile(); xml = fetchUrl(url, null /*outException*/); @@ -412,10 +457,11 @@ public class RepoSource implements IDescription { /** * Validates this XML against one of the requested SDK Repository schemas. * If the XML was correctly validated, returns the schema that worked. - * If it doesn't validate, returns null and store the error in outError[0]. + * If it doesn't validate, returns null and stores the error in outError[0]. * If we can't find a validator, returns null and set validatorFound[0] to false. */ - private String validateXml(InputStream xml, String url, int version, + @VisibleForTesting(visibility=Visibility.PRIVATE) + protected String validateXml(InputStream xml, String url, int version, String[] outError, Boolean[] validatorFound) { if (xml == null) { @@ -446,7 +492,7 @@ public class RepoSource implements IDescription { // Validation throws a bunch of possible Exceptions on failure. validator.validate(new StreamSource(xml)); - return SdkRepository.getSchemaUri(version); + return getSchemaUri(version); } catch (SAXParseException e) { outError[0] = String.format( @@ -458,7 +504,7 @@ public class RepoSource implements IDescription { } catch (Exception e) { outError[0] = String.format( - "XML verification failed for %1$s.\nError: %4$s", + "XML verification failed for %1$s.\nError: %2$s", url, e.toString()); } @@ -470,10 +516,11 @@ public class RepoSource implements IDescription { * at the end of the xmlns:sdk="http://schemas.android.com/sdk/android/repository/$N" * declaration. * - * @return 1..{@link SdkRepository#NS_LATEST_VERSION} for a valid schema version + * @return 1..{@link SdkRepoConstants#NS_LATEST_VERSION} for a valid schema version * or 0 if no schema could be found. */ - private int getXmlSchemaVersion(InputStream xml) { + @VisibleForTesting(visibility=Visibility.PRIVATE) + protected int getXmlSchemaVersion(InputStream xml) { if (xml == null) { return 0; } @@ -520,7 +567,7 @@ public class RepoSource implements IDescription { // // Note that we don't have namespace support enabled, we just do it manually. - Pattern nsPattern = Pattern.compile(SdkRepository.NS_SDK_REPOSITORY_PATTERN); + Pattern nsPattern = Pattern.compile(getNsPattern()); String prefix = null; for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) { @@ -532,7 +579,7 @@ public class RepoSource implements IDescription { prefix = name.substring(0, pos); name = name.substring(pos + 1); } - if (SdkRepository.NODE_SDK_REPOSITORY.equals(name)) { + if (getRootElementName().equals(name)) { NamedNodeMap attrs = child.getAttributes(); String xmlns = "xmlns"; //$NON-NLS-1$ if (prefix != null) { @@ -561,285 +608,14 @@ public class RepoSource implements IDescription { } /** - * The purpose of this method is to support forward evolution of our schema. - *

- * At this point, we know that xml does not point to any schema that this version of - * the tool know how to process, so it's not one of the possible 1..N versions of our - * XSD schema. - *

- * We thus try to interpret the byte stream as a possible XML stream. It may not be - * one at all in the first place. If it looks anything line an XML schema, we try to - * find its <tool> elements. If we find any, we recreate a suitable document - * that conforms to what we expect from our XSD schema with only those elements. - * To be valid, the <tool> element must have at least one <archive> - * compatible with this platform. - * - * If we don't find anything suitable, we drop the whole thing. - * - * @param xml The input XML stream. Can be null. - * @return Either a new XML document conforming to our schema with at least one <tool> - * element or null. - */ - protected Document findAlternateToolsXml(InputStream xml) { - // Note: protected for unit-test access - - if (xml == null) { - return null; - } - - // Reset the stream if it supports that operation. - // At runtime we use a ByteArrayInputStream which can be reset; however for unit tests - // we use a FileInputStream that doesn't support resetting and is read-once. - try { - xml.reset(); - } catch (IOException e1) { - // ignore if not supported - } - - // Get an XML document - - Document oldDoc = null; - Document newDoc = null; - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(false); - factory.setValidating(false); - - // Parse the old document using a non namespace aware builder - factory.setNamespaceAware(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - oldDoc = builder.parse(xml); - - // Prepare a new document using a namespace aware builder - factory.setNamespaceAware(true); - builder = factory.newDocumentBuilder(); - newDoc = builder.newDocument(); - - } catch (Exception e) { - // Failed to get builder factor - // Failed to create XML document builder - // Failed to parse XML document - // Failed to read XML document - } - - if (oldDoc == null || newDoc == null) { - return null; - } - - - // Check the root element is an XML with at least the following properties: - // - // - // Note that we don't have namespace support enabled, we just do it manually. - - Pattern nsPattern = Pattern.compile(SdkRepository.NS_SDK_REPOSITORY_PATTERN); - - Node oldRoot = null; - String prefix = null; - for (Node child = oldDoc.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - prefix = null; - String name = child.getNodeName(); - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - prefix = name.substring(0, pos); - name = name.substring(pos + 1); - } - if (SdkRepository.NODE_SDK_REPOSITORY.equals(name)) { - NamedNodeMap attrs = child.getAttributes(); - String xmlns = "xmlns"; //$NON-NLS-1$ - if (prefix != null) { - xmlns += ":" + prefix; //$NON-NLS-1$ - } - Node attr = attrs.getNamedItem(xmlns); - if (attr != null) { - String uri = attr.getNodeValue(); - if (uri != null && nsPattern.matcher(uri).matches()) { - oldRoot = child; - break; - } - } - } - } - } - - // we must have found the root node, and it must have an XML namespace prefix. - if (oldRoot == null || prefix == null || prefix.length() == 0) { - return null; - } - - final String ns = SdkRepository.NS_SDK_REPOSITORY; - Element newRoot = newDoc.createElementNS(ns, SdkRepository.NODE_SDK_REPOSITORY); - newRoot.setPrefix(prefix); - newDoc.appendChild(newRoot); - int numTool = 0; - - // Find an inner node and extract its required parameters - - Node tool = null; - while ((tool = findChild(oldRoot, tool, prefix, SdkRepository.NODE_TOOL)) != null) { - // To be valid, the tool element must have: - // - a element with a number - // - an optional node, which we'll skip right now. - // (if we add it later, we must find the license declaration element too) - // - an element with one or more elements inside - // - one of the elements must have an "os" and "arch" attributes - // compatible with the current platform. Only keep the first such element found. - // - the element must contain a , a and a . - - try { - Node revision = findChild(tool, null, prefix, SdkRepository.NODE_REVISION); - Node archives = findChild(tool, null, prefix, SdkRepository.NODE_ARCHIVES); - - if (revision == null || archives == null) { - continue; - } - - int rev = 0; - try { - String content = revision.getTextContent(); - content = content.trim(); - rev = Integer.parseInt(content); - if (rev < 1) { - continue; - } - } catch (NumberFormatException ignore) { - continue; - } - - Element newTool = newDoc.createElementNS(ns, SdkRepository.NODE_TOOL); - newTool.setPrefix(prefix); - appendChild(newTool, ns, prefix, - SdkRepository.NODE_REVISION, Integer.toString(rev)); - Element newArchives = appendChild(newTool, ns, prefix, - SdkRepository.NODE_ARCHIVES, null); - int numArchives = 0; - - Node archive = null; - while ((archive = findChild(archives, - archive, - prefix, - SdkRepository.NODE_ARCHIVE)) != null) { - try { - Os os = (Os) XmlParserUtils.getEnumAttribute(archive, - SdkRepository.ATTR_OS, - Os.values(), - null /*default*/); - Arch arch = (Arch) XmlParserUtils.getEnumAttribute(archive, - SdkRepository.ATTR_ARCH, - Arch.values(), - Arch.ANY); - if (os == null || !os.isCompatible() || - arch == null || !arch.isCompatible()) { - continue; - } - - Node node = findChild(archive, null, prefix, SdkRepository.NODE_URL); - String url = node == null ? null : node.getTextContent().trim(); - if (url == null || url.length() == 0) { - continue; - } - - node = findChild(archive, null, prefix, SdkRepository.NODE_SIZE); - long size = 0; - try { - size = Long.parseLong(node.getTextContent()); - } catch (Exception e) { - // pass - } - if (size < 1) { - continue; - } - - node = findChild(archive, null, prefix, SdkRepository.NODE_CHECKSUM); - // double check that the checksum element contains a type=sha1 attribute - if (node == null) { - continue; - } - NamedNodeMap attrs = node.getAttributes(); - Node typeNode = attrs.getNamedItem(SdkRepository.ATTR_TYPE); - if (typeNode == null || - !SdkRepository.ATTR_TYPE.equals(typeNode.getNodeName()) || - !SdkRepository.SHA1_TYPE.equals(typeNode.getNodeValue())) { - continue; - } - String sha1 = node == null ? null : node.getTextContent().trim(); - if (sha1 == null || sha1.length() != SdkRepository.SHA1_CHECKSUM_LEN) { - continue; - } - - // Use that archive for the new tool element - Element ar = appendChild(newArchives, ns, prefix, - SdkRepository.NODE_ARCHIVE, null); - ar.setAttributeNS(ns, SdkRepository.ATTR_OS, os.getXmlName()); - ar.setAttributeNS(ns, SdkRepository.ATTR_ARCH, arch.getXmlName()); - - appendChild(ar, ns, prefix, SdkRepository.NODE_URL, url); - appendChild(ar, ns, prefix, SdkRepository.NODE_SIZE, Long.toString(size)); - Element cs = appendChild(ar, ns, prefix, SdkRepository.NODE_CHECKSUM, sha1); - cs.setAttributeNS(ns, SdkRepository.ATTR_TYPE, SdkRepository.SHA1_TYPE); - - numArchives++; - - } catch (Exception ignore1) { - // pass - } - } // while - - if (numArchives > 0) { - newRoot.appendChild(newTool); - numTool++; - } - } catch (Exception ignore2) { - // pass - } - } // while - - return numTool > 0 ? newDoc : null; - } - - /** - * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given - * element child in a root XML node. - */ - private Node findChild(Node rootNode, Node after, String prefix, String nodeName) { - nodeName = prefix + ":" + nodeName; - Node child = after == null ? rootNode.getFirstChild() : after.getNextSibling(); - for(; child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && nodeName.equals(child.getNodeName())) { - return child; - } - } - return null; - } - - /** - * Helper method used by {@link #findAlternateToolsXml(InputStream)} to create a new - * XML element into a parent element. - */ - private Element appendChild(Element rootNode, String namespaceUri, - String prefix, String nodeName, - String nodeValue) { - Element node = rootNode.getOwnerDocument().createElementNS(namespaceUri, nodeName); - node.setPrefix(prefix); - if (nodeValue != null) { - node.setTextContent(nodeValue); - } - rootNode.appendChild(node); - return node; - } - - - /** * Helper method that returns a validator for our XSD, or null if the current Java * implementation can't process XSD schemas. * * @param version The version of the XML Schema. - * See {@link SdkRepository#getXsdStream(int)} + * See {@link SdkRepoConstants#getXsdStream(int)} */ private Validator getValidator(int version) throws SAXException { - InputStream xsdStream = SdkRepository.getXsdStream(version); + InputStream xsdStream = getXsdStream(version); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); if (factory == null) { @@ -864,7 +640,7 @@ public class RepoSource implements IDescription { assert doc != null; - Node root = getFirstChild(doc, nsUri, SdkRepository.NODE_SDK_REPOSITORY); + Node root = getFirstChild(doc, nsUri, getRootElementName()); if (root != null) { ArrayList packages = new ArrayList(); @@ -876,8 +652,8 @@ public class RepoSource implements IDescription { child = child.getNextSibling()) { if (child.getNodeType() == Node.ELEMENT_NODE && nsUri.equals(child.getNamespaceURI()) && - child.getLocalName().equals(SdkRepository.NODE_LICENSE)) { - Node id = child.getAttributes().getNamedItem(SdkRepository.ATTR_ID); + child.getLocalName().equals(CommonConstants.NODE_LICENSE)) { + Node id = child.getAttributes().getNamedItem(CommonConstants.ATTR_ID); if (id != null) { licenses.put(id.getNodeValue(), child.getTextContent()); } @@ -896,25 +672,25 @@ public class RepoSource implements IDescription { try { // We can load addon and extra packages from all sources, either // internal or user sources. - if (SdkRepository.NODE_ADD_ON.equals(name)) { - p = new AddonPackage(this, child, licenses); + if (SdkAddonConstants.NODE_ADD_ON.equals(name)) { + p = new AddonPackage(this, child, nsUri, licenses); - } else if (SdkRepository.NODE_EXTRA.equals(name)) { - p = new ExtraPackage(this, child, licenses); + } else if (CommonConstants.NODE_EXTRA.equals(name)) { + p = new ExtraPackage(this, child, nsUri, licenses); } else if (!mUserSource) { // We only load platform, doc and tool packages from internal // sources, never from user sources. - if (SdkRepository.NODE_PLATFORM.equals(name)) { - p = new PlatformPackage(this, child, licenses); - } else if (SdkRepository.NODE_DOC.equals(name)) { - p = new DocPackage(this, child, licenses); - } else if (SdkRepository.NODE_TOOL.equals(name)) { - p = new ToolPackage(this, child, licenses); - } else if (SdkRepository.NODE_PLATFORM_TOOL.equals(name)) { - p = new PlatformToolPackage(this, child, licenses); - } else if (SdkRepository.NODE_SAMPLE.equals(name)) { - p = new SamplePackage(this, child, licenses); + if (SdkRepoConstants.NODE_PLATFORM.equals(name)) { + p = new PlatformPackage(this, child, nsUri, licenses); + } else if (SdkRepoConstants.NODE_DOC.equals(name)) { + p = new DocPackage(this, child, nsUri, licenses); + } else if (SdkRepoConstants.NODE_TOOL.equals(name)) { + p = new ToolPackage(this, child, nsUri, licenses); + } else if (SdkRepoConstants.NODE_PLATFORM_TOOL.equals(name)) { + p = new PlatformToolPackage(this, child, nsUri, licenses); + } else if (SdkRepoConstants.NODE_SAMPLE.equals(name)) { + p = new SamplePackage(this, child, nsUri, licenses); } } @@ -924,6 +700,8 @@ public class RepoSource implements IDescription { } } catch (Exception e) { // Ignore invalid packages + monitor.setResult("Ignoring invalid %1$s element: %2$s", + name, e.toString()); } } } @@ -962,7 +740,8 @@ public class RepoSource implements IDescription { * * On error, returns null and prints a (hopefully) useful message on the monitor. */ - private Document getDocument(ByteArrayInputStream xml, ITaskMonitor monitor) { + @VisibleForTesting(visibility=Visibility.PRIVATE) + protected Document getDocument(InputStream xml, ITaskMonitor monitor) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringComments(true); diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSources.java similarity index 83% rename from sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java rename to sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSources.java index 9dbdaf511..2bb22f48f 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkSources.java @@ -29,9 +29,9 @@ import java.util.Iterator; import java.util.Properties; /** - * A list of sdk-repository sources. + * A list of sdk-repository and sdk-addon sources. */ -public class RepoSources { +public class SdkSources { private static final String KEY_COUNT = "count"; @@ -39,30 +39,30 @@ public class RepoSources { private static final String SRC_FILENAME = "repositories.cfg"; //$NON-NLS-1$ - private ArrayList mSources = new ArrayList(); + private ArrayList mSources = new ArrayList(); - public RepoSources() { + public SdkSources() { } /** * Adds a new source to the Sources list. */ - public void add(RepoSource source) { + public void add(SdkSource source) { mSources.add(source); } /** * Removes a source from the Sources list. */ - public void remove(RepoSource source) { + public void remove(SdkSource source) { mSources.remove(source); } /** * Returns the sources list array. This is never null. */ - public RepoSource[] getSources() { - return mSources.toArray(new RepoSource[mSources.size()]); + public SdkSource[] getSources() { + return mSources.toArray(new SdkSource[mSources.size()]); } /** @@ -72,8 +72,8 @@ public class RepoSources { public void loadUserSources(ISdkLog log) { // Remove all existing user sources - for (Iterator it = mSources.iterator(); it.hasNext(); ) { - RepoSource s = it.next(); + for (Iterator it = mSources.iterator(); it.hasNext(); ) { + SdkSource s = it.next(); if (s.isUserSource()) { it.remove(); } @@ -95,7 +95,7 @@ public class RepoSources { for (int i = 0; i < count; i++) { String url = props.getProperty(String.format("%s%02d", KEY_SRC, i)); //$NON-NLS-1$ if (url != null) { - RepoSource s = new RepoSource(url, true /*userSource*/); + SdkSource s = new SdkAddonSource(url, true /*userSource*/); if (!hasSource(s)) { mSources.add(s); } @@ -127,8 +127,8 @@ public class RepoSources { *

* The search is O(N), which should be acceptable on the expectedly small source list. */ - public boolean hasSource(RepoSource source) { - for (RepoSource s : mSources) { + public boolean hasSource(SdkSource source) { + for (SdkSource s : mSources) { if (s.equals(source)) { return true; } @@ -151,7 +151,7 @@ public class RepoSources { Properties props = new Properties(); int count = 0; - for (RepoSource s : mSources) { + for (SdkSource s : mSources) { if (s.isUserSource()) { count++; props.setProperty(String.format("%s%02d", KEY_SRC, count), s.getUrl()); //$NON-NLS-1$ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java index 0e5ed47a3..24316e458 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java @@ -20,7 +20,7 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive.Arch; import com.android.sdklib.internal.repository.Archive.Os; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import org.w3c.dom.Node; @@ -30,6 +30,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Represents a tool XML node in an SDK repository. @@ -47,21 +49,44 @@ public class ToolPackage extends Package implements IMinPlatformToolsDependency /** * Creates a new tool package from the attributes and elements of the given XML node. - *

* This constructor should throw an exception if the package cannot be created. + * + * @param source The {@link SdkSource} where this is loaded from. + * @param packageNode The XML element being parsed. + * @param nsUri The namespace URI of the originating XML document, to be able to deal with + * parameters that vary according to the originating XML schema. + * @param licenses The licenses loaded from the XML originating document. */ - ToolPackage(RepoSource source, Node packageNode, Map licenses) { - super(source, packageNode, licenses); + ToolPackage(SdkSource source, Node packageNode, String nsUri, Map licenses) { + super(source, packageNode, nsUri, licenses); mMinPlatformToolsRevision = XmlParserUtils.getXmlInt( packageNode, - SdkRepository.NODE_MIN_PLATFORM_TOOLS_REV, + SdkRepoConstants.NODE_MIN_PLATFORM_TOOLS_REV, MIN_PLATFORM_TOOLS_REV_INVALID); if (mMinPlatformToolsRevision == MIN_PLATFORM_TOOLS_REV_INVALID) { - throw new IllegalArgumentException( - String.format("Missing %1$s element in %2$s package", - SdkRepository.NODE_MIN_PLATFORM_TOOLS_REV, - SdkRepository.NODE_PLATFORM_TOOL)); + // This revision number is mandatory starting with sdk-repository-3.xsd + // and did not exist before. Complain if the URI has level >= 3. + + boolean needRevision = false; + + Pattern nsPattern = Pattern.compile(SdkRepoConstants.NS_PATTERN); + Matcher m = nsPattern.matcher(nsUri); + if (m.matches()) { + String version = m.group(1); + try { + needRevision = Integer.parseInt(version) >= 3; + } catch (NumberFormatException e) { + // ignore. needRevision defaults to false + } + } + + if (needRevision) { + throw new IllegalArgumentException( + String.format("Missing %1$s element in %2$s package", + SdkRepoConstants.NODE_MIN_PLATFORM_TOOLS_REV, + SdkRepoConstants.NODE_PLATFORM_TOOL)); + } } } @@ -73,7 +98,7 @@ public class ToolPackage extends Package implements IMinPlatformToolsDependency * By design, this creates a package with one and only one archive. */ ToolPackage( - RepoSource source, + SdkSource source, Properties props, int revision, String license, diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/CommonConstants.java similarity index 61% rename from sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java rename to sdkmanager/libs/sdklib/src/com/android/sdklib/repository/CommonConstants.java index 0a4452ab5..f3e5cd432 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/CommonConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2010 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. @@ -17,66 +17,15 @@ package com.android.sdklib.repository; -import java.io.InputStream; /** - * Public constants for the sdk-repository XML Schema. + * Public constants common to the sdk-repository and sdk-addon XML Schemas. */ -public class SdkRepository { - - /** The URL of the official Google sdk-repository site. */ - public static final String URL_GOOGLE_SDK_REPO_SITE = - "https://dl-ssl.google.com/android/repository/"; //$NON-NLS-1$ - - public static final String URL_DEFAULT_XML_FILE = "repository.xml"; //$NON-NLS-1$ - - /** The base of our XML namespace. */ - private static final String NS_SDK_REPOSITORY_BASE = - "http://schemas.android.com/sdk/android/repository/"; //$NON-NLS-1$ - - /** The pattern of our XML namespace. Matcher's group(1) is the schema version (integer). */ - public static final String NS_SDK_REPOSITORY_PATTERN = - NS_SDK_REPOSITORY_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** The latest version of the sdk-repository XML Schema. - * Valid version numbers are between 1 and this number, included. */ - public static final int NS_LATEST_VERSION = 3; - - /** The XML namespace of the latest sdk-repository XML. */ - public static final String NS_SDK_REPOSITORY = getSchemaUri(NS_LATEST_VERSION); - - /** The root sdk-repository element */ - public static final String NODE_SDK_REPOSITORY = "sdk-repository"; //$NON-NLS-1$ - - /** A platform package. */ - public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$ - /** An add-on package. */ - public static final String NODE_ADD_ON = "add-on"; //$NON-NLS-1$ - /** A tool package. */ - public static final String NODE_TOOL = "tool"; //$NON-NLS-1$ - /** A platform-tool package. */ - public static final String NODE_PLATFORM_TOOL = "platform-tool"; //$NON-NLS-1$ - /** A doc package. */ - public static final String NODE_DOC = "doc"; //$NON-NLS-1$ - /** A sample package. */ - public static final String NODE_SAMPLE = "sample"; //$NON-NLS-1$ +public class CommonConstants { + /** An extra package. */ public static final String NODE_EXTRA = "extra"; //$NON-NLS-1$ - /** - * List of possible nodes in a repository XML. Used to populate options automatically - * in the no-GUI mode. - */ - public static final String[] NODES = { - NODE_PLATFORM, - NODE_ADD_ON, - NODE_TOOL, - NODE_PLATFORM_TOOL, - NODE_DOC, - NODE_SAMPLE, - NODE_EXTRA - }; - /** The license definition. */ public static final String NODE_LICENSE = "license"; //$NON-NLS-1$ /** The optional uses-license for all packages or for a lib. */ @@ -150,24 +99,4 @@ public class SdkRepository { /** Length of a string representing a SHA1 checksum; always 40 characters long. */ public static final int SHA1_CHECKSUM_LEN = 40; - - /** - * Returns a stream to the requested repository XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - String filename = String.format("sdk-repository-%d.xsd", version); //$NON-NLS-1$ - return SdkRepository.class.getResourceAsStream(filename); - } - - /** - * Returns the URI of the SDK Repository schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_SDK_REPOSITORY_BASE + "%d", version); //$NON-NLS-1$ - } } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java new file mode 100755 index 000000000..4f228c631 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 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.sdklib.repository; + + +import java.io.InputStream; + +/** + * Public constants for the sdk-addon XML Schema. + */ +public class SdkAddonConstants extends CommonConstants { + + /** The URL of the official Google sdk-addon site. */ + public static final String URL_GOOGLE_SDK_SITE = + "https://dl-ssl.google.com/android/repository/"; //$NON-NLS-1$ + + public static final String URL_DEFAULT_XML_FILE = "addon.xml"; //$NON-NLS-1$ + + /** The base of our sdk-addon XML namespace. */ + private static final String NS_BASE = + "http://schemas.android.com/sdk/android/addon/"; //$NON-NLS-1$ + + /** + * The pattern of our sdk-addon XML namespace. + * Matcher's group(1) is the schema version (integer). + */ + public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ + + /** The latest version of the sdk-addon XML Schema. + * Valid version numbers are between 1 and this number, included. */ + public static final int NS_LATEST_VERSION = 3; + + /** The XML namespace of the latest sdk-addon XML. */ + public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); + + /** The root sdk-addon element */ + public static final String NODE_SDK_ADDON = "sdk-addon"; //$NON-NLS-1$ + + /** An add-on package. */ + public static final String NODE_ADD_ON = "add-on"; //$NON-NLS-1$ + + /** + * List of possible nodes in a repository XML. Used to populate options automatically + * in the no-GUI mode. + */ + public static final String[] NODES = { + NODE_ADD_ON, + NODE_EXTRA + }; + + /** + * Returns a stream to the requested sdk-addon XML Schema. + * + * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. + * @return An {@link InputStream} object for the local XSD file or + * null if there is no schema for the requested version. + */ + public static InputStream getXsdStream(int version) { + String filename = String.format("sdk-addon-%d.xsd", version); //$NON-NLS-1$ + return SdkAddonConstants.class.getResourceAsStream(filename); + } + + /** + * Returns the URI of the sdk-addon schema for the given version number. + * @param version Between 1 and {@link #NS_LATEST_VERSION} included. + */ + public static String getSchemaUri(int version) { + return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ + } +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java new file mode 100755 index 000000000..45d5f1668 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2009 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.sdklib.repository; + + +import java.io.InputStream; + +/** + * Public constants for the sdk-repository XML Schema. + */ +public class SdkRepoConstants extends CommonConstants { + + /** The URL of the official Google sdk-repository site. */ + public static final String URL_GOOGLE_SDK_SITE = + "https://dl-ssl.google.com/android/repository/"; //$NON-NLS-1$ + + public static final String URL_DEFAULT_XML_FILE = "repository.xml"; //$NON-NLS-1$ + + /** The base of our sdk-repository XML namespace. */ + private static final String NS_BASE = + "http://schemas.android.com/sdk/android/repository/"; //$NON-NLS-1$ + + /** + * The pattern of our sdk-repository XML namespace. + * Matcher's group(1) is the schema version (integer). + */ + public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ + + /** The latest version of the sdk-repository XML Schema. + * Valid version numbers are between 1 and this number, included. */ + public static final int NS_LATEST_VERSION = 3; + + /** The XML namespace of the latest sdk-repository XML. */ + public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); + + /** The root sdk-repository element */ + public static final String NODE_SDK_REPOSITORY = "sdk-repository"; //$NON-NLS-1$ + + /** A platform package. */ + public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$ + /** A tool package. */ + public static final String NODE_TOOL = "tool"; //$NON-NLS-1$ + /** A platform-tool package. */ + public static final String NODE_PLATFORM_TOOL = "platform-tool"; //$NON-NLS-1$ + /** A doc package. */ + public static final String NODE_DOC = "doc"; //$NON-NLS-1$ + /** A sample package. */ + public static final String NODE_SAMPLE = "sample"; //$NON-NLS-1$ + + /** + * List of possible nodes in a repository XML. Used to populate options automatically + * in the no-GUI mode. + */ + public static final String[] NODES = { + NODE_PLATFORM, + NODE_TOOL, + NODE_PLATFORM_TOOL, + NODE_DOC, + NODE_SAMPLE, + NODE_EXTRA + }; + + /** + * Returns a stream to the requested repository XML Schema. + * + * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. + * @return An {@link InputStream} object for the local XSD file or + * null if there is no schema for the requested version. + */ + public static InputStream getXsdStream(int version) { + String filename = String.format("sdk-repository-%d.xsd", version); //$NON-NLS-1$ + return SdkRepoConstants.class.getResourceAsStream(filename); + } + + /** + * Returns the URI of the SDK Repository schema for the given version number. + * @param version Between 1 and {@link #NS_LATEST_VERSION} included. + */ + public static String getSchemaUri(int version) { + return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ + } +} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd new file mode 100755 index 000000000..041a038d2 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd @@ -0,0 +1,287 @@ + + + + + + + + + + + + The repository contains a collection of downloadable packages. + + + + + + + + + + + + + + An SDK add-on package. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An SDK extra package. This kind of package is for "free" + content and specifies in which fixed root directory it must be + installed. + The paths "add-ons", "platforms", "tools" and "docs" are + reserved and cannot be used. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A license definition. Such a license must be used later as a reference + using a uses-license element in one of the package elements. + + + + + + + + + + + + + + + + + Describes the license used by a package. The license MUST be defined + using a license node and referenced using the ref attribute of the + license element inside a package. + + + + + + + + + + + + A collection of files that can be downloaded for a given architecture. + The <archives> node is mandatory in the repository packages and the + collection must have at least one <archive> declared. + Each archive is a zip file that will be unzipped in a location that depends + on its package type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A SHA1 checksum. + + + + + + + + + A file checksum, currently only SHA1. + + + + + + + + + diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd index 66387562f..89c74d2ef 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd @@ -46,6 +46,7 @@ and platform-specific tools are installed in $SDK/platform-tools - There's a new element in . The tool package now requires that at least some minimal version of be installed. + - It removes the repository type, which is now in its own XML Schema. --> @@ -58,7 +59,6 @@ - @@ -109,65 +109,6 @@ - - - - - An SDK add-on package. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -319,8 +260,8 @@ An SDK extra package. This kind of package is for "free" content and specifies in which fixed root directory it must be installed. - The paths "add-ons", "platforms", "tools" and "docs" are - reserved and cannot be used. + Path names matching existing package types here (e.g. "add-ons", + "platforms", "tools", "docs", etc.) are reserved and cannot be used. diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkAddonSourceTest.java similarity index 50% rename from sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java rename to sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkAddonSourceTest.java index 87da29415..57f079736 100755 --- a/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkAddonSourceTest.java @@ -16,28 +16,44 @@ package com.android.sdklib.internal.repository; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkAddonConstants; import org.w3c.dom.Document; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; import junit.framework.TestCase; /** - * Tests for {@link RepoSource} + * Tests for {@link SdkAddonSource} */ -public class RepoSourceTest extends TestCase { +public class SdkAddonSourceTest extends TestCase { private static class MockMonitor implements ITaskMonitor { + + String mCapturedResults = ""; + String mCapturedDescriptions = ""; + + public String getCapturedResults() { + return mCapturedResults; + } + + public String getCapturedDescriptions() { + return mCapturedDescriptions; + } + public void setResult(String resultFormat, Object... args) { + mCapturedResults += String.format(resultFormat, args) + "\n"; } public void setProgressMax(int max) { } public void setDescription(String descriptionFormat, Object... args) { + mCapturedDescriptions += String.format(descriptionFormat, args) + "\n"; } public boolean isCancelRequested() { @@ -64,9 +80,9 @@ public class RepoSourceTest extends TestCase { * An internal helper class to give us visibility to the protected members we want * to test. */ - private static class MockRepoSource extends RepoSource { - public MockRepoSource() { - super("fake-url", false /*userSource*/); + private static class MockSdkAddonSource extends SdkAddonSource { + public MockSdkAddonSource() { + super("fake-url", true /*userSource*/); } public Document _findAlternateToolsXml(InputStream xml) { @@ -76,15 +92,29 @@ public class RepoSourceTest extends TestCase { public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { return super.parsePackages(doc, nsUri, monitor); } + + public int _getXmlSchemaVersion(InputStream xml) { + return super.getXmlSchemaVersion(xml); + } + + public String _validateXml(InputStream xml, String url, int version, + String[] outError, Boolean[] validatorFound) { + return super.validateXml(xml, url, version, outError, validatorFound); + } + + public Document _getDocument(InputStream xml, ITaskMonitor monitor) { + return super.getDocument(xml, monitor); + } + } - private MockRepoSource mSource; + private MockSdkAddonSource mSource; @Override protected void setUp() throws Exception { super.setUp(); - mSource = new MockRepoSource(); + mSource = new MockSdkAddonSource(); } @Override @@ -94,7 +124,7 @@ public class RepoSourceTest extends TestCase { mSource = null; } - public void testFindAlternateToolsXml_Errors() { + public void testFindAlternateToolsXml_Errors() throws Exception { // Support null as input Document result = mSource._findAlternateToolsXml(null); assertNull(result); @@ -142,22 +172,94 @@ public class RepoSourceTest extends TestCase { assertNull(result); } - public void testFindAlternateToolsXml_1() { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_1.xml"); + /** + * Validate that findAlternateToolsXml doesn't work for addon even + * when trying to load a valid addon xml. + */ + public void testFindAlternateToolsXml_1() throws Exception { + InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_1.xml"); Document result = mSource._findAlternateToolsXml(xmlStream); - assertNotNull(result); - assertTrue(mSource._parsePackages(result, - SdkRepository.NS_SDK_REPOSITORY, new MockMonitor())); + assertNull(result); + } - // check the packages we found... we expected to find 2 tool packages with 1 archive each. + /** + * Validate we can still load a valid addon schema version 1 + */ + public void testLoadOldXml_1() throws Exception { + InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_1.xml"); + + // guess the version from the XML document + int version = mSource._getXmlSchemaVersion(xmlStream); + assertEquals(1, version); + + Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; + String[] validationError = new String[] { null }; + String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_XML_FILE; + + String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); + assertEquals(Boolean.TRUE, validatorFound[0]); + assertEquals(null, validationError[0]); + assertEquals(SdkAddonConstants.getSchemaUri(1), uri); + + // Validation was successful, load the document + MockMonitor monitor = new MockMonitor(); + Document doc = mSource._getDocument(xmlStream, monitor); + assertNotNull(doc); + + // Get the packages + assertTrue(mSource._parsePackages(doc, uri, monitor)); + + assertEquals("Found My First add-on by John Doe, Android API 1, revision 1\n" + + "Found My Second add-on by John Deer, Android API 2, revision 42\n" + + "Found This add-on has no libraries by Joe Bar, Android API 4, revision 3\n" + + "Found Usb Driver package, revision 43 (Obsolete)\n" + + "Found Extra Api Dep package, revision 2 (Obsolete)\n", + monitor.getCapturedDescriptions()); + assertEquals("", monitor.getCapturedResults()); + + // check the packages we found... we expected to find 11 packages with each at least + // one archive. Package[] pkgs = mSource.getPackages(); - assertEquals(2, pkgs.length); + assertEquals(5, pkgs.length); for (Package p : pkgs) { - assertEquals(ToolPackage.class, p.getClass()); - assertEquals(1, p.getArchives().length); + assertTrue(p.getArchives().length >= 1); } } + /** + * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, + * which has the advantage that we can use {@link InputStream#reset()} on it + * at any time to read it multiple times. + *

+ * The default for getResourceAsStream() is to return a {@link FileInputStream} that + * does not support reset(), yet we need it in the tested code. + * + * @throws IOException if some I/O read fails + */ + private ByteArrayInputStream getTestResource(String filename) throws IOException { + InputStream xmlStream = this.getClass().getResourceAsStream(filename); + + try { + byte[] data = new byte[8192]; + int offset = 0; + int n; + + while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { + offset += n; + + if (offset == data.length) { + byte[] newData = new byte[offset + 8192]; + System.arraycopy(data, 0, newData, 0, offset); + data = newData; + } + } + + return new ByteArrayInputStream(data, 0, offset); + } finally { + if (xmlStream != null) { + xmlStream.close(); + } + } + } } diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkRepoSourceTest.java b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkRepoSourceTest.java new file mode 100755 index 000000000..dabcd5ebe --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/SdkRepoSourceTest.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2009 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.sdklib.internal.repository; + +import com.android.sdklib.repository.SdkRepoConstants; + +import org.w3c.dom.Document; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.TestCase; + +/** + * Tests for {@link SdkRepoSource} + */ +public class SdkRepoSourceTest extends TestCase { + + private static class MockMonitor implements ITaskMonitor { + + String mCapturedResults = ""; + String mCapturedDescriptions = ""; + + public String getCapturedResults() { + return mCapturedResults; + } + + public String getCapturedDescriptions() { + return mCapturedDescriptions; + } + + public void setResult(String resultFormat, Object... args) { + mCapturedResults += String.format(resultFormat, args) + "\n"; + } + + public void setProgressMax(int max) { + } + + public void setDescription(String descriptionFormat, Object... args) { + mCapturedDescriptions += String.format(descriptionFormat, args) + "\n"; + } + + public boolean isCancelRequested() { + return false; + } + + public void incProgress(int delta) { + } + + public int getProgress() { + return 0; + } + + public boolean displayPrompt(String title, String message) { + return false; + } + + public ITaskMonitor createSubMonitor(int tickCount) { + return null; + } + } + + /** + * An internal helper class to give us visibility to the protected members we want + * to test. + */ + private static class MockSdkRepoSource extends SdkRepoSource { + public MockSdkRepoSource() { + super("fake-url"); + } + + public Document _findAlternateToolsXml(InputStream xml) throws IOException { + return super.findAlternateToolsXml(xml); + } + + public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { + return super.parsePackages(doc, nsUri, monitor); + } + + public int _getXmlSchemaVersion(InputStream xml) { + return super.getXmlSchemaVersion(xml); + } + + public String _validateXml(InputStream xml, String url, int version, + String[] outError, Boolean[] validatorFound) { + return super.validateXml(xml, url, version, outError, validatorFound); + } + + public Document _getDocument(InputStream xml, ITaskMonitor monitor) { + return super.getDocument(xml, monitor); + } + + } + + private MockSdkRepoSource mSource; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mSource = new MockSdkRepoSource(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + mSource = null; + } + + public void testFindAlternateToolsXml_Errors() throws Exception { + // Support null as input + Document result = mSource._findAlternateToolsXml(null); + assertNull(result); + + // Support an empty input + String str = ""; + ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes()); + result = mSource._findAlternateToolsXml(input); + assertNull(result); + + // Support a random string as input + str = "Some random string, not even HTML nor XML"; + input = new ByteArrayInputStream(str.getBytes()); + result = mSource._findAlternateToolsXml(input); + assertNull(result); + + // Support an HTML input, e.g. a typical 404 document as returned by DL + str = " " + + " " + + "404 Not Found " + " " + " " + " " + + " " + + " " + + " " + + "
" + + "Google   " + + " 
Error
 
" + "

" + "

Not Found

" + + "The requested URL /404 was not found on this server." + " " + "

" + + "

" + + "
\"\"
" + + " "; + input = new ByteArrayInputStream(str.getBytes()); + result = mSource._findAlternateToolsXml(input); + assertNull(result); + + // Support some random XML document, totally unrelated to our sdk-repository schema + str = "" + + "" + + " " + + ""; + input = new ByteArrayInputStream(str.getBytes()); + result = mSource._findAlternateToolsXml(input); + assertNull(result); + } + + /** + * Validate we can load a new schema version 3 using the "alternate future tool" mode. + */ + public void testFindAlternateToolsXml_3() throws Exception { + InputStream xmlStream = getTestResource( + "/com/android/sdklib/testdata/repository_sample_3.xml"); + + Document result = mSource._findAlternateToolsXml(xmlStream); + assertNotNull(result); + MockMonitor mon = new MockMonitor(); + assertTrue(mSource._parsePackages(result, SdkRepoConstants.NS_URI, mon)); + + assertEquals("Found Android SDK Tools, revision 1\n" + + "Found Android SDK Tools, revision 42\n" + + "Found Android SDK Platform-tools, revision 3\n", + mon.getCapturedDescriptions()); + assertEquals("", mon.getCapturedResults()); + + // check the packages we found... we expected to find 2 tool packages and 1 + // platform-tools package, with at least 1 archive each. + Package[] pkgs = mSource.getPackages(); + assertEquals(3, pkgs.length); + for (Package p : pkgs) { + assertTrue((p instanceof ToolPackage) || (p instanceof PlatformToolPackage)); + assertTrue(p.getArchives().length >= 1); + } + } + + /** + * Validate we can still load an old repository in schema version 1 + */ + public void testLoadOldXml_1() throws Exception { + InputStream xmlStream = getTestResource( + "/com/android/sdklib/testdata/repository_sample_1.xml"); + + // guess the version from the XML document + int version = mSource._getXmlSchemaVersion(xmlStream); + assertEquals(1, version); + + Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; + String[] validationError = new String[] { null }; + String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_XML_FILE; + + String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); + assertEquals(Boolean.TRUE, validatorFound[0]); + assertEquals(null, validationError[0]); + assertEquals(SdkRepoConstants.getSchemaUri(1), uri); + + // Validation was successful, load the document + MockMonitor monitor = new MockMonitor(); + Document doc = mSource._getDocument(xmlStream, monitor); + assertNotNull(doc); + + // Get the packages + assertTrue(mSource._parsePackages(doc, uri, monitor)); + + assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + + "Found Documentation for Android SDK, API 1, revision 1\n" + + "Found My First add-on by John Doe, Android API 1, revision 1\n" + + "Found SDK Platform Android 1.1, API 2, revision 12\n" + + "Found My Second add-on by John Deer, Android API 2, revision 42\n" + + "Found SDK Platform Android Pastry Preview, revision 3\n" + + "Found Android SDK Tools, revision 1\n" + + "Found Documentation for Android SDK, API 2, revision 42\n" + + "Found Android SDK Tools, revision 42\n" + + "Found This add-on has no libraries by Joe Bar, Android API 4, revision 3\n" + + "Found Usb Driver package, revision 43\n", + monitor.getCapturedDescriptions()); + assertEquals("", monitor.getCapturedResults()); + + // check the packages we found... we expected to find 11 packages with each at least + // one archive. + Package[] pkgs = mSource.getPackages(); + assertEquals(11, pkgs.length); + for (Package p : pkgs) { + assertTrue(p.getArchives().length >= 1); + } + } + + /** + * Validate we can still load an old repository in schema version 2 + */ + public void testLoadOldXml_2() throws Exception { + InputStream xmlStream = getTestResource( + "/com/android/sdklib/testdata/repository_sample_2.xml"); + + // guess the version from the XML document + int version = mSource._getXmlSchemaVersion(xmlStream); + assertEquals(2, version); + + Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; + String[] validationError = new String[] { null }; + String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_XML_FILE; + + String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); + assertEquals(Boolean.TRUE, validatorFound[0]); + assertEquals(null, validationError[0]); + assertEquals(SdkRepoConstants.getSchemaUri(2), uri); + + // Validation was successful, load the document + MockMonitor monitor = new MockMonitor(); + Document doc = mSource._getDocument(xmlStream, monitor); + assertNotNull(doc); + + // Get the packages + assertTrue(mSource._parsePackages(doc, uri, monitor)); + + assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + + "Found Documentation for Android SDK, API 1, revision 1\n" + + "Found My First add-on by John Doe, Android API 1, revision 1\n" + + "Found SDK Platform Android 1.1, API 2, revision 12\n" + + "Found My Second add-on by John Deer, Android API 2, revision 42\n" + + "Found SDK Platform Android Pastry Preview, revision 3\n" + + "Found Android SDK Tools, revision 1\n" + + "Found Documentation for Android SDK, API 2, revision 42\n" + + "Found Android SDK Tools, revision 42\n" + + "Found This add-on has no libraries by Joe Bar, Android API 4, revision 3\n" + + "Found Usb Driver package, revision 43 (Obsolete)\n" + + "Found Extra Api Dep package, revision 2 (Obsolete)\n" + + "Found Samples for SDK API 14, revision 24 (Obsolete)\n", + monitor.getCapturedDescriptions()); + assertEquals("", monitor.getCapturedResults()); + + // check the packages we found... we expected to find 13 packages with each at least + // one archive. + Package[] pkgs = mSource.getPackages(); + assertEquals(13, pkgs.length); + for (Package p : pkgs) { + assertTrue(p.getArchives().length >= 1); + } + } + + /** + * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, + * which has the advantage that we can use {@link InputStream#reset()} on it + * at any time to read it multiple times. + *

+ * The default for getResourceAsStream() is to return a {@link FileInputStream} that + * does not support reset(), yet we need it in the tested code. + * + * @throws IOException if some I/O read fails + */ + private ByteArrayInputStream getTestResource(String filename) throws IOException { + InputStream xmlStream = this.getClass().getResourceAsStream(filename); + + try { + byte[] data = new byte[8192]; + int offset = 0; + int n; + + while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { + offset += n; + + if (offset == data.length) { + byte[] newData = new byte[offset + 8192]; + System.arraycopy(data, 0, newData, 0, offset); + data = newData; + } + } + + return new ByteArrayInputStream(data, 0, offset); + } finally { + if (xmlStream != null) { + xmlStream.close(); + } + } + } +} diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java b/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java index 14b0b6071..2bbc088fb 100755 --- a/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java @@ -112,7 +112,7 @@ public class SdkRepositoryTest extends TestCase { /** Helper method that returns a validator for our XSD */ private Validator getValidator(int version, CaptureErrorHandler handler) throws SAXException { - InputStream xsdStream = SdkRepository.getXsdStream(version); + InputStream xsdStream = SdkRepoConstants.getXsdStream(version); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = factory.newSchema(new StreamSource(xsdStream)); Validator validator = schema.newValidator(); @@ -177,7 +177,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, handler); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, handler); try { validator.validate(source); @@ -193,7 +193,7 @@ public class SdkRepositoryTest extends TestCase { private static String OPEN_TAG = ""; private static String CLOSE_TAG = ""; @@ -207,7 +207,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, handler); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, handler); validator.validate(source); handler.verify(); } @@ -222,7 +222,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, null); try { validator.validate(source); } catch (SAXParseException e) { @@ -244,7 +244,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, null); try { validator.validate(source); } catch (SAXParseException e) { @@ -266,7 +266,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, null); try { validator.validate(source); } catch (SAXParseException e) { @@ -294,7 +294,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, null); try { validator.validate(source); } catch (SAXParseException e) { @@ -320,7 +320,7 @@ public class SdkRepositoryTest extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null); + Validator validator = getValidator(SdkRepoConstants.NS_LATEST_VERSION, null); try { validator.validate(source); } catch (SAXParseException e) { diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/addon_sample_1.xml b/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/addon_sample_1.xml new file mode 100755 index 000000000..7e304b94f --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/addon_sample_1.xml @@ -0,0 +1,144 @@ + + + + + + + + This is the license + for this platform. + + + + Licenses are only of type 'text' right now, so this is implied. + + + + + + My First add-on + 1 + John Doe + 1 + + Some optional description + http://www.example.com/myfirstaddon + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + http://www.example.com/add-ons/first.zip + + + + + + android.blah.somelib + The description for this library. + + + + com.android.mymaps + + + + + + My Second add-on + 2 + John Deer + 42 + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/second-42-win.zip + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/second-42-linux.tar.bz2 + + + + + android.blah.somelib + The description for this library. + + + com.android.mymaps + + + + + + + + This add-on has no libraries + 4 + Joe Bar + 3 + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/imnotanarchiveimadoctorjim.zip + + + + + + + + usb_driver + + 43 + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/extraduff.zip + + + An Extra package for the USB driver, it will install in $SDK/usb_driver + http://www.example.com/extra.html + 3 + + + + + extra_api_dep + + 2 + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/extra_mega_duff.zip + + + Some extra package that has a min-api-level of 42 + http://www.example.com/extra.html + 3 + 42 + + + + diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_3.xml b/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_3.xml index 4b2779e61..feaad6a8c 100755 --- a/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_3.xml +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_3.xml @@ -69,34 +69,6 @@ - - My First add-on - 1 - John Doe - 1 - - Some optional description - http://www.example.com/myfirstaddon - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - http://www.example.com/add-ons/first.zip - - - - - - android.blah.somelib - The description for this library. - - - - com.android.mymaps - - - - 1.1 2 @@ -133,35 +105,6 @@ - - My Second add-on - 2 - John Deer - 42 - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - distrib/second-42-win.zip - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - distrib/second-42-linux.tar.bz2 - - - - - android.blah.somelib - The description for this library. - - - com.android.mymaps - - - - - Pastry 5 @@ -263,23 +206,6 @@ - - - This add-on has no libraries - 4 - Joe Bar - 3 - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - distrib/imnotanarchiveimadoctorjim.zip - - - - - - usb_driver diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java index c124b4784..444e99858 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java @@ -18,7 +18,7 @@ package com.android.sdkuilib.internal.repository; import com.android.sdklib.internal.repository.IDescription; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.SdkSource; import com.android.sdkuilib.internal.repository.icons.ImageFactory; import org.eclipse.jface.viewers.IContentProvider; @@ -90,7 +90,7 @@ class LocalSdkAdapter { /** * Called to collect the root elements for the given input. * The input here is a {@link LocalSdkAdapter} object, this returns an array - * of {@link RepoSource}. + * of {@link SdkSource}. */ public Object[] getElements(Object inputElement) { if (inputElement == LocalSdkAdapter.this) { diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java index fe2734d39..ac6c0c886 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java @@ -20,7 +20,8 @@ package com.android.sdkuilib.internal.repository; import com.android.sdklib.internal.repository.Archive; import com.android.sdklib.internal.repository.IDescription; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.SdkAddonSource; +import com.android.sdklib.internal.repository.SdkSource; import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener; import org.eclipse.jface.dialogs.IInputValidator; @@ -260,7 +261,7 @@ public class RemotePackagesPage extends Composite implements ISdkListener { (ITreeContentProvider) mTreeViewerSources.getContentProvider(); // When selecting, we want to only select compatible archives. - if (elem instanceof RepoSource) { + if (elem instanceof SdkSource) { mTreeViewerSources.setExpandedState(elem, true); for (Object pkg : provider.getChildren(elem)) { mTreeViewerSources.setChecked(pkg, true); @@ -328,7 +329,7 @@ public class RemotePackagesPage extends Composite implements ISdkListener { private void onAddSiteSelected() { - final RepoSource[] knowSources = mUpdaterData.getSources().getSources(); + final SdkSource[] knowSources = mUpdaterData.getSources().getSources(); String title = "Add Add-on Site URL"; String msg = @@ -358,7 +359,7 @@ public class RemotePackagesPage extends Composite implements ISdkListener { // Reject URLs that are already in the source list. // URLs are generally case-insensitive (except for file:// where it all depends // on the current OS so we'll ignore this case.) - for (RepoSource s : knowSources) { + for (SdkSource s : knowSources) { if (newText.equalsIgnoreCase(s.getUrl())) { return "Error : This site is already listed."; } @@ -370,7 +371,7 @@ public class RemotePackagesPage extends Composite implements ISdkListener { if (dlg.open() == Window.OK) { String url = dlg.getValue(); - mUpdaterData.getSources().add(new RepoSource(url, true /*userSource*/)); + mUpdaterData.getSources().add(new SdkAddonSource(url, true /*userSource*/)); onRefreshSelected(); } } @@ -381,8 +382,8 @@ public class RemotePackagesPage extends Composite implements ISdkListener { ISelection sel = mTreeViewerSources.getSelection(); if (mUpdaterData != null && sel instanceof ITreeSelection) { for (Object c : ((ITreeSelection) sel).toList()) { - if (c instanceof RepoSource && ((RepoSource) c).isUserSource()) { - RepoSource source = (RepoSource) c; + if (c instanceof SdkSource && ((SdkSource) c).isUserSource()) { + SdkSource source = (SdkSource) c; String title = "Delete Add-on Site?"; @@ -437,8 +438,8 @@ public class RemotePackagesPage extends Composite implements ISdkListener { ISelection sel = mTreeViewerSources.getSelection(); if (sel instanceof ITreeSelection) { for (Object c : ((ITreeSelection) sel).toList()) { - if (c instanceof RepoSource && - ((RepoSource) c).isUserSource()) { + if (c instanceof SdkSource && + ((SdkSource) c).isUserSource()) { hasSelectedUserSource = true; break; } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java index 625cf3a7e..3a44bb4f9 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java @@ -21,7 +21,7 @@ import com.android.sdklib.internal.repository.IDescription; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskMonitor; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.SdkSource; import com.android.sdklib.internal.repository.Package.UpdateInfo; import com.android.sdkuilib.internal.repository.icons.ImageFactory; @@ -50,9 +50,9 @@ public class RepoSourcesAdapter { */ public static class RepoSourceError implements IDescription { - private final RepoSource mSource; + private final SdkSource mSource; - public RepoSourceError(RepoSource source) { + public RepoSourceError(SdkSource source) { mSource = source; } @@ -72,10 +72,10 @@ public class RepoSourcesAdapter { */ public static class RepoSourceEmpty implements IDescription { - private final RepoSource mSource; + private final SdkSource mSource; private final boolean mEmptyBecauseOfUpdateOnly; - public RepoSourceEmpty(RepoSource source, boolean emptyBecauseOfUpdateOnly) { + public RepoSourceEmpty(SdkSource source, boolean emptyBecauseOfUpdateOnly) { mSource = source; mEmptyBecauseOfUpdateOnly = emptyBecauseOfUpdateOnly; } @@ -150,7 +150,7 @@ public class RepoSourcesAdapter { /** * Called to collect the root elements for the given input. * The input here is a {@link RepoSourcesAdapter} object, this returns an array - * of {@link RepoSource}. + * of {@link SdkSource}. */ public Object[] getElements(Object inputElement) { return getChildren(inputElement); @@ -160,16 +160,16 @@ public class RepoSourcesAdapter { * Get the children of the given parent. This is requested on-demand as * nodes are expanded. * - * For a {@link RepoSourcesAdapter} object, returns an array of {@link RepoSource}s. - * For a {@link RepoSource}, returns an array of {@link Package}s. + * For a {@link RepoSourcesAdapter} object, returns an array of {@link SdkSource}s. + * For a {@link SdkSource}, returns an array of {@link Package}s. * For a {@link Package}, returns an array of {@link Archive}s. */ public Object[] getChildren(Object parentElement) { if (parentElement == RepoSourcesAdapter.this) { return mUpdaterData.getSources().getSources(); - } else if (parentElement instanceof RepoSource) { - return getRepoSourceChildren((RepoSource) parentElement); + } else if (parentElement instanceof SdkSource) { + return getRepoSourceChildren((SdkSource) parentElement); } else if (parentElement instanceof Package) { return getPackageChildren((Package) parentElement); @@ -183,7 +183,7 @@ public class RepoSourcesAdapter { * only update packages. If the list is empty, returns a specific empty node. If there's * an error, returns a specific error node. */ - private Object[] getRepoSourceChildren(final RepoSource source) { + private Object[] getRepoSourceChildren(final SdkSource source) { Package[] packages = source.getPackages(); if (packages == null && source.getFetchError() == null) { @@ -250,11 +250,11 @@ public class RepoSourcesAdapter { /** * Returns the parent of a given element. - * The input {@link RepoSourcesAdapter} is the parent of all {@link RepoSource} elements. + * The input {@link RepoSourcesAdapter} is the parent of all {@link SdkSource} elements. */ public Object getParent(Object element) { - if (element instanceof RepoSource) { + if (element instanceof SdkSource) { return RepoSourcesAdapter.this; } else if (element instanceof Package) { @@ -269,11 +269,11 @@ public class RepoSourcesAdapter { /** * Returns true if a given element has children, which is used to display a * "+/expand" box next to the tree node. - * All {@link RepoSource} and {@link Package} are expandable, whether they actually + * All {@link SdkSource} and {@link Package} are expandable, whether they actually * have any children or not. */ public boolean hasChildren(Object element) { - return element instanceof RepoSource || element instanceof Package; + return element instanceof SdkSource || element instanceof Package; } } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateNoWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateNoWindow.java index be8f8410f..53ddd1ec0 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateNoWindow.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateNoWindow.java @@ -21,7 +21,7 @@ import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskFactory; import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkRepoConstants; import java.util.ArrayList; @@ -87,7 +87,7 @@ public class UpdateNoWindow { /** * Performs the actual update. * - * @param pkgFilter A list of {@link SdkRepository#NODES} to limit the type of packages + * @param pkgFilter A list of {@link SdkRepoConstants#NODES} to limit the type of packages * we can update. A null or empty list means to update everything possible. * @param includeObsoletes True to also list and install obsolete packages. * @param dryMode True to check what would be updated/installed but do not actually diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index dd98b0080..81f567a8d 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -28,10 +28,13 @@ import com.android.sdklib.internal.repository.ITaskFactory; import com.android.sdklib.internal.repository.ITaskMonitor; import com.android.sdklib.internal.repository.LocalSdkParser; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; -import com.android.sdklib.internal.repository.RepoSources; +import com.android.sdklib.internal.repository.SdkAddonSource; +import com.android.sdklib.internal.repository.SdkRepoSource; +import com.android.sdklib.internal.repository.SdkSource; +import com.android.sdklib.internal.repository.SdkSources; import com.android.sdklib.internal.repository.ToolPackage; -import com.android.sdklib.repository.SdkRepository; +import com.android.sdklib.repository.SdkAddonConstants; +import com.android.sdklib.repository.SdkRepoConstants; import com.android.sdkuilib.internal.repository.icons.ImageFactory; import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener; @@ -61,7 +64,7 @@ class UpdaterData { private AvdManager mAvdManager; private final LocalSdkParser mLocalSdkParser = new LocalSdkParser(); - private final RepoSources mSources = new RepoSources(); + private final SdkSources mSources = new SdkSources(); private final LocalSdkAdapter mLocalSdkAdapter = new LocalSdkAdapter(this); private final RepoSourcesAdapter mSourcesAdapter = new RepoSourcesAdapter(this); @@ -113,7 +116,7 @@ class UpdaterData { return mUserCanChangeSdkRoot; } - public RepoSources getSources() { + public SdkSources getSources() { return mSources; } @@ -288,8 +291,9 @@ class UpdaterData { * - and finally the extra user repo URLs from the environment. */ public void setupDefaultSources() { - RepoSources sources = getSources(); - sources.add(new RepoSource(SdkRepository.URL_GOOGLE_SDK_REPO_SITE, false /*userSource*/)); + SdkSources sources = getSources(); + sources.add(new SdkRepoSource(SdkRepoConstants.URL_GOOGLE_SDK_SITE)); + sources.add(new SdkAddonSource(SdkAddonConstants.URL_GOOGLE_SDK_SITE, false /*userSource*/)); // SDK_UPDATER_URLS is a semicolon-separated list of URLs that can be used to // seed the SDK Updater list for full repositories. @@ -298,7 +302,11 @@ class UpdaterData { String[] urls = str.split(";"); for (String url : urls) { if (url != null && url.length() > 0) { - RepoSource s = new RepoSource(url, false /*userSource*/); + SdkSource s = new SdkRepoSource(url); + if (!sources.hasSource(s)) { + sources.add(s); + } + s = new SdkAddonSource(url, false /*userSource*/); if (!sources.hasSource(s)) { sources.add(s); } @@ -317,7 +325,7 @@ class UpdaterData { String[] urls = str.split(";"); for (String url : urls) { if (url != null && url.length() > 0) { - RepoSource s = new RepoSource(url, true /*userSource*/); + SdkSource s = new SdkAddonSource(url, true /*userSource*/); if (!sources.hasSource(s)) { sources.add(s); } @@ -628,7 +636,7 @@ class UpdaterData { * This version is intended to run without a GUI and * only outputs to the current {@link ISdkLog}. * - * @param pkgFilter A list of {@link SdkRepository#NODES} to limit the type of packages + * @param pkgFilter A list of {@link SdkRepoConstants#NODES} to limit the type of packages * we can update. A null or empty list means to update everything possible. * @param includeObsoletes True to also list and install obsolete packages. * @param dryMode True to check what would be updated/installed but do not actually @@ -664,7 +672,7 @@ class UpdaterData { // Automatically find the classes matching the node names ClassLoader classLoader = getClass().getClassLoader(); String basePackage = Package.class.getPackage().getName(); - for (String node : SdkRepository.NODES) { + for (String node : SdkRepoConstants.NODES) { // Capitalize the name String name = node.substring(0, 1).toUpperCase() + node.substring(1); @@ -700,7 +708,7 @@ class UpdaterData { } } - if (SdkRepository.NODES.length != pkgMap.size()) { + if (SdkRepoConstants.NODES.length != pkgMap.size()) { // Sanity check in case we forget to update this node array. // We don't cancel the operation though. mSdkLog.printf( @@ -783,9 +791,9 @@ class UpdaterData { mTaskFactory.start("Refresh Sources", new ITask() { public void run(ITaskMonitor monitor) { - RepoSource[] sources = mSources.getSources(); + SdkSource[] sources = mSources.getSources(); monitor.setProgressMax(sources.length); - for (RepoSource source : sources) { + for (SdkSource source : sources) { if (forceFetching || source.getPackages() != null || source.getFetchError() != null) { diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java index 81a11a276..9c26388b6 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java @@ -30,8 +30,8 @@ import com.android.sdklib.internal.repository.MinToolsPackage; import com.android.sdklib.internal.repository.Package; import com.android.sdklib.internal.repository.PlatformPackage; import com.android.sdklib.internal.repository.PlatformToolPackage; -import com.android.sdklib.internal.repository.RepoSource; -import com.android.sdklib.internal.repository.RepoSources; +import com.android.sdklib.internal.repository.SdkSource; +import com.android.sdklib.internal.repository.SdkSources; import com.android.sdklib.internal.repository.SamplePackage; import com.android.sdklib.internal.repository.ToolPackage; import com.android.sdklib.internal.repository.Package.UpdateInfo; @@ -58,13 +58,13 @@ class UpdaterLogic { */ public ArrayList computeUpdates( Collection selectedArchives, - RepoSources sources, + SdkSources sources, Package[] localPkgs, boolean includeObsoletes) { ArrayList archives = new ArrayList(); ArrayList remotePkgs = new ArrayList(); - RepoSource[] remoteSources = sources.getSources(); + SdkSource[] remoteSources = sources.getSources(); // Create ArchiveInfos out of local (installed) packages. ArchiveInfo[] localArchives = createLocalArchives(localPkgs); @@ -96,7 +96,7 @@ class UpdaterLogic { */ public void addNewPlatforms( ArrayList archives, - RepoSources sources, + SdkSources sources, Package[] localPkgs, boolean includeObsoletes) { @@ -137,7 +137,7 @@ class UpdaterLogic { } } - RepoSource[] remoteSources = sources.getSources(); + SdkSource[] remoteSources = sources.getSources(); ArrayList remotePkgs = new ArrayList(); fetchRemotePackages(remotePkgs, remoteSources); @@ -248,7 +248,7 @@ class UpdaterLogic { private Collection findUpdates( ArchiveInfo[] localArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, boolean includeObsoletes) { ArrayList updates = new ArrayList(); @@ -285,7 +285,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives, boolean automated) { Package p = archive.getParentPackage(); @@ -351,7 +351,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives) { // Current dependencies can be: @@ -440,7 +440,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives) { // This is the requirement to match. int rev = pkg.getMinToolsRevision(); @@ -538,7 +538,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives) { // This is the requirement to match. int rev = pkg.getMinPlatformToolsRevision(); @@ -637,7 +637,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives) { // This is the requirement to match. AndroidVersion v = pkg.getVersion(); @@ -736,7 +736,7 @@ class UpdaterLogic { ArrayList outArchives, Collection selectedArchives, ArrayList remotePkgs, - RepoSource[] remoteSources, + SdkSource[] remoteSources, ArchiveInfo[] localArchives) { int api = pkg.getMinApiLevel(); @@ -840,12 +840,12 @@ class UpdaterLogic { } /** Fetch all remote packages only if really needed. */ - protected void fetchRemotePackages(ArrayList remotePkgs, RepoSource[] remoteSources) { + protected void fetchRemotePackages(ArrayList remotePkgs, SdkSource[] remoteSources) { if (remotePkgs.size() > 0) { return; } - for (RepoSource remoteSrc : remoteSources) { + for (SdkSource remoteSrc : remoteSources) { Package[] pkgs = remoteSrc.getPackages(); if (pkgs != null) { nextPackage: for (Package pkg : pkgs) { diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java index 5111f49e6..b4ccaf227 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java @@ -18,7 +18,7 @@ package com.android.sdkuilib.internal.repository.icons; import com.android.sdklib.internal.repository.Archive; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.SdkSource; import com.android.sdkuilib.internal.repository.RepoSourcesAdapter; import org.eclipse.swt.SWTException; @@ -79,7 +79,7 @@ public class ImageFactory { /** * Loads and returns the appropriate image for a given package, archive or source object. * - * @param object A {@link RepoSource} or {@link Package} or {@link Archive}. + * @param object A {@link SdkSource} or {@link Package} or {@link Archive}. * @return A new or existing {@link Image}. The caller must NOT dispose the image (the * image will disposed by {@link #dispose()}). The returned image can be null if the * expected file is missing. @@ -97,7 +97,7 @@ public class ImageFactory { return getImageByName(name); } - if (object instanceof RepoSource) { + if (object instanceof SdkSource) { return getImageByName("source_icon16.png"); //$NON-NLS-1$ } else if (object instanceof RepoSourcesAdapter.RepoSourceError) { diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java index 5e5259ac1..485619ac7 100755 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java +++ b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java @@ -22,7 +22,7 @@ import com.android.sdklib.internal.repository.MockPlatformPackage; import com.android.sdklib.internal.repository.MockPlatformToolPackage; import com.android.sdklib.internal.repository.MockToolPackage; import com.android.sdklib.internal.repository.Package; -import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.SdkSource; import java.util.ArrayList; import java.util.Arrays; @@ -40,7 +40,7 @@ public class UpdaterLogicTest extends TestCase { @Override protected void fetchRemotePackages(ArrayList remotePkgs, - RepoSource[] remoteSources) { + SdkSource[] remoteSources) { // Ignore remoteSources and instead uses the remotePackages list given to the // constructor. if (mRemotePackages != null) { @@ -71,7 +71,7 @@ public class UpdaterLogicTest extends TestCase { Package[] localPkgs = { p1, a1 }; ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - RepoSource[] sources = null; + SdkSource[] sources = null; // a2 now depends on a "fake" archive info with no newArchive that wraps the missing // underlying platform. @@ -114,7 +114,7 @@ public class UpdaterLogicTest extends TestCase { Package[] localPkgs = { t1, pt1 }; ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - RepoSource[] sources = null; + SdkSource[] sources = null; // p2 now depends on a "fake" archive info with no newArchive that wraps the missing // underlying tool @@ -155,7 +155,7 @@ public class UpdaterLogicTest extends TestCase { Package[] localPkgs = { t1 }; ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - RepoSource[] sources = null; + SdkSource[] sources = null; // p2 now depends on a "fake" archive info with no newArchive that wraps the missing // underlying tool -- 2.11.0