Merge commit '17c674d1057aeb3946747ca3b1d67a8468e1efb4' * commit '17c674d1057aeb3946747ca3b1d67a8468e1efb4': ADT #1844909: Tweak XML schema, add more tests.
This commit is contained in:
@@ -86,9 +86,11 @@
|
|||||||
<xsd:element name="desc-url" type="xsd:token" minOccurs="0" />
|
<xsd:element name="desc-url" type="xsd:token" minOccurs="0" />
|
||||||
<xsd:element name="archives" type="sdk:archivesType" />
|
<xsd:element name="archives" type="sdk:archivesType" />
|
||||||
|
|
||||||
|
<!-- An add-on can declare 0 or more libraries. -->
|
||||||
|
|
||||||
<xsd:element name="libs">
|
<xsd:element name="libs">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:sequence maxOccurs="unbounded">
|
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
<xsd:element name="lib">
|
<xsd:element name="lib">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:all>
|
<xsd:all>
|
||||||
@@ -135,13 +137,16 @@
|
|||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
<!-- A collection of files that can be downloaded for a given architectures -->
|
<!-- 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.
|
||||||
|
-->
|
||||||
|
|
||||||
<xsd:complexType name="archivesType">
|
<xsd:complexType name="archivesType">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>A collection of architecture-dependent archives.</xsd:documentation>
|
<xsd:documentation>A collection of architecture-dependent archives.</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
<xsd:sequence maxOccurs="unbounded">
|
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
|
||||||
<!-- One archive file -->
|
<!-- One archive file -->
|
||||||
<xsd:element name="archive">
|
<xsd:element name="archive">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
|
|||||||
@@ -16,15 +16,15 @@
|
|||||||
|
|
||||||
package com.android.sdklib.repository;
|
package com.android.sdklib.repository;
|
||||||
|
|
||||||
import com.android.sdklib.repository.SdkRepositoryConstants;
|
|
||||||
|
|
||||||
import org.xml.sax.ErrorHandler;
|
import org.xml.sax.ErrorHandler;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.stream.StreamSource;
|
import javax.xml.transform.stream.StreamSource;
|
||||||
import javax.xml.validation.Schema;
|
import javax.xml.validation.Schema;
|
||||||
import javax.xml.validation.SchemaFactory;
|
import javax.xml.validation.SchemaFactory;
|
||||||
@@ -50,34 +50,10 @@ public class TestSdkRepository extends TestCase {
|
|||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testValidateLocalRepositoryFile() throws Exception {
|
/**
|
||||||
|
* A SAX error handler that captures the errors and warnings.
|
||||||
InputStream xsdStream = SdkRepositoryConstants.getXsdStream();
|
* This allows us to capture *all* errors and just not get an exception on the first one.
|
||||||
InputStream xmlStream = TestSdkRepository.class.getResourceAsStream("repository_sample.xml");
|
*/
|
||||||
|
|
||||||
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
|
||||||
|
|
||||||
Schema schema = factory.newSchema(new StreamSource(xsdStream));
|
|
||||||
|
|
||||||
Validator validator = schema.newValidator();
|
|
||||||
|
|
||||||
CaptureErrorHandler handler = new CaptureErrorHandler();
|
|
||||||
validator.setErrorHandler(handler);
|
|
||||||
|
|
||||||
validator.validate(new StreamSource(xmlStream));
|
|
||||||
|
|
||||||
String warnings = handler.getWarnings();
|
|
||||||
if (warnings.length() > 0) {
|
|
||||||
System.err.println(warnings);
|
|
||||||
}
|
|
||||||
|
|
||||||
String errors = handler.getErrors();
|
|
||||||
if (errors.length() > 0) {
|
|
||||||
System.err.println(errors);
|
|
||||||
fail(errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class CaptureErrorHandler implements ErrorHandler {
|
private static class CaptureErrorHandler implements ErrorHandler {
|
||||||
|
|
||||||
private String mWarnings = "";
|
private String mWarnings = "";
|
||||||
@@ -91,6 +67,22 @@ public class TestSdkRepository extends TestCase {
|
|||||||
return mWarnings;
|
return mWarnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies if the handler captures some errors or warnings.
|
||||||
|
* Prints them on stderr.
|
||||||
|
* Also fails the unit test if any error was generated.
|
||||||
|
*/
|
||||||
|
public void verify() {
|
||||||
|
if (mWarnings.length() > 0) {
|
||||||
|
System.err.println(mWarnings);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mErrors.length() > 0) {
|
||||||
|
System.err.println(mErrors);
|
||||||
|
fail(mErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws SAXException
|
* @throws SAXException
|
||||||
*/
|
*/
|
||||||
@@ -98,9 +90,11 @@ public class TestSdkRepository extends TestCase {
|
|||||||
mErrors += "Error: " + ex.getMessage() + "\n";
|
mErrors += "Error: " + ex.getMessage() + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws SAXException
|
||||||
|
*/
|
||||||
public void fatalError(SAXParseException ex) throws SAXException {
|
public void fatalError(SAXParseException ex) throws SAXException {
|
||||||
mErrors += "Fatal Error: " + ex.getMessage() + "\n";
|
mErrors += "Fatal Error: " + ex.getMessage() + "\n";
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,4 +106,143 @@ public class TestSdkRepository extends TestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Helpers ------------
|
||||||
|
|
||||||
|
/** Helper method that returns a validator for our XSD */
|
||||||
|
private Validator getValidator(CaptureErrorHandler handler) throws SAXException {
|
||||||
|
InputStream xsdStream = SdkRepositoryConstants.getXsdStream();
|
||||||
|
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
|
Schema schema = factory.newSchema(new StreamSource(xsdStream));
|
||||||
|
Validator validator = schema.newValidator();
|
||||||
|
if (handler != null) {
|
||||||
|
validator.setErrorHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Validate a valid sample using an InputStream */
|
||||||
|
public void testValidateLocalRepositoryFile() throws Exception {
|
||||||
|
|
||||||
|
InputStream xmlStream =
|
||||||
|
TestSdkRepository.class.getResourceAsStream("repository_sample.xml");
|
||||||
|
Source source = new StreamSource(xmlStream);
|
||||||
|
|
||||||
|
CaptureErrorHandler handler = new CaptureErrorHandler();
|
||||||
|
Validator validator = getValidator(handler);
|
||||||
|
validator.validate(source);
|
||||||
|
handler.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** An helper that validates a string against an expected regexp. */
|
||||||
|
private void assertRegex(String expectedRegexp, String actualString) {
|
||||||
|
assertNotNull(actualString);
|
||||||
|
assertTrue(
|
||||||
|
String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n",
|
||||||
|
expectedRegexp, actualString),
|
||||||
|
actualString.matches(expectedRegexp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tests ------------
|
||||||
|
|
||||||
|
/** A document should at least have a root to be valid */
|
||||||
|
public void testEmptyXml() throws Exception {
|
||||||
|
String document = "<?xml version=\"1.0\"?>";
|
||||||
|
|
||||||
|
Source source = new StreamSource(new StringReader(document));
|
||||||
|
|
||||||
|
CaptureErrorHandler handler = new CaptureErrorHandler();
|
||||||
|
Validator validator = getValidator(handler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
validator.validate(source);
|
||||||
|
} catch (SAXParseException e) {
|
||||||
|
// We expect to get this specific exception message
|
||||||
|
assertRegex("Premature end of file.*", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We shouldn't get here
|
||||||
|
handler.verify();
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A document with a root element containing no platform, addon, etc., is valid. */
|
||||||
|
public void testEmptyRootXml() throws Exception {
|
||||||
|
String document = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" />";
|
||||||
|
|
||||||
|
Source source = new StreamSource(new StringReader(document));
|
||||||
|
|
||||||
|
CaptureErrorHandler handler = new CaptureErrorHandler();
|
||||||
|
Validator validator = getValidator(handler);
|
||||||
|
validator.validate(source);
|
||||||
|
handler.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A document with an unknown element. */
|
||||||
|
public void testUnknownContentXml() throws Exception {
|
||||||
|
String document = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +
|
||||||
|
"<r:unknown />" +
|
||||||
|
"</r:sdk-repository>";
|
||||||
|
|
||||||
|
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(null);
|
||||||
|
try {
|
||||||
|
validator.validate(source);
|
||||||
|
} catch (SAXParseException e) {
|
||||||
|
// We expect a parse expression referring to this grammar rule
|
||||||
|
assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If we get here, the validator has not failed as we expected it to.
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A document with an incomplete element. */
|
||||||
|
public void testIncompleteContentXml() throws Exception {
|
||||||
|
String document = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +
|
||||||
|
"<r:platform> <r:api-level>1</r:api-level> <r:libs /> </r:platform>" +
|
||||||
|
"</r:sdk-repository>";
|
||||||
|
|
||||||
|
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(null);
|
||||||
|
try {
|
||||||
|
validator.validate(source);
|
||||||
|
} catch (SAXParseException e) {
|
||||||
|
// We expect a parse error referring to this grammar rule
|
||||||
|
assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If we get here, the validator has not failed as we expected it to.
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A document with a wrong type element. */
|
||||||
|
public void testWrongTypeContentXml() throws Exception {
|
||||||
|
String document = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +
|
||||||
|
"<r:platform> <r:api-level>NotAnInteger</r:api-level> <r:libs /> </r:platform>" +
|
||||||
|
"</r:sdk-repository>";
|
||||||
|
|
||||||
|
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(null);
|
||||||
|
try {
|
||||||
|
validator.validate(source);
|
||||||
|
} catch (SAXParseException e) {
|
||||||
|
// We expect a parse error referring to this grammar rule
|
||||||
|
assertRegex("cvc-datatype-valid.1.2.1: 'NotAnInteger' is not a valid value.*",
|
||||||
|
e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If we get here, the validator has not failed as we expected it to.
|
||||||
|
fail();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,17 @@
|
|||||||
<sdk:sdk-repository
|
<sdk:sdk-repository
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:sdk="http://schemas.android.com/sdk/android/repository/1">
|
xmlns:sdk="http://schemas.android.com/sdk/android/repository/1">
|
||||||
|
|
||||||
|
<!-- Inner elements must be either platform, add-on, doc or tool.
|
||||||
|
There can be 0 or more of each, in any order. -->
|
||||||
|
|
||||||
<sdk:platform>
|
<sdk:platform>
|
||||||
<sdk:version>1.0</sdk:version>
|
<sdk:version>1.0</sdk:version>
|
||||||
<sdk:api-level>1</sdk:api-level>
|
<sdk:api-level>1</sdk:api-level>
|
||||||
<sdk:revision>3</sdk:revision>
|
<sdk:revision>3</sdk:revision>
|
||||||
<sdk:description>Some optional description</sdk:description>
|
<sdk:description>Some optional description</sdk:description>
|
||||||
<sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url>
|
<sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url>
|
||||||
|
<!-- The archives node is mandatory and it cannot be empty. -->
|
||||||
<sdk:archives>
|
<sdk:archives>
|
||||||
<sdk:archive os="any">
|
<sdk:archive os="any">
|
||||||
<sdk:size>65536</sdk:size>
|
<sdk:size>65536</sdk:size>
|
||||||
@@ -31,6 +36,48 @@
|
|||||||
</sdk:archive>
|
</sdk:archive>
|
||||||
</sdk:archives>
|
</sdk:archives>
|
||||||
</sdk:platform>
|
</sdk:platform>
|
||||||
|
|
||||||
|
<sdk:doc>
|
||||||
|
<sdk:api-level>1</sdk:api-level>
|
||||||
|
<sdk:revision>1</sdk:revision>
|
||||||
|
<sdk:description>Some optional description</sdk:description>
|
||||||
|
<sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url>
|
||||||
|
<sdk:archives>
|
||||||
|
<sdk:archive os="any">
|
||||||
|
<sdk:size>65536</sdk:size>
|
||||||
|
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
||||||
|
<sdk:url>http://www.example.com/docs/docs1.zip</sdk:url>
|
||||||
|
</sdk:archive>
|
||||||
|
</sdk:archives>
|
||||||
|
</sdk:doc>
|
||||||
|
|
||||||
|
<sdk:add-on>
|
||||||
|
<sdk:name>My First add-on</sdk:name>
|
||||||
|
<sdk:api-level>1</sdk:api-level>
|
||||||
|
<sdk:vendor>John Doe</sdk:vendor>
|
||||||
|
<sdk:revision>1</sdk:revision>
|
||||||
|
<sdk:description>Some optional description</sdk:description>
|
||||||
|
<sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url>
|
||||||
|
<sdk:archives>
|
||||||
|
<sdk:archive os="any">
|
||||||
|
<sdk:size>65536</sdk:size>
|
||||||
|
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
||||||
|
<sdk:url>http://www.example.com/add-ons/first.zip</sdk:url>
|
||||||
|
</sdk:archive>
|
||||||
|
</sdk:archives>
|
||||||
|
<!-- The libs node is mandatory, however it can be empty. -->
|
||||||
|
<sdk:libs>
|
||||||
|
<sdk:lib>
|
||||||
|
<sdk:name>android.blah.somelib</sdk:name>
|
||||||
|
<sdk:description>The description for this library.</sdk:description>
|
||||||
|
</sdk:lib>
|
||||||
|
<sdk:lib>
|
||||||
|
<!-- sdk:description is optional, name is not -->
|
||||||
|
<sdk:name>com.android.mymaps</sdk:name>
|
||||||
|
</sdk:lib>
|
||||||
|
</sdk:libs>
|
||||||
|
</sdk:add-on>
|
||||||
|
|
||||||
<sdk:platform>
|
<sdk:platform>
|
||||||
<sdk:version>1.1</sdk:version>
|
<sdk:version>1.1</sdk:version>
|
||||||
<sdk:api-level>2</sdk:api-level>
|
<sdk:api-level>2</sdk:api-level>
|
||||||
@@ -65,31 +112,7 @@
|
|||||||
</sdk:archive>
|
</sdk:archive>
|
||||||
</sdk:archives>
|
</sdk:archives>
|
||||||
</sdk:platform>
|
</sdk:platform>
|
||||||
<sdk:add-on>
|
|
||||||
<sdk:name>My First add-on</sdk:name>
|
|
||||||
<sdk:api-level>1</sdk:api-level>
|
|
||||||
<sdk:vendor>John Doe</sdk:vendor>
|
|
||||||
<sdk:revision>1</sdk:revision>
|
|
||||||
<sdk:description>Some optional description</sdk:description>
|
|
||||||
<sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url>
|
|
||||||
<sdk:archives>
|
|
||||||
<sdk:archive os="any">
|
|
||||||
<sdk:size>65536</sdk:size>
|
|
||||||
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
|
||||||
<sdk:url>http://www.example.com/add-ons/first.zip</sdk:url>
|
|
||||||
</sdk:archive>
|
|
||||||
</sdk:archives>
|
|
||||||
<sdk:libs>
|
|
||||||
<sdk:lib>
|
|
||||||
<sdk:name>android.blah.somelib</sdk:name>
|
|
||||||
<sdk:description>The description for this library.</sdk:description>
|
|
||||||
</sdk:lib>
|
|
||||||
<sdk:lib>
|
|
||||||
<!-- sdk:description is optional, name is not -->
|
|
||||||
<sdk:name>com.android.mymaps</sdk:name>
|
|
||||||
</sdk:lib>
|
|
||||||
</sdk:libs>
|
|
||||||
</sdk:add-on>
|
|
||||||
<sdk:add-on>
|
<sdk:add-on>
|
||||||
<sdk:name>My Second add-on</sdk:name>
|
<sdk:name>My Second add-on</sdk:name>
|
||||||
<sdk:api-level>2</sdk:api-level>
|
<sdk:api-level>2</sdk:api-level>
|
||||||
@@ -117,19 +140,20 @@
|
|||||||
</sdk:lib>
|
</sdk:lib>
|
||||||
</sdk:libs>
|
</sdk:libs>
|
||||||
</sdk:add-on>
|
</sdk:add-on>
|
||||||
<sdk:doc>
|
|
||||||
<sdk:api-level>1</sdk:api-level>
|
<sdk:tool>
|
||||||
<sdk:revision>1</sdk:revision>
|
<sdk:revision>1</sdk:revision>
|
||||||
<sdk:description>Some optional description</sdk:description>
|
<sdk:description>Some optional description</sdk:description>
|
||||||
<sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url>
|
<sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url>
|
||||||
<sdk:archives>
|
<sdk:archives>
|
||||||
<sdk:archive os="any">
|
<sdk:archive os="any">
|
||||||
<sdk:size>65536</sdk:size>
|
<sdk:size>65536</sdk:size>
|
||||||
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
||||||
<sdk:url>http://www.example.com/docs/docs1.zip</sdk:url>
|
<sdk:url>http://www.example.com/files/tools1.zip</sdk:url>
|
||||||
</sdk:archive>
|
</sdk:archive>
|
||||||
</sdk:archives>
|
</sdk:archives>
|
||||||
</sdk:doc>
|
</sdk:tool>
|
||||||
|
|
||||||
<sdk:doc>
|
<sdk:doc>
|
||||||
<sdk:api-level>2</sdk:api-level>
|
<sdk:api-level>2</sdk:api-level>
|
||||||
<sdk:revision>42</sdk:revision>
|
<sdk:revision>42</sdk:revision>
|
||||||
@@ -151,18 +175,7 @@
|
|||||||
</sdk:archive>
|
</sdk:archive>
|
||||||
</sdk:archives>
|
</sdk:archives>
|
||||||
</sdk:doc>
|
</sdk:doc>
|
||||||
<sdk:tool>
|
|
||||||
<sdk:revision>1</sdk:revision>
|
|
||||||
<sdk:description>Some optional description</sdk:description>
|
|
||||||
<sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url>
|
|
||||||
<sdk:archives>
|
|
||||||
<sdk:archive os="any">
|
|
||||||
<sdk:size>65536</sdk:size>
|
|
||||||
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
|
||||||
<sdk:url>http://www.example.com/files/tools1.zip</sdk:url>
|
|
||||||
</sdk:archive>
|
|
||||||
</sdk:archives>
|
|
||||||
</sdk:tool>
|
|
||||||
<sdk:tool>
|
<sdk:tool>
|
||||||
<sdk:revision>42</sdk:revision>
|
<sdk:revision>42</sdk:revision>
|
||||||
<sdk:archives>
|
<sdk:archives>
|
||||||
@@ -183,4 +196,21 @@
|
|||||||
</sdk:archive>
|
</sdk:archive>
|
||||||
</sdk:archives>
|
</sdk:archives>
|
||||||
</sdk:tool>
|
</sdk:tool>
|
||||||
|
|
||||||
|
<sdk:add-on>
|
||||||
|
<sdk:name>This add-on has no libraries</sdk:name>
|
||||||
|
<sdk:api-level>4</sdk:api-level>
|
||||||
|
<sdk:vendor>Joe Bar</sdk:vendor>
|
||||||
|
<sdk:revision>3</sdk:revision>
|
||||||
|
<sdk:archives>
|
||||||
|
<sdk:archive os="any" arch="any">
|
||||||
|
<sdk:size>65536</sdk:size>
|
||||||
|
<sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
|
||||||
|
<sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url>
|
||||||
|
</sdk:archive>
|
||||||
|
</sdk:archives>
|
||||||
|
<!-- The libs node is mandatory, however it can be empty. -->
|
||||||
|
<sdk:libs />
|
||||||
|
</sdk:add-on>
|
||||||
|
|
||||||
</sdk:sdk-repository>
|
</sdk:sdk-repository>
|
||||||
|
|||||||
Reference in New Issue
Block a user