diff options
25 files changed, 1297 insertions, 48 deletions
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java index 216e309..0880645 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java @@ -57,14 +57,21 @@ import javax.xml.validation.Validator; */
public class AddonsListFetcher {
+ public enum SiteType {
+ ADDON_SITE,
+ SYS_IMG_SITE
+ }
+
/**
* An immutable structure representing an add-on site.
*/
public static class Site {
private final String mUrl;
private final String mUiName;
+ private final SiteType mType;
- private Site(String url, String uiName) {
+ private Site(String url, String uiName, SiteType type) {
+ mType = type;
mUrl = url.trim();
mUiName = uiName;
}
@@ -76,6 +83,17 @@ public class AddonsListFetcher { public String getUiName() {
return mUiName;
}
+
+ public SiteType getType() {
+ return mType;
+ }
+
+ /** Returns a debug string representation of this object. Not for user display. */
+ @Override
+ public String toString() {
+ return String.format("<%1$s URL='%2$s' Name='%3$s'>", //$NON-NLS-1$
+ mType, mUrl, mUiName);
+ }
}
/**
@@ -92,7 +110,7 @@ public class AddonsListFetcher { url = url == null ? "" : url.trim();
- monitor.setProgressMax(5);
+ monitor.setProgressMax(6);
monitor.setDescription("Fetching %1$s", url);
monitor.incProgress(1);
@@ -102,7 +120,55 @@ public class AddonsListFetcher { Document validatedDoc = null;
String validatedUri = null;
+ String[] defaultNames = new String[SdkAddonsListConstants.NS_LATEST_VERSION];
+ for (int version = SdkAddonsListConstants.NS_LATEST_VERSION, i = 0;
+ version >= 1;
+ version--, i++) {
+ defaultNames[i] = SdkAddonsListConstants.getDefaultName(version);
+ }
+
InputStream xml = fetchUrl(url, cache, monitor.createSubMonitor(1), exception);
+ if (xml != null) {
+ int version = getXmlSchemaVersion(xml);
+ if (version == 0) {
+ xml = null;
+ }
+ }
+
+ // If we can't find the latest version, try earlier schema versions.
+ if (xml == null && defaultNames.length > 0) {
+ ITaskMonitor subMonitor = monitor.createSubMonitor(1);
+ subMonitor.setProgressMax(defaultNames.length);
+
+ String baseUrl = url;
+ if (!baseUrl.endsWith("/")) { //$NON-NLS-1$
+ int pos = baseUrl.lastIndexOf('/');
+ if (pos > 0) {
+ baseUrl = baseUrl.substring(0, pos + 1);
+ }
+ }
+
+ for (String name : defaultNames) {
+ String newUrl = baseUrl + name;
+ if (newUrl.equals(url)) {
+ continue;
+ }
+ xml = fetchUrl(newUrl, cache, subMonitor.createSubMonitor(1), exception);
+ if (xml != null) {
+ int version = getXmlSchemaVersion(xml);
+ if (version == 0) {
+ xml = null;
+ } else {
+ url = newUrl;
+ subMonitor.incProgress(
+ subMonitor.getProgressMax() - subMonitor.getProgress());
+ break;
+ }
+ }
+ }
+ } else {
+ monitor.incProgress(1);
+ }
if (xml != null) {
monitor.setDescription("Validate XML");
@@ -434,8 +500,22 @@ public class AddonsListFetcher { child != null;
child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE &&
- nsUri.equals(child.getNamespaceURI()) &&
- child.getLocalName().equals(SdkAddonsListConstants.NODE_ADDON_SITE)) {
+ nsUri.equals(child.getNamespaceURI())) {
+
+ String elementName = child.getLocalName();
+ SiteType type = null;
+
+ if (SdkAddonsListConstants.NODE_SYS_IMG_SITE.equals(elementName)) {
+ type = SiteType.SYS_IMG_SITE;
+
+ } else if (SdkAddonsListConstants.NODE_ADDON_SITE.equals(elementName)) {
+ type = SiteType.ADDON_SITE;
+ }
+
+ // Not an addon-site nor a sys-img-site, don't process this.
+ if (type == null) {
+ continue;
+ }
Node url = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_URL);
Node name = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_NAME);
@@ -451,7 +531,7 @@ public class AddonsListFetcher { }
if (strUrl.length() > 0 && strName.length() > 0) {
- sites.add(new Site(strUrl, strName));
+ sites.add(new Site(strUrl, strName, type));
}
}
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java index 39a134b..cff7e1a 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java @@ -34,7 +34,7 @@ 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.
+ * addon.xml filename will be appended automatically.
* @param uiName The UI-visible name of the source. Can be null.
*/
public SdkAddonSource(String url, String uiName) {
@@ -50,6 +50,16 @@ public class SdkAddonSource extends SdkSource { return true;
}
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return false;
+ }
+
+
@Override
protected String[] getDefaultXmlFileUrls() {
return new String[] { SdkAddonConstants.URL_DEFAULT_FILENAME };
@@ -86,8 +96,7 @@ public class SdkAddonSource extends SdkSource { }
/**
- * There is no support forward evolution of the sdk-addon schema yet since we
- * currently have only one version.
+ * This kind of schema does not support forward-evolution of the <tool> element.
*
* @param xml The input XML stream. Can be null.
* @return Always null.
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java index 482655f..9fe5574 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java @@ -65,6 +65,15 @@ public class SdkRepoSource extends SdkSource { return false;
}
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return false;
+ }
+
private static String[] sDefaults = null; // lazily allocated in getDefaultXmlFileUrls
@Override
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java index c07715b..8187480 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java @@ -126,6 +126,13 @@ public abstract class SdkSource implements IDescription, Comparable<SdkSource> { public abstract boolean isAddonSource();
/**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ public abstract boolean isSysImgSource();
+
+
+ /**
* Returns the basename of the default URLs to try to download the
* XML manifest.
* E.g. this is typically SdkRepoConstants.URL_DEFAULT_XML_FILE
@@ -373,7 +380,7 @@ public abstract class SdkSource implements IDescription, Comparable<SdkSource> { }
}
- for(String name : defaultNames) {
+ for (String name : defaultNames) {
String newUrl = baseUrl + name;
if (newUrl.equals(url)) {
continue;
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java new file mode 100755 index 0000000..7cee61d --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java @@ -0,0 +1,109 @@ +/*
+ * Copyright (C) 2012 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.sources;
+
+import com.android.annotations.Nullable;
+import com.android.sdklib.internal.repository.packages.Package;
+import com.android.sdklib.repository.SdkSysImgConstants;
+
+import org.w3c.dom.Document;
+
+import java.io.InputStream;
+
+
+/**
+ * An sdk-sys-img source, i.e. a download site for system-image packages.
+ * A repository describes one or more {@link Package}s available for download.
+ */
+public class SdkSysImgSource 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
+ * sys-img.xml filename will be appended automatically.
+ * @param uiName The UI-visible name of the source. Can be null.
+ */
+ public SdkSysImgSource(String url, String uiName) {
+ super(url, uiName);
+ }
+
+ /**
+ * Returns true if this is an addon source.
+ * We only load addons and extras from these sources.
+ */
+ @Override
+ public boolean isAddonSource() {
+ return false;
+ }
+
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return true;
+ }
+
+
+ @Override
+ protected String[] getDefaultXmlFileUrls() {
+ return new String[] { SdkSysImgConstants.URL_DEFAULT_FILENAME };
+ }
+
+ @Override
+ protected int getNsLatestVersion() {
+ return SdkSysImgConstants.NS_LATEST_VERSION;
+ }
+
+ @Override
+ protected String getNsUri() {
+ return SdkSysImgConstants.NS_URI;
+ }
+
+ @Override
+ protected String getNsPattern() {
+ return SdkSysImgConstants.NS_PATTERN;
+ }
+
+ @Override
+ protected String getSchemaUri(int version) {
+ return SdkSysImgConstants.getSchemaUri(version);
+ }
+
+ @Override
+ protected String getRootElementName() {
+ return SdkSysImgConstants.NODE_SDK_SYS_IMG;
+ }
+
+ @Override
+ protected InputStream getXsdStream(int version) {
+ return SdkSysImgConstants.getXsdStream(version);
+ }
+
+ /**
+ * This kind of schema does not support forward-evolution of the <tool> element.
+ *
+ * @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/repository/-sdk-addon-5.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd index 6250789..546b00d 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd @@ -70,12 +70,13 @@ </xsd:documentation> </xsd:annotation> <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> + <xsd:element name="add-on" type="sdk:addonType" /> + <xsd:element name="extra" type="sdk:extraType" /> + <xsd:element name="license" type="sdk:licenseType" /> </xsd:choice> </xsd:complexType> + <!-- The definition of an SDK Add-on package. --> <xsd:complexType name="addonType"> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd index ca41b36..ea18070 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd @@ -212,6 +212,7 @@ </xsd:all> </xsd:complexType> + <!-- The definition of the ABI supported by a platform's system image. --> <xsd:simpleType name="abiType"> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java index 53db79f..703cc9d 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java @@ -44,6 +44,14 @@ public class RepoConstants { /** The optional project-files provided by extra packages. */
public static final String NODE_PROJECT_FILES = "project-files"; //$NON-NLS-1$
+ /** A system-image package. */
+ public static final String NODE_SYSTEM_IMAGE = "system-image"; //$NON-NLS-1$
+
+ /* An included-ABI element for a system-image package. */
+ public static final String NODE_ABI_INCLUDED = "included-abi"; //$NON-NLS-1$
+ /* An ABI element for a system-image package. */
+ public static final String NODE_ABI = "abi"; //$NON-NLS-1$
+
/** The optional minimal tools revision required by platform & extra packages. */
public static final String NODE_MIN_TOOLS_REV = "min-tools-rev"; //$NON-NLS-1$
/** The optional minimal platform-tools revision required by tool packages. */
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java index b5b0249..6b4498f 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java @@ -24,13 +24,6 @@ import java.io.InputStream; */
public class SdkAddonsListConstants {
- /** The canonical URL filename for addons-list XML files. */
- public static final String URL_DEFAULT_FILENAME = "addons_list-1.xml"; //$NON-NLS-1$
-
- /** The URL where to find the official addons list fle. */
- public static final String URL_ADDON_LIST =
- SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME;
-
/** The base of our sdk-addons-list XML namespace. */
private static final String NS_BASE =
"http://schemas.android.com/sdk/android/addons-list/"; //$NON-NLS-1$
@@ -43,17 +36,30 @@ public class SdkAddonsListConstants { /** The latest version of the sdk-addons-list XML Schema.
* Valid version numbers are between 1 and this number, included. */
- public static final int NS_LATEST_VERSION = 1;
+ public static final int NS_LATEST_VERSION = 2;
/** The XML namespace of the latest sdk-addons-list XML. */
public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION);
+
+ /** The canonical URL filename for addons-list XML files. */
+ public static final String URL_DEFAULT_FILENAME = getDefaultName(NS_LATEST_VERSION);
+
+ /** The URL where to find the official addons list fle. */
+ public static final String URL_ADDON_LIST =
+ SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME;
+
+
+
/** The root sdk-addons-list element */
public static final String NODE_SDK_ADDONS_LIST = "sdk-addons-list"; //$NON-NLS-1$
/** An add-on site. */
public static final String NODE_ADDON_SITE = "addon-site"; //$NON-NLS-1$
+ /** A system image site. */
+ public static final String NODE_SYS_IMG_SITE = "sys-img-site"; //$NON-NLS-1$
+
/** The UI-visible name of the add-on site. */
public static final String NODE_NAME = "name"; //$NON-NLS-1$
@@ -84,7 +90,7 @@ public class SdkAddonsListConstants { * null if there is no schema for the requested version.
*/
public static InputStream getXsdStream(int version) {
- String filename = String.format("sdk-addons-list-%d.xsd", version); //$NON-NLS-1$
+ String filename = String.format("sdk-addons-list-%d.xsd", version); //$NON-NLS-1$
return SdkAddonsListConstants.class.getResourceAsStream(filename);
}
@@ -95,4 +101,8 @@ public class SdkAddonsListConstants { public static String getSchemaUri(int version) {
return String.format(NS_BASE + "%d", version); //$NON-NLS-1$
}
+
+ public static String getDefaultName(int version) {
+ return String.format("addons_list-%1$d.xml", 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 index 5ad6285..e45da76 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java @@ -107,16 +107,9 @@ public class SdkRepoConstants extends RepoConstants { public static final String NODE_DOC = "doc"; //$NON-NLS-1$
/** A sample package. */
public static final String NODE_SAMPLE = "sample"; //$NON-NLS-1$
- /** A system-image package. */
- public static final String NODE_SYSTEM_IMAGE = "system-image"; //$NON-NLS-1$
/** A source package. */
public static final String NODE_SOURCE = "source"; //$NON-NLS-1$
- /* An included-ABI element for a system-image package. */
- public static final String NODE_ABI_INCLUDED = "included-abi"; //$NON-NLS-1$
- /* An ABI element for a system-image package. */
- public static final String NODE_ABI = "abi"; //$NON-NLS-1$
-
/**
* List of possible nodes in a repository XML. Used to populate options automatically
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java new file mode 100755 index 0000000..cf84d60 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java @@ -0,0 +1,83 @@ +/*
+ * Copyright (C) 2012 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 com.android.sdklib.internal.repository.sources.SdkSource;
+
+import java.io.InputStream;
+
+/**
+ * Public constants for the sdk-sys-img XML Schema.
+ */
+public class SdkSysImgConstants extends RepoConstants {
+
+ /**
+ * The default name looked for by {@link SdkSource} when trying to load an
+ * sdk-sys-img XML if the URL doesn't match an existing resource.
+ */
+ public static final String URL_DEFAULT_FILENAME = "sys-img.xml"; //$NON-NLS-1$
+
+ /** The base of our sdk-sys-img XML namespace. */
+ private static final String NS_BASE =
+ "http://schemas.android.com/sdk/android/sys-img/"; //$NON-NLS-1$
+
+ /**
+ * The pattern of our sdk-sys-img 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-sys-img XML Schema.
+ * Valid version numbers are between 1 and this number, included.
+ */
+ public static final int NS_LATEST_VERSION = 1;
+
+ /** The XML namespace of the latest sdk-sys-img XML. */
+ public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION);
+
+ /** The root sdk-sys-img element */
+ public static final String NODE_SDK_SYS_IMG = "sdk-sys-img"; //$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_SYSTEM_IMAGE,
+ };
+
+ /**
+ * Returns a stream to the requested {@code sdk-sys-img} 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) {
+ return getXsdStream(NODE_SDK_SYS_IMG, version);
+ }
+
+ /**
+ * Returns the URI of the sdk-sys-img 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-addons-list-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd index ac2113c..176fb60 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd @@ -23,7 +23,7 @@ version="1"> <!-- - A simple list of add-ons site that is loaded by default by the SDK Manager. + A simple list of add-ons sites that is loaded by default by the SDK Manager. --> <xsd:element name="sdk-addons-list" type="sa1:addonsListType" /> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd new file mode 100755 index 0000000..dde7214 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Copyright (C) 2012 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. +--> +<xsd:schema + targetNamespace="http://schemas.android.com/sdk/android/addons-list/2" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:sa1="http://schemas.android.com/sdk/android/addons-list/2" + elementFormDefault="qualified" + attributeFormDefault="unqualified" + version="1"> + + <!-- + A simple list of add-ons sites that is loaded by default by the SDK Manager. + + - v1: Defines <addon-site> + - v2: Adds support for <sys-img-site> + --> + + <xsd:element name="sdk-addons-list" type="sa1:addonsListType" /> + + <xsd:complexType name="addonsListType"> + <xsd:annotation> + <xsd:documentation> + A simple list of add-ons site. + </xsd:documentation> + </xsd:annotation> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="addon-site" type="sa1:addonSiteType" /> + <xsd:element name="sys-img-site" type="sa1:sysImgSiteType" /> + </xsd:choice> + </xsd:complexType> + + <!-- The definition of an Add-on Site. --> + + <xsd:complexType name="addonSiteType"> + <xsd:annotation> + <xsd:documentation>An SDK add-on site.</xsd:documentation> + </xsd:annotation> + <xsd:all> + <!-- The URL of the site. + + This can be either the exact URL of the an XML resource conforming + to the latest sdk-addon-N.xsd schema, or it can be the URL of a + 'directory', in which case the manager will look for a resource + named 'addon.xml' at this location. + + Examples: + http://www.example.com/android/my_addons.xml + or + http://www.example.com/android/ + + In the second example, the manager will actually look for: + http://www.example.com/android/addon.xml + --> + <xsd:element name="url" type="xsd:token" /> + + <!-- The UI-visible name of the add-on site. --> + <xsd:element name="name" type="xsd:normalizedString" /> + + </xsd:all> + </xsd:complexType> + + <!-- The definition of an Sys-Img Site. --> + + <xsd:complexType name="sysImgSiteType"> + <xsd:annotation> + <xsd:documentation>An SDK sys-img site.</xsd:documentation> + </xsd:annotation> + <xsd:all> + <!-- The URL of the site. + + This can be either the exact URL of the an XML resource conforming + to the latest sdk-sys-img-N.xsd schema, or it can be the URL of a + 'directory', in which case the manager will look for a resource + named 'sysimg.xml' at this location. + + Examples: + http://www.example.com/android/my_sys_img.xml + or + http://www.example.com/android/ + + In the second example, the manager will actually look for: + http://www.example.com/android/sysimg.xml + --> + <xsd:element name="url" type="xsd:token" /> + + <!-- The UI-visible name of the sys-img site. --> + <xsd:element name="name" type="xsd:normalizedString" /> + + </xsd:all> + </xsd:complexType> + +</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd new file mode 100755 index 0000000..a19aa49 --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Copyright (C) 2012 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. +--> +<xsd:schema + targetNamespace="http://schemas.android.com/sdk/android/sys-img/1" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1" + elementFormDefault="qualified" + attributeFormDefault="unqualified" + version="1"> + + <!-- The repository contains a collection of downloadable items known as + "packages". Each package has a type and various attributes and contains + a list of file "archives" that can be downloaded for specific OSes. + + An Android Addon repository is a web site that contains an "addon.xml" + file that conforms to this XML Schema. + + History: + - v1 is used by the SDK Updater in Tools r20. It is split out of the + main SDK Repository XML Schema and can only contain <system-image> packages. + --> + + <xsd:element name="sdk-sys-img" type="sdk:repositoryType" /> + + <xsd:complexType name="repositoryType"> + <xsd:annotation> + <xsd:documentation> + The repository contains a collection of downloadable system images. + </xsd:documentation> + </xsd:annotation> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="system-image" type="sdk:systemImageType" /> + <xsd:element name="license" type="sdk:licenseType" /> + </xsd:choice> + </xsd:complexType> + + + <!-- The definition of a system image used by a platform. --> + + <xsd:complexType name="systemImageType" > + <xsd:annotation> + <xsd:documentation> + System Image for a platform. + </xsd:documentation> + </xsd:annotation> + <xsd:all> + <!-- api-level+codename identifies the platform to which this system image belongs. --> + + <!-- The Android API Level for the platform. An int > 0. --> + <xsd:element name="api-level" type="xsd:positiveInteger" /> + <!-- The optional codename for this platform, if it's a preview. --> + <xsd:element name="codename" type="xsd:string" minOccurs="0" /> + + <!-- The revision, an int > 0, incremented each time a new + package is generated. --> + <xsd:element name="revision" type="xsd:positiveInteger" /> + + <!-- The ABI of the system emulated by this image. --> + <xsd:element name="abi" type="sdk:abiType" /> + + <!-- The optional license of this package. If present, users will have + to agree to it before downloading. --> + <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> + <!-- The optional description of this package. --> + <xsd:element name="description" type="xsd:string" minOccurs="0" /> + <!-- The optional description URL of this package --> + <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> + <!-- The optional release note for this package. --> + <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> + <!-- The optional release note URL of this package --> + <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> + + <!-- A list of file archives for this package. --> + <xsd:element name="archives" type="sdk:archivesType" /> + + <!-- An optional element indicating the package is obsolete. + The string content is however currently not defined and ignored. --> + <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> + </xsd:all> + </xsd:complexType> + + + <!-- The definition of the ABI supported by a platform's system image. --> + + <xsd:simpleType name="abiType"> + <xsd:annotation> + <xsd:documentation>The ABI of a platform's system image.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:token"> + <xsd:enumeration value="armeabi" /> + <xsd:enumeration value="armeabi-v7a" /> + <xsd:enumeration value="x86" /> + <xsd:enumeration value="mips" /> + </xsd:restriction> + </xsd:simpleType> + + + <!-- The definition of a license to be referenced by the uses-license element. --> + + <xsd:complexType name="licenseType"> + <xsd:annotation> + <xsd:documentation> + A license definition. Such a license must be used later as a reference + using a uses-license element in one of the package elements. + </xsd:documentation> + </xsd:annotation> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="id" type="xsd:ID" /> + <xsd:attribute name="type" type="xsd:token" fixed="text" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + + <!-- Type describing 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. + --> + + <xsd:complexType name="usesLicenseType"> + <xsd:annotation> + <xsd:documentation> + 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. + </xsd:documentation> + </xsd:annotation> + <xsd:attribute name="ref" type="xsd:IDREF" /> + </xsd:complexType> + + + <!-- A collection of files that can be downloaded for a given architecture. + The <archives> node is mandatory in the repository elements 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. + --> + + <xsd:complexType name="archivesType"> + <xsd:annotation> + <xsd:documentation> + 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. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <!-- One archive file --> + <xsd:element name="archive"> + <xsd:complexType> + <!-- Properties of the archive file --> + <xsd:all> + <!-- The size in bytes of the archive to download. --> + <xsd:element name="size" type="xsd:positiveInteger" /> + <!-- The checksum of the archive file. --> + <xsd:element name="checksum" type="sdk:checksumType" /> + <!-- The URL is an absolute URL if it starts with http://, https:// + or ftp://. Otherwise it is relative to the parent directory that + contains this repository.xml --> + <xsd:element name="url" type="xsd:token" /> + </xsd:all> + + <!-- Attributes that identify the OS and architecture --> + <xsd:attribute name="os" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:token"> + <xsd:enumeration value="any" /> + <xsd:enumeration value="linux" /> + <xsd:enumeration value="macosx" /> + <xsd:enumeration value="windows" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="arch" use="optional"> + <xsd:simpleType> + <xsd:restriction base="xsd:token"> + <xsd:enumeration value="any" /> + <xsd:enumeration value="ppc" /> + <xsd:enumeration value="x86" /> + <xsd:enumeration value="x86_64" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + + <!-- The definition of a file checksum --> + + <xsd:simpleType name="sha1Number"> + <xsd:annotation> + <xsd:documentation>A SHA1 checksum.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="([0-9a-fA-F]){40}"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="checksumType"> + <xsd:annotation> + <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> + </xsd:annotation> + <xsd:simpleContent> + <xsd:extension base="sdk:sha1Number"> + <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + +</xsd:schema> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java index 9cf84a2..9c9c149 100755 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java @@ -25,6 +25,7 @@ import java.io.ByteArrayInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Arrays;
import junit.framework.TestCase;
@@ -75,7 +76,7 @@ public class AddonsListFetcherTest extends TestCase { }
/**
- * Validate we can still load a valid addon schema version 1
+ * Validate we can load a valid addon schema version 1
*/
public void testLoadSample_1() throws Exception {
InputStream xmlStream =
@@ -109,21 +110,66 @@ public class AddonsListFetcherTest extends TestCase { assertEquals("", monitor.getCapturedVerboseLog());
// check the sites we found...
+ // The XML file is UTF-8 so we support character sets (but the Java source file is
+ // not, so we use the \\u notation to create the Unicode String)
+ assertEquals(
+ "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " +
+ "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " +
+ "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>]",
+ Arrays.toString(result));
assertEquals(3, result.length);
+ }
+
+ /**
+ * Validate we can load a valid addon schema version 2
+ */
+ public void testLoadSample_2() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/addons_list_sample_2.xml");
+
+ // guess the version from the XML document
+ int version = mFetcher._getXmlSchemaVersion(xmlStream);
+ assertEquals(2, version);
+
+ Boolean[] validatorFound = new Boolean[] { Boolean.FALSE };
+ String[] validationError = new String[] { null };
+ String url = "not-a-valid-url://addons_list.xml";
+
+ String uri = mFetcher._validateXml(
+ xmlStream, url, version, validationError, validatorFound);
+ assertEquals(Boolean.TRUE, validatorFound[0]);
+ assertEquals(null, validationError[0]);
+ assertEquals(SdkAddonsListConstants.getSchemaUri(2), uri);
- assertEquals("My Example Add-ons.", result[0].getUiName());
- assertEquals("http://www.example.com/my_addons.xml", result[0].getUrl());
+ // Validation was successful, load the document
+ MockMonitor monitor = new MockMonitor();
+ Document doc = mFetcher._getDocument(xmlStream, monitor);
+ assertNotNull(doc);
+
+ // Get the sites
+ Site[] result = mFetcher._parseAddonsList(doc, uri, monitor);
+ assertEquals("", monitor.getCapturedDescriptions());
+ assertEquals("", monitor.getCapturedLog());
+ assertEquals("", monitor.getCapturedErrorLog());
+ assertEquals("", monitor.getCapturedVerboseLog());
+
+ // check the sites we found...
// The XML file is UTF-8 so we support character sets (but the Java source file is
// not, so we use the \\u notation to create the Unicode String)
- assertEquals("\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002",
- result[1].getUiName());
- assertEquals("http://www.example.co.jp/addons.xml", result[1].getUrl());
-
- assertEquals("Example of directory URL.", result[2].getUiName());
- assertEquals("http://www.example.com/", result[2].getUrl());
+ assertEquals(
+ "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " +
+ "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " +
+ "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>, " +
+ "<SYS_IMG_SITE URL='http://www.example.com/' Name='Example of sys-img URL using the default xml filename.'>, " +
+ "<SYS_IMG_SITE URL='http://www.example.com/specific_file.xml' Name='Example of sys-img URL using a specific xml filename.'>]",
+ Arrays.toString(result));
+ assertEquals(5, result.length);
}
+ // IMPORTANT: Each time you add a test here for a new version, you should
+ // also add a test in ValidateAddonsListXmlTest.
+
/**
* Returns an SdkLib file resource as a {@link ByteArrayInputStream},
* which has the advantage that we can use {@link InputStream#reset()} on it
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java index d866018..e7950dd 100755 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java @@ -41,7 +41,7 @@ import java.util.Arrays; import junit.framework.TestCase;
/**
- * Tests for {@link SdkAddonSource}
+ * Tests for {@link SdkAddonSource}.
*/
public class SdkAddonSourceTest extends TestCase {
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java new file mode 100755 index 0000000..96c3d40 --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java @@ -0,0 +1,211 @@ +/*
+ * Copyright (C) 2012 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.sources;
+
+import com.android.sdklib.internal.repository.ITaskMonitor;
+import com.android.sdklib.internal.repository.MockMonitor;
+import com.android.sdklib.internal.repository.packages.Package;
+import com.android.sdklib.internal.repository.packages.SystemImagePackage;
+import com.android.sdklib.repository.SdkSysImgConstants;
+
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SdkSysImgSource}.
+ */
+public class SdkSysImgSourceTest extends TestCase {
+
+ /**
+ * An internal helper class to give us visibility to the protected members we want
+ * to test.
+ */
+ private static class MockSdkSysImgSource extends SdkSysImgSource {
+ public MockSdkSysImgSource() {
+ super("fake-url", null /*uiName*/);
+ }
+
+ public Document _findAlternateToolsXml(InputStream xml) {
+ 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 MockSdkSysImgSource mSource;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mSource = new MockSdkSysImgSource();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ mSource = null;
+ }
+
+ /**
+ * Validate that findAlternateToolsXml doesn't work for this source even
+ * when trying to load a valid xml. That's because finding alternate tools
+ * is not supported by this kind of source.
+ */
+ public void testFindAlternateToolsXml_1() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/sys_img_sample_1.xml");
+
+ Document result = mSource._findAlternateToolsXml(xmlStream);
+ assertNull(result);
+ }
+
+ /**
+ * Validate we can load a valid schema version 1
+ */
+ public void testLoadSysImgXml_1() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/sys_img_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://" + SdkSysImgConstants.URL_DEFAULT_FILENAME;
+
+ String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound);
+ assertEquals(Boolean.TRUE, validatorFound[0]);
+ assertEquals(null, validationError[0]);
+ assertEquals(SdkSysImgConstants.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 Intel x86 Atom System Image, Android API 2, revision 1\n" +
+ "Found ARM EABI v7a System Image, Android API 2, revision 2\n" +
+ "Found ARM EABI System Image, Android API 42, revision 12\n" +
+ "Found Mips System Image, Android API 42, revision 12\n",
+ monitor.getCapturedVerboseLog());
+ assertEquals("", monitor.getCapturedLog());
+ assertEquals("", monitor.getCapturedErrorLog());
+
+ // check the packages we found...
+ // Note the order doesn't necessary match the one from the
+ // assertEquald(getCapturedVerboseLog) because packages are sorted using the
+ // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc.
+
+ Package[] pkgs = mSource.getPackages();
+
+ assertEquals(4, pkgs.length);
+ for (Package p : pkgs) {
+ // We expected to find packages with each at least one archive.
+ assertTrue(p.getArchives().length >= 1);
+ // And only system images are supported by this source
+ assertTrue(p instanceof SystemImagePackage);
+ }
+
+ // Check the system-image packages
+ ArrayList<String> sysImgVersionAbi = new ArrayList<String>();
+ for (Package p : pkgs) {
+ if (p instanceof SystemImagePackage) {
+ SystemImagePackage sip = (SystemImagePackage) p;
+ String v = sip.getAndroidVersion().getApiString();
+ String a = sip.getAbi();
+ sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$
+ }
+ }
+ assertEquals(
+ "[42 armeabi, " +
+ "42 mips, " +
+ "2 armeabi-v7a, " +
+ "2 x86]",
+ Arrays.toString(sysImgVersionAbi.toArray()));
+
+ }
+
+
+ //-----
+
+ /**
+ * 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.
+ * <p/>
+ * 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/src/com/android/sdklib/repository/ValidateAddonXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java index d88d566..40ff727 100755 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java @@ -49,7 +49,7 @@ public class ValidateAddonXmlTest extends TestCase { /**
* Helper method that returns a validator for our Addon XSD
*
- * @param version The versoion number, in range {@code 1..NS_LATEST_VERSION}
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
* @param handler A {@link CaptureErrorHandler}. If null the default will be used,
* which will most likely print errors to stderr.
*/
@@ -80,7 +80,7 @@ public class ValidateAddonXmlTest extends TestCase { // --- Tests ------------
- /** Validates that NS_LATEST_VERSION points to the max avaialble XSD schema. */
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
public void testAddonLatestVersionNumber() throws Exception {
CaptureErrorHandler handler = new CaptureErrorHandler();
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java new file mode 100755 index 0000000..2f68e41 --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java @@ -0,0 +1,108 @@ +/*
+ * Copyright (C) 2012 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 com.android.annotations.Nullable;
+
+import org.xml.sax.SAXException;
+
+import java.io.InputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests local validation of an SDK Addon-List sample XMLs using an XML Schema validator.
+ */
+public class ValidateAddonsListXmlTest extends TestCase {
+
+ // --- Helpers ------------
+
+ /**
+ * Helper method that returns a validator for our Addons-List XSD
+ *
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
+ * @param handler A {@link CaptureErrorHandler}. If null the default will be used,
+ * which will most likely print errors to stderr.
+ */
+ private Validator getValidator(int version, @Nullable CaptureErrorHandler handler)
+ throws SAXException {
+ Validator validator = null;
+ InputStream xsdStream = SdkAddonsListConstants.getXsdStream(version);
+ if (xsdStream != null) {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));
+ validator = schema.newValidator();
+ if (handler != null) {
+ validator.setErrorHandler(handler);
+ }
+ }
+
+ return validator;
+ }
+
+ // --- Tests ------------
+
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
+ public void testAddonLatestVersionNumber() throws Exception {
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+
+ // There should be a schema matching NS_LATEST_VERSION
+ assertNotNull(getValidator(SdkAddonsListConstants.NS_LATEST_VERSION, handler));
+
+ // There should NOT be a schema with NS_LATEST_VERSION+1
+ assertNull(
+ String.format(
+ "There's an ADDON XSD at version %d but SdkAddonsListConstants.NS_LATEST_VERSION is still set to %d.",
+ SdkAddonsListConstants.NS_LATEST_VERSION + 1,
+ SdkAddonsListConstants.NS_LATEST_VERSION),
+ getValidator(SdkAddonsListConstants.NS_LATEST_VERSION + 1, handler));
+ }
+
+ /** Validate a valid sample using namespace version 1 using an InputStream */
+ public void testValidateLocalAddonFile1() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/addons_list_sample_1.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(1, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ /** Validate a valid sample using namespace version 2 using an InputStream */
+ public void testValidateLocalAddonFile2() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/addons_list_sample_2.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(2, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ // IMPORTANT: each time you add a test here, you should add a corresponding
+ // test in AddonsListFetcherTest to validate the XML content is parsed correctly.
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java index 648ff05..c5ceb3e 100755 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java @@ -52,7 +52,7 @@ public class ValidateRepositoryXmlTest extends TestCase { /**
* Helper method that returns a validator for our Repository XSD
*
- * @param version The versoion number, in range {@code 1..NS_LATEST_VERSION}
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
* @param handler A {@link CaptureErrorHandler}. If null the default will be used,
* which will most likely print errors to stderr.
*/
@@ -84,7 +84,7 @@ public class ValidateRepositoryXmlTest extends TestCase { // --- Tests ------------
- /** Validates that NS_LATEST_VERSION points to the max avaialble XSD schema. */
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
public void testRepoLatestVersionNumber() throws Exception {
CaptureErrorHandler handler = new CaptureErrorHandler();
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java new file mode 100755 index 0000000..6933634 --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java @@ -0,0 +1,101 @@ +/*
+ * Copyright (C) 2012 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 com.android.annotations.Nullable;
+
+import org.xml.sax.SAXException;
+
+import java.io.InputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests local validation of an SDK Repository sample XMLs using an XML Schema validator.
+ *
+ * References:
+ * http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html
+ */
+public class ValidateSysImgXmlTest extends TestCase {
+
+ // --- Helpers ------------
+
+ /**
+ * Helper method that returns a validator for our Repository XSD
+ *
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
+ * @param handler A {@link CaptureErrorHandler}. If null the default will be used,
+ * which will most likely print errors to stderr.
+ */
+ private Validator getValidator(int version, @Nullable CaptureErrorHandler handler)
+ throws SAXException {
+ Validator validator = null;
+ InputStream xsdStream = SdkSysImgConstants.getXsdStream(version);
+ if (xsdStream != null) {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));
+ validator = schema.newValidator();
+
+ if (handler != null) {
+ validator.setErrorHandler(handler);
+ }
+ }
+
+ return validator;
+ }
+
+ // --- Tests ------------
+
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
+ public void testSysImgLatestVersionNumber() throws Exception {
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+
+ // There should be a schema matching NS_LATEST_VERSION
+ assertNotNull(getValidator(SdkSysImgConstants.NS_LATEST_VERSION, handler));
+
+ // There should NOT be a schema with NS_LATEST_VERSION+1
+ assertNull(
+ String.format(
+ "There's a REPO XSD at version %d but SdkSysImgConstants.NS_LATEST_VERSION is still set to %d.",
+ SdkSysImgConstants.NS_LATEST_VERSION + 1,
+ SdkSysImgConstants.NS_LATEST_VERSION),
+ getValidator(SdkSysImgConstants.NS_LATEST_VERSION + 1, handler));
+ }
+
+ /** Validate a valid sample using namespace version 1 using an InputStream */
+ public void testValidateLocalRepositoryFile1() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/sys_img_sample_1.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(1, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ // IMPORTANT: each time you add a test here, you should add a corresponding
+ // test in SdkSysImgSourceTest to validate the XML content is parsed correctly.
+
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml new file mode 100755 index 0000000..4e4907c --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Copyright (C) 2012 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. +--> +<sdk:sdk-addons-list + xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/2"> + + <sdk:addon-site> + <sdk:url>http://www.example.com/my_addons.xml</sdk:url> + <sdk:name> <!-- we'll ignore leading/trailing spacing --> + My Example Add-ons. + </sdk:name> + </sdk:addon-site> + + <sdk:addon-site> + <sdk:url>http://www.example.co.jp/addons.xml</sdk:url> + <!-- this file is UTF-8 so we support character sets --> + <sdk:name>ありがとうございます。</sdk:name> + </sdk:addon-site> + + <sdk:addon-site> + <sdk:url>http://www.example.com/</sdk:url> + <sdk:name>Example of directory URL.</sdk:name> + </sdk:addon-site> + + <sdk:sys-img-site> + <sdk:url>http://www.example.com/</sdk:url> + <sdk:name>Example of sys-img URL using the default xml filename.</sdk:name> + </sdk:sys-img-site> + + <sdk:sys-img-site> + <sdk:url>http://www.example.com/specific_file.xml</sdk:url> + <sdk:name>Example of sys-img URL using a specific xml filename.</sdk:name> + </sdk:sys-img-site> + +</sdk:sdk-addons-list> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml new file mode 100755 index 0000000..6196db4 --- /dev/null +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<!-- + * Copyright (C) 2012 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. +--> +<sdk:sdk-sys-img + xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1"> + + <!-- Define a couple of licenses. These will be referenced by uses-license later. --> + + <sdk:license type="text" id="license1"> + This is the license + for this platform. + </sdk:license> + + <sdk:license id="license2"> + Licenses are only of type 'text' right now, so this is implied. + </sdk:license> + + <sdk:system-image> + <sdk:api-level>2</sdk:api-level> + <sdk:revision>1</sdk:revision> + <sdk:abi>x86</sdk:abi> + <sdk:archives> + <sdk:archive os="any"> + <sdk:size>65535</sdk:size> + <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> + <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url> + </sdk:archive> + </sdk:archives> + </sdk:system-image> + + <sdk:system-image> + <sdk:api-level>2</sdk:api-level> + <sdk:revision>2</sdk:revision> + <sdk:abi>armeabi-v7a</sdk:abi> + <sdk:archives> + <sdk:archive os="any"> + <sdk:size>65534</sdk:size> + <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> + <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url> + </sdk:archive> + </sdk:archives> + </sdk:system-image> + + <sdk:system-image> + <sdk:api-level>42</sdk:api-level> + <sdk:revision>12</sdk:revision> + <sdk:abi>armeabi</sdk:abi> + <sdk:archives> + <sdk:archive os="any"> + <sdk:size>1234</sdk:size> + <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> + <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url> + </sdk:archive> + </sdk:archives> + </sdk:system-image> + + <sdk:system-image> + <sdk:api-level>42</sdk:api-level> + <sdk:revision>12</sdk:revision> + <sdk:abi>mips</sdk:abi> + <sdk:archives> + <sdk:archive os="any"> + <sdk:size>12345</sdk:size> + <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> + <sdk:url>http://www.example.com/plat42/mips/image12.zip</sdk:url> + </sdk:archive> + </sdk:archives> + </sdk:system-image> + +</sdk:sdk-sys-img> diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java index 10b02c6..d1078d0 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java @@ -382,9 +382,7 @@ public class AddonSitesDialog extends UpdaterBaseDialog { // create the source, store it and update the list SdkAddonSource newSource = new SdkAddonSource(url, null/*uiName*/); - mSources.add( - SdkSourceCategory.USER_ADDONS, - newSource); + mSources.add(SdkSourceCategory.USER_ADDONS, newSource); setReturnValue(true); // notify sources change listeners. This will invoke our own loadUserUrlsList(). mSources.notifyChangeListeners(); diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java index 4ad78b8..983c94d 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java @@ -29,6 +29,7 @@ import com.android.sdklib.internal.repository.sources.SdkAddonSource; import com.android.sdklib.internal.repository.sources.SdkSource; import com.android.sdklib.internal.repository.sources.SdkSourceCategory; import com.android.sdklib.internal.repository.sources.SdkSources; +import com.android.sdklib.internal.repository.sources.SdkSysImgSource; import com.android.sdklib.repository.SdkAddonsListConstants; import com.android.sdklib.repository.SdkRepoConstants; import com.android.sdkuilib.internal.repository.UpdaterData; @@ -448,8 +449,16 @@ public class PackageLoader { if (fetch3rdParties) { for (Site s : sites) { - sources.add(SdkSourceCategory.ADDONS_3RD_PARTY, - new SdkAddonSource(s.getUrl(), s.getUiName())); + switch (s.getType()) { + case ADDON_SITE: + sources.add(SdkSourceCategory.ADDONS_3RD_PARTY, + new SdkAddonSource(s.getUrl(), s.getUiName())); + break; + case SYS_IMG_SITE: + sources.add(SdkSourceCategory.ADDONS_3RD_PARTY, + new SdkSysImgSource(s.getUrl(), s.getUiName())); + break; + } } } |