Merge change 2384 into donut

* changes:
  SDK Updater: display properties of sources and packages.
This commit is contained in:
Android (Google) Code Review
2009-05-22 17:20:35 -07:00
9 changed files with 458 additions and 116 deletions

View File

@@ -20,35 +20,110 @@ import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import java.util.ArrayList;
/** /**
* * Represents an add-on XML node in an SDK repository.
*/ */
public class AddonPackage extends Package { public class AddonPackage extends Package {
private final String mVendor; private final String mVendor;
private final String mName; private final String mName;
private final String mApiLevel; private final int mApiLevel;
public AddonPackage(Node packageNode) { /** An add-on library. */
super(packageNode); public static class Lib {
mVendor = getXmlString(packageNode, SdkRepository.NODE_VENDOR); private final String mName;
mName = getXmlString(packageNode, SdkRepository.NODE_NAME); private final String mDescription;
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL);
// TODO libs public Lib(String name, String description) {
} mName = name;
mDescription = description;
public String getVendor() {
return mVendor;
} }
public String getName() { public String getName() {
return mName; return mName;
} }
public String getApiLevel() { public String getDescription() {
return mDescription;
}
}
private final Lib[] mLibs;
/**
* Creates a new add-on package from the attributes and elements of the given XML node.
* <p/>
* This constructor should throw an exception if the package cannot be created.
*/
AddonPackage(Node packageNode) {
super(packageNode);
mVendor = getXmlString(packageNode, SdkRepository.NODE_VENDOR);
mName = getXmlString(packageNode, SdkRepository.NODE_NAME);
mApiLevel = getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0);
mLibs = parseLibs(getFirstChild(packageNode, SdkRepository.NODE_LIBS));
}
private Lib[] parseLibs(Node libsNode) {
ArrayList<Lib> libs = new ArrayList<Lib>();
if (libsNode != null) {
for(Node child = libsNode.getFirstChild();
child != null;
child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE &&
SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI()) &&
SdkRepository.NODE_LIB.equals(child.getLocalName())) {
libs.add(parseLib(child));
}
}
}
return libs.toArray(new Lib[libs.size()]);
}
private Lib parseLib(Node libNode) {
return new Lib(getXmlString(libNode, SdkRepository.NODE_NAME),
getXmlString(libNode, SdkRepository.NODE_DESCRIPTION));
}
/** Returns the vendor, a string, for add-on packages. */
public String getVendor() {
return mVendor;
}
/** Returns the name, a string, for add-on packages or for libraries. */
public String getName() {
return mName;
}
/** Returns the api-level, an int > 0, for platform, add-on and doc packages. */
public int getApiLevel() {
return mApiLevel; return mApiLevel;
} }
/** Returns the libs defined in this add-on. Can be an empty array but not null. */
public Lib[] getLibs() {
return mLibs;
}
/** Returns a short description for an {@link IDescription}. */
@Override
public String getShortDescription() {
return String.format("%1$s by %2$s for Android API %3$d",
getName(),
getVendor(),
getApiLevel());
}
/** Returns a long description for an {@link IDescription}. */
@Override
public String getLongDescription() {
return String.format("%1$s.\n%2$s",
getShortDescription(),
super.getLongDescription());
}
} }

View File

@@ -0,0 +1,131 @@
/*
* 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;
/**
* A {@link Archive} is the base class for "something" that can be downloaded from
* the SDK repository -- subclasses include {@link PlatformPackage}, {@link AddonPackage},
* {@link DocPackage} and {@link ToolPackage}.
* <p/>
* A package has some attributes (revision, description) and a list of archives
* which represent the downloadable bits.
* <p/>
* Packages are contained in offered by a {@link RepoSource} (a download site).
*/
public class Archive implements IDescription {
/** The checksum type. */
public enum ChecksumType {
/** A SHA1 checksum, represented as a 40-hex string. */
SHA1
}
/** The OS that this archive can be downloaded on. */
public enum Os {
ANY,
LINUX,
MACOSX,
WINDOWS
}
/** The Architecture that this archvie can be downloaded on. */
public enum Arch {
ANY,
PPC,
X86,
X86_64
}
private final Os mOs;
private final Arch mArch;
private final String mUrl;
private final long mSize;
private final String mChecksum;
private final ChecksumType mChecksumType = ChecksumType.SHA1;
/**
* Creates a new archive.
*/
Archive(Os os, Arch arch, String url, long size, String checksum) {
mOs = os;
mArch = arch;
mUrl = url;
mSize = size;
mChecksum = checksum;
}
/** Returns the archive size, an int > 0. */
public long getSize() {
return mSize;
}
/** Returns the SHA1 archive checksum, as a 40-char hex. */
public String getChecksum() {
return mChecksum;
}
/** Returns the checksum type, always {@link ChecksumType#SHA1} right now. */
public ChecksumType getChecksumType() {
return mChecksumType;
}
/** Returns the optional description URL for all packages (platform, add-on, tool, doc).
* Can be empty but not null. */
public String getDescUrl() {
return mUrl;
}
/** Returns the archive {@link Os} enum. */
public Os getOs() {
return mOs;
}
/** Returns the archive {@link Arch} enum. */
public Arch getArch() {
return mArch;
}
public String getShortDescription() {
String os = "any OS";
if (mOs != Os.ANY) {
os = capitalize(mOs.toString());
}
String arch = "";
if (mArch != Arch.ANY) {
arch = mArch.toString().toLowerCase();
}
return String.format("Archive for %1$s %2$s", os, arch);
}
private String capitalize(String string) {
if (string.length() > 1) {
return string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase();
} else {
return string.toUpperCase();
}
}
public String getLongDescription() {
return String.format("%1$s\nSize: %2$d MiB\nSHA1: %3$s",
getShortDescription(),
Math.round(getSize() / (1024*1024)),
getChecksum());
}
}

View File

@@ -16,14 +16,43 @@
package com.android.sdklib.internal.repository; package com.android.sdklib.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node; import org.w3c.dom.Node;
/** /**
* * Represents a doc XML node in an SDK repository.
*/ */
public class DocPackage extends Package { public class DocPackage extends Package {
public DocPackage(Node packageNode) { private final int mApiLevel;
/**
* Creates a new doc package from the attributes and elements of the given XML node.
* <p/>
* This constructor should throw an exception if the package cannot be created.
*/
DocPackage(Node packageNode) {
super(packageNode); super(packageNode);
mApiLevel = getXmlInt(packageNode, SdkRepository.NODE_API_LEVEL, 0);
}
/** Returns the api-level, an int > 0, for platform, add-on and doc packages. */
public int getApiLevel() {
return mApiLevel;
}
/** Returns a short description for an {@link IDescription}. */
@Override
public String getShortDescription() {
return String.format("Documentation for SDK Android API %1$d", getApiLevel());
}
/** Returns a long description for an {@link IDescription}. */
@Override
public String getLongDescription() {
return String.format("%1$s.\n%2$s",
getShortDescription(),
super.getLongDescription());
} }
} }

View File

@@ -16,64 +16,133 @@
package com.android.sdklib.internal.repository; 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.SdkRepository;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import java.util.ArrayList;
/** /**
* * A {@link Package} is the base class for "something" that can be downloaded from
* the SDK repository -- subclasses include {@link PlatformPackage}, {@link AddonPackage},
* {@link DocPackage} and {@link ToolPackage}.
* <p/>
* A package has some attributes (revision, description) and a list of archives
* which represent the downloadable bits.
* <p/>
* Packages are contained by a {@link RepoSource} (a download site).
* <p/>
* Derived classes must implement the {@link IDescription} methods.
*/ */
public class Package { public abstract class Package implements IDescription {
private final int mRevision; private final int mRevision;
private final String mDescription; private final String mDescription;
private final String mDescUrl; private final String mDescUrl;
private final Archive[] mArchives;
private Package(int revision, String description, String descUrl) { /**
mRevision = revision; * Creates a new package from the attributes and elements of the given XML node.
mDescription = description; * <p/>
mDescUrl = descUrl; * This constructor should throw an exception if the package cannot be created.
*/
Package(Node packageNode) {
mRevision = getXmlInt (packageNode, SdkRepository.NODE_REVISION, 0);
mDescription = getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION);
mDescUrl = getXmlString(packageNode, SdkRepository.NODE_DESC_URL);
mArchives = parseArchives(getFirstChild(packageNode, SdkRepository.NODE_ARCHIVES));
} }
public Package(Node packageNode) { private Archive[] parseArchives(Node archivesNode) {
this(getXmlInt (packageNode, SdkRepository.NODE_REVISION, 0), ArrayList<Archive> archives = new ArrayList<Archive>();
getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION),
getXmlString(packageNode, SdkRepository.NODE_DESC_URL));
// TODO archives if (archivesNode != null) {
for(Node child = archivesNode.getFirstChild();
child != null;
child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE &&
SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI()) &&
SdkRepository.NODE_ARCHIVE.equals(child.getLocalName())) {
archives.add(parseArchive(child));
}
}
} }
/** The revision, an int > 0, for all packages (platform, add-on, tool, doc). */ return archives.toArray(new Archive[archives.size()]);
}
private Archive parseArchive(Node archiveNode) {
Archive a = new Archive(
(Os) getEnumAttribute(archiveNode, SdkRepository.ATTR_OS,
Os.values(), null),
(Arch) getEnumAttribute(archiveNode, SdkRepository.ATTR_ARCH,
Arch.values(), Arch.ANY),
getXmlString(archiveNode, SdkRepository.NODE_URL),
getXmlInt(archiveNode, SdkRepository.NODE_SIZE, 0),
getXmlString(archiveNode, SdkRepository.NODE_CHECKSUM)
);
return a;
}
/** Returns the revision, an int > 0, for all packages (platform, add-on, tool, doc). */
public int getRevision() { public int getRevision() {
return mRevision; return mRevision;
} }
/** The optional description for all packages (platform, add-on, tool, doc) or for a lib. */ /** Returns the optional description for all packages (platform, add-on, tool, doc) or
* for a lib. */
public String getDescription() { public String getDescription() {
return mDescription; return mDescription;
} }
/** The optional description URL for all packages (platform, add-on, tool, doc). /** Returns the optional description URL for all packages (platform, add-on, tool, doc).
* Can be empty but not null. */ * Can be empty but not null. */
public String getDescUrl() { public String getDescUrl() {
return mDescUrl; return mDescUrl;
} }
/** Returns the archives defined in this package. Can be an empty array but not null. */
public Archive[] getArchives() {
return mArchives;
}
/** Returns a short description for an {@link IDescription}. */
public abstract String getShortDescription();
/** Returns a long description for an {@link IDescription}. */
public String getLongDescription() {
return String.format("%1$s\nRevision %2$d", getDescription(), getRevision());
}
//---
protected static Node getFirstChild(Node node, String xmlLocalName) {
for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE &&
SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI())) {
if (xmlLocalName == null || xmlLocalName.equals(child.getLocalName())) {
return child;
}
}
}
return null;
}
/** /**
* Retrieves the value of that XML element as a string. * Retrieves the value of that XML element as a string.
* Returns an empty string when the element is missing. * Returns an empty string when the element is missing.
*/ */
protected static String getXmlString(Node node, String xmlLocalName) { protected static String getXmlString(Node node, String xmlLocalName) {
for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { Node child = getFirstChild(node, xmlLocalName);
if (child.getNodeType() == Node.ELEMENT_NODE &&
child.getNamespaceURI().equals(SdkRepository.NS_SDK_REPOSITORY)) {
if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) {
return child.getTextContent();
}
}
}
return ""; return child == null ? "" : child.getTextContent(); //$NON-NLS-1$
} }
/** /**
@@ -89,4 +158,29 @@ public class Package {
} }
} }
/**
* Retrieve an attribute which value must match one of the given enums using a
* case-insensitive name match.
*
* Returns defaultValue if the attribute does not exist or its value does not match
* the given enum values.
*/
private Object getEnumAttribute(
Node archiveNode,
String attrName,
Object[] values,
Object defaultValue) {
Node attr = archiveNode.getAttributes().getNamedItem(attrName);
if (attr != null) {
String found = attr.getNodeValue();
for (Object value : values) {
if (value.toString().equalsIgnoreCase(found)) {
return value;
}
}
}
return defaultValue;
}
} }

View File

@@ -21,26 +21,47 @@ import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node; import org.w3c.dom.Node;
/** /**
* * Represents a platform XML node in an SDK repository.
*/ */
public class PlatformPackage extends Package { public class PlatformPackage extends Package {
private final String mVersion; private final String mVersion;
private final String mApiLevel; private final int mApiLevel;
public PlatformPackage(Node packageNode) { /**
* Creates a new platform package from the attributes and elements of the given XML node.
* <p/>
* This constructor should throw an exception if the package cannot be created.
*/
PlatformPackage(Node packageNode) {
super(packageNode); super(packageNode);
mVersion = getXmlString(packageNode, SdkRepository.NODE_VERSION); mVersion = getXmlString(packageNode, SdkRepository.NODE_VERSION);
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL); mApiLevel = getXmlInt (packageNode, SdkRepository.NODE_API_LEVEL, 0);
} }
/** Returns the version, a string, for platform packages. */
public String getVersion() { public String getVersion() {
return mVersion; return mVersion;
} }
public String getApiLevel() { /** Returns the api-level, an int > 0, for platform, add-on and doc packages. */
public int getApiLevel() {
return mApiLevel; return mApiLevel;
} }
/** Returns a short description for an {@link IDescription}. */
@Override
public String getShortDescription() {
return String.format("SDK Platform Android %1$s, API %2$d",
getVersion(),
getApiLevel());
}
/** Returns a long description for an {@link IDescription}. */
@Override
public String getLongDescription() {
return String.format("%1$s.\n%2$s",
getShortDescription(),
super.getLongDescription());
}
} }

View File

@@ -41,14 +41,16 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
/** /**
* An sdk-repository source. It may be a full repository or an add-on only repository. * An 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 class RepoSource implements IDescription {
private final String mUrl; private final String mUrl;
private final boolean mAddonOnly; private final boolean mAddonOnly;
private ArrayList<String> mPackages; private Package[] mPackages;
private String mDescription; private String mDescription;
/** /**
@@ -68,7 +70,7 @@ public class RepoSource implements IDescription {
/** /**
* Returns the list of known packages. This is null when the source hasn't been loaded yet. * Returns the list of known packages. This is null when the source hasn't been loaded yet.
*/ */
public ArrayList<String> getPackages() { public Package[] getPackages() {
return mPackages; return mPackages;
} }
@@ -112,12 +114,12 @@ public class RepoSource implements IDescription {
monitor.setDescription("Parse XML"); monitor.setDescription("Parse XML");
monitor.incProgress(1); monitor.incProgress(1);
parsePackages(xml, monitor); parsePackages(xml, monitor);
if (mPackages.size() == 0) { if (mPackages.length == 0) {
mDescription += "\nNo packages found."; mDescription += "\nNo packages found.";
} else if (mPackages.size() == 1) { } else if (mPackages.length == 1) {
mDescription += "\nOne package found."; mDescription += "\nOne package found.";
} else { } else {
mDescription += String.format("\n%1$d packages found.", mPackages.size()); mDescription += String.format("\n%1$d packages found.", mPackages.length);
} }
// done // done
@@ -223,31 +225,42 @@ public class RepoSource implements IDescription {
Node root = getFirstChild(doc, SdkRepository.NODE_SDK_REPOSITORY); Node root = getFirstChild(doc, SdkRepository.NODE_SDK_REPOSITORY);
if (root != null) { if (root != null) {
mPackages = new ArrayList<String>(); ArrayList<Package> packages = new ArrayList<Package>();
for (Node child = root.getFirstChild(); for (Node child = root.getFirstChild();
child != null; child != null;
child = child.getNextSibling()) { child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE && if (child.getNodeType() == Node.ELEMENT_NODE &&
child.getNamespaceURI().equals(SdkRepository.NS_SDK_REPOSITORY)) { SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI())) {
String name = child.getLocalName(); String name = child.getLocalName();
Package p = null;
try {
if (SdkRepository.NODE_ADD_ON.equals(name)) { if (SdkRepository.NODE_ADD_ON.equals(name)) {
parseAddon(child, mPackages, monitor); p = new AddonPackage(child);
} else if (!mAddonOnly) { } else if (!mAddonOnly) {
if (SdkRepository.NODE_PLATFORM.equals(name)) { if (SdkRepository.NODE_PLATFORM.equals(name)) {
parsePlatform(child, mPackages, monitor); p = new PlatformPackage(child);
} else if (SdkRepository.NODE_DOC.equals(name)) { } else if (SdkRepository.NODE_DOC.equals(name)) {
parseDoc(child, mPackages, monitor); p = new DocPackage(child);
} else if (SdkRepository.NODE_TOOL.equals(name)) { } else if (SdkRepository.NODE_TOOL.equals(name)) {
parseTool(child, mPackages, monitor); p = new ToolPackage(child);
}
}
if (p != null) {
packages.add(p);
monitor.setDescription(
String.format("Found %1$s", p.getShortDescription()));
}
} catch (Exception e) {
// Ignore invalid packages
} }
} }
} }
}
mPackages = packages.toArray(new Package[packages.size()]);
return true; return true;
} }
@@ -269,7 +282,7 @@ public class RepoSource implements IDescription {
for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE && if (child.getNodeType() == Node.ELEMENT_NODE &&
child.getNamespaceURI().equals(SdkRepository.NS_SDK_REPOSITORY)) { SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI())) {
if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) { if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) {
return child; return child;
} }
@@ -290,42 +303,4 @@ public class RepoSource implements IDescription {
return doc; return doc;
} }
private void parseAddon(Node addon, ArrayList<String> packages, ITaskMonitor monitor) {
// TODO Auto-generated method stub
String s = String.format("addon %1$s by %2$s, api %3$s, rev %4$s",
getFirstChild(addon, SdkRepository.NODE_NAME).getTextContent(),
getFirstChild(addon, SdkRepository.NODE_VENDOR).getTextContent(),
getFirstChild(addon, SdkRepository.NODE_API_LEVEL).getTextContent(),
getFirstChild(addon, SdkRepository.NODE_REVISION).getTextContent()
);
packages.add(s);
}
private void parsePlatform(Node platform, ArrayList<String> packages, ITaskMonitor monitor) {
// TODO Auto-generated method stub
String s = String.format("platform %1$s, api %2$s, rev %3$s",
getFirstChild(platform, SdkRepository.NODE_VERSION).getTextContent(),
getFirstChild(platform, SdkRepository.NODE_API_LEVEL).getTextContent(),
getFirstChild(platform, SdkRepository.NODE_REVISION).getTextContent()
);
packages.add(s);
}
private void parseDoc(Node doc, ArrayList<String> packages, ITaskMonitor monitor) {
// TODO Auto-generated method stub
String s = String.format("doc for api %1$s, rev %2$s",
getFirstChild(doc, SdkRepository.NODE_API_LEVEL).getTextContent(),
getFirstChild(doc, SdkRepository.NODE_REVISION).getTextContent()
);
packages.add(s);
}
private void parseTool(Node tool, ArrayList<String> packages, ITaskMonitor monitor) {
// TODO Auto-generated method stub
String s = String.format("tool, rev %1$s",
getFirstChild(tool, SdkRepository.NODE_REVISION).getTextContent()
);
packages.add(s);
}
} }

View File

@@ -16,25 +16,33 @@
package com.android.sdklib.internal.repository; package com.android.sdklib.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node; import org.w3c.dom.Node;
/** /**
* * Represents a tool XML node in an SDK repository.
*/ */
public class ToolPackage extends Package { public class ToolPackage extends Package {
private final String mApiLevel; /**
* Creates a new tool package from the attributes and elements of the given XML node.
public ToolPackage(Node packageNode) { * <p/>
* This constructor should throw an exception if the package cannot be created.
*/
ToolPackage(Node packageNode) {
super(packageNode); super(packageNode);
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL);
} }
public String getApiLevel() { /** Returns a short description for an {@link IDescription}. */
return mApiLevel; @Override
public String getShortDescription() {
return String.format("Android SDK Tools, revision %1$d", getRevision());
} }
/** Returns a long description for an {@link IDescription}. */
@Override
public String getLongDescription() {
return String.format("Android SDK Tools, revision %1$d.\n%2$s",
getRevision(),
super.getLongDescription());
}
} }

View File

@@ -61,9 +61,9 @@ public class SdkRepository {
public static final String NODE_LIB = "lib"; //$NON-NLS-1$ public static final String NODE_LIB = "lib"; //$NON-NLS-1$
/** The archives container, for all packages. */ /** The archives container, for all packages. */
public static final String NODE_ARCHVIES = "archives"; //$NON-NLS-1$ public static final String NODE_ARCHIVES = "archives"; //$NON-NLS-1$
/** An archive element, for the archives container. */ /** An archive element, for the archives container. */
public static final String NODE_ARCHVIE = "archive"; //$NON-NLS-1$ public static final String NODE_ARCHIVE = "archive"; //$NON-NLS-1$
/** An archive size, an int > 0. */ /** An archive size, an int > 0. */
public static final String NODE_SIZE = "size"; //$NON-NLS-1$ public static final String NODE_SIZE = "size"; //$NON-NLS-1$
@@ -72,10 +72,12 @@ public class SdkRepository {
/** A download archive URL, either absolute or relative to the repository xml. */ /** A download archive URL, either absolute or relative to the repository xml. */
public static final String NODE_URL = "url"; //$NON-NLS-1$ public static final String NODE_URL = "url"; //$NON-NLS-1$
/** An archive checksum type, mandatory. */
public static final String ATTR_TYPE = "type"; //$NON-NLS-1$
/** An archive OS attribute, mandatory. */ /** An archive OS attribute, mandatory. */
public static final String NODE_OS = "os"; //$NON-NLS-1$ public static final String ATTR_OS = "os"; //$NON-NLS-1$
/** An optional archive Architecture attribute. */ /** An optional archive Architecture attribute. */
public static final String NODE_ARCH = "arch"; //$NON-NLS-1$ public static final String ATTR_ARCH = "arch"; //$NON-NLS-1$
public static InputStream getXsdStream() { public static InputStream getXsdStream() {
return SdkRepository.class.getResourceAsStream("sdk-repository.xsd"); //$NON-NLS-1$ return SdkRepository.class.getResourceAsStream("sdk-repository.xsd"); //$NON-NLS-1$

View File

@@ -16,8 +16,10 @@
package com.android.sdkuilib.internal.repository; 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.IDescription;
import com.android.sdklib.internal.repository.ITaskFactory; import com.android.sdklib.internal.repository.ITaskFactory;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.RepoSource; import com.android.sdklib.internal.repository.RepoSource;
import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IContentProvider;
@@ -108,8 +110,9 @@ class RepoSources {
* Get the children of the given parent. This is requested on-demand as * Get the children of the given parent. This is requested on-demand as
* nodes are expanded. * nodes are expanded.
* *
* For a {@link RepoSources} object, returns an array of {@link RepoSource}. * For a {@link RepoSources} object, returns an array of {@link RepoSource}s.
* For a {@link RepoSource}, returns an array of packages. * For a {@link RepoSource}, returns an array of {@link Package}s.
* For a {@link Package}, returns an array of {@link Archive}s.
*/ */
public Object[] getChildren(Object parentElement) { public Object[] getChildren(Object parentElement) {
if (parentElement instanceof RepoSources) { if (parentElement instanceof RepoSources) {
@@ -117,17 +120,21 @@ class RepoSources {
} else if (parentElement instanceof RepoSource) { } else if (parentElement instanceof RepoSource) {
RepoSource source = (RepoSource) parentElement; RepoSource source = (RepoSource) parentElement;
ArrayList<String> pkgs = source.getPackages(); Package[] packages = source.getPackages();
if (pkgs == null) { if (packages == null) {
source.load(mTaskFactory); source.load(mTaskFactory);
pkgs = source.getPackages(); packages = source.getPackages();
} }
if (pkgs != null) { if (packages != null) {
return pkgs.toArray(); return packages;
} }
} else if (parentElement instanceof Package) {
return ((Package) parentElement).getArchives();
} }
return new Object[0]; return new Object[0];
} }
@@ -148,7 +155,7 @@ class RepoSources {
* All {@link RepoSource} are expandable, whether they actually have any childre or not. * All {@link RepoSource} are expandable, whether they actually have any childre or not.
*/ */
public boolean hasChildren(Object element) { public boolean hasChildren(Object element) {
return element instanceof RepoSource; return element instanceof RepoSource || element instanceof Package;
} }
} }