package test.metatype;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import javax.xml.xpath.XPathExpressionException;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
import aQute.bnd.annotation.metatype.Meta;
import aQute.bnd.annotation.xml.XMLAttribute;
import aQute.bnd.metatype.MetatypeVersion;
import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Resource;
import aQute.bnd.test.XmlTester;
import aQute.lib.io.IO;
import junit.framework.TestCase;
@SuppressWarnings({
"resource", "restriction"
})
public class SpecMetatypeTest extends TestCase {
public enum Foo {
A, B
}
/**
* Test method naming options with '.' and reserved names
*/
@ObjectClassDefinition
public static interface Naming {
String secret();
String _secret(); // .secret
String __secret(); // _secret
String $new(); // new
String $$new(); // $new
String a_b_c(); // a.b.c
String a__b__c(); // a_b_c
String _a__b(); // .a_b
String $$$$$$$$a__b(); // $$$$a_b
String $$$$$$$$a_b(); // $$$$a.b
String a$(); // a
String a$$(); // a$
String b$$$(); // b$
String a$$$$(); // a$$
String a$$_$$(); // a$.$
String a$$__$$(); // a$_$
String a_$_(); // a..
@AttributeDefinition(name = "secret")
String xsecret();
@AttributeDefinition(name = ".secret")
String x_secret();
@AttributeDefinition(name = "_secret")
String x__secret(); // _secret
@AttributeDefinition(name = "new")
String x$new(); // new
@AttributeDefinition(name = "$new")
String x$$new(); // $new
@AttributeDefinition(name = "a.b.c")
String xa_b_c(); // a.b.c
@AttributeDefinition(name = "a_b_c")
String xa__b__c(); // a_b_c
@AttributeDefinition(name = ".a_b")
String x_a__b(); // .a_b
@AttributeDefinition(name = "$$$$a_b")
String x$$$$$$$$a__b(); // $$$$a_b
@AttributeDefinition(name = "$$$$a.b")
String x$$$$$$$$a_b(); // $$$$a.b
@AttributeDefinition(name = "a")
String xa$(); // a
@AttributeDefinition(name = "a$")
String xa$$(); // a$
@AttributeDefinition(name = "a$")
String xb$$$(); // b$
@AttributeDefinition(name = "a$$")
String xa$$$$(); // a$$
@AttributeDefinition(name = "a$.$")
String xa$$_$$(); // a$.$
@AttributeDefinition(name = "a$_$")
String xa$$__$$(); // a$_$
@AttributeDefinition(name = "a..")
String xa_$_(); // a..
String noid();
@AttributeDefinition(name = "§NULL§") // Meta.NULL
String nullid();
}
private void assertAD(XmlTester xt, String id, String name) throws XPathExpressionException {
assertAD(xt, id, name, null, null, null, 0, "String", null, null, null);
}
public void testNaming() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, Naming.class.getName());
b.build();
System.out.println(b.getErrors());
assertEquals(0, b.getErrors().size());
System.out.println(b.getWarnings());
assertEquals(0, b.getWarnings().size());
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$Naming.xml");
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
assertAD(xt, "secret", "Secret");
assertAD(xt, ".secret", "Secret");
assertAD(xt, "_secret", "Secret");
assertAD(xt, "new", "New");
assertAD(xt, "$new", "New");
assertAD(xt, "a.b.c", "A b c");
assertAD(xt, "a_b_c", "A b c");
assertAD(xt, ".a_b", "A b");
assertAD(xt, "$$$$a_b", "A b");
assertAD(xt, "$$$$a.b", "A b");
assertAD(xt, "a", "A ");
assertAD(xt, "a$", "A ");
assertAD(xt, "b$", "B ");
assertAD(xt, "a$$", "A ");
assertAD(xt, "a$.$", "A ");
assertAD(xt, "a$_$", "A ");
assertAD(xt, "a..", "A ");
assertAD(xt, "xsecret", "secret");
assertAD(xt, "x.secret", ".secret");
assertAD(xt, "x_secret", "_secret");
assertAD(xt, "xnew", "new");
assertAD(xt, "x$new", "$new");
assertAD(xt, "xa.b.c", "a.b.c");
assertAD(xt, "xa_b_c", "a_b_c");
assertAD(xt, "x.a_b", ".a_b");
assertAD(xt, "x$$$$a_b", "$$$$a_b");
assertAD(xt, "x$$$$a.b", "$$$$a.b");
assertAD(xt, "xa", "a");
assertAD(xt, "xa$", "a$");
assertAD(xt, "xb$", "a$");
assertAD(xt, "xa$$", "a$$");
assertAD(xt, "xa$.$", "a$.$");
assertAD(xt, "xa$_$", "a$_$");
assertAD(xt, "xa..", "a..");
assertAD(xt, "noid", "Noid");
assertAD(xt, "nullid", "§NULL§");
}
/**
* Test method naming options with '.' and reserved names
*/
@ObjectClassDefinition
public static @interface Naming14 {
String PREFIX_ = "test.";
String a$_$b() default "foo"; // test.a-b
@AttributeDefinition(name = "a-b")
String xa$_$b() default "foo"; // test.xa-b
String value() default "foo"; // test.naming14
}
private void assertAD(XmlTester xt, String id, String name, String deflt) throws XPathExpressionException {
assertAD(xt, id, name, null, null, deflt, 0, "String", null, null, null);
}
public void testNaming14() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, Naming14.class.getName());
b.build();
System.out.println(b.getErrors());
assertEquals(0, b.getErrors().size());
System.out.println(b.getWarnings());
assertEquals(0, b.getWarnings().size());
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$Naming14.xml");
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester14(r);
assertAD(xt, "test.a-b", "A b", "foo");
assertAD(xt, "test.xa-b", "a-b", "foo");
assertAD(xt, "test.naming14", "Value", "foo");
}
@ObjectClassDefinition
public static interface ADCollision {
String a$$(); // a$
String a$$$(); // a$
}
public void testADCollision() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, ADCollision.class.getName());
b.build();
System.out.println(b.getErrors());
assertEquals(1, b.getErrors().size());
}
@ObjectClassDefinition(id = "duplicate")
public static interface DupOCDId1 {
}
@ObjectClassDefinition(id = "duplicate")
public static interface DupOCDId2 {
}
public void testOCDCollision() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
String name = DupOCDId2.class.getName();
b.setProperty(Constants.METATYPE_ANNOTATIONS, name.substring(0, name.length() - "1".length()) + "*");
b.build();
assertEquals(1, b.getErrors().size());
}
@ObjectClassDefinition(pid = {
"1"
})
public static interface DupPid1 {
}
@ObjectClassDefinition(pid = {
"1"
})
public static interface DupPid2 {
}
@ObjectClassDefinition(factoryPid = {
"2"
})
public static interface DupPid3 {
}
@ObjectClassDefinition(factoryPid = {
"2"
})
public static interface DupPid4 {
}
@ObjectClassDefinition(pid = {
"3"
}, factoryPid = {
"3"
})
public static interface DupPid5 {
}
@ObjectClassDefinition(pid = {
"4"
})
public static interface DupPid6 {
}
@ObjectClassDefinition(factoryPid = {
"4"
})
public static interface DupPid7 {
}
public void testPidCollision() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
String name = DupPid2.class.getName();
b.setProperty(Constants.METATYPE_ANNOTATIONS, name.substring(0, name.length() - "1".length()) + "*");
b.build();
System.err.println(b.getErrors());
assertEquals(4, b.getErrors().size());
}
/**
* Test the special conversions.
*/
public static class MyList<T> extends ArrayList<T> {
private static final long serialVersionUID = 1L;
public MyList() {}
}
interface L<T> extends List<T> {}
public static class StringList<T> implements L<T> {
@Override
public void add(int arg0, T arg1) {
// TODO Auto-generated method stub
}
@Override
public boolean addAll(int arg0, Collection< ? extends T> arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public T get(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public int indexOf(Object arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int lastIndexOf(Object arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public ListIterator<T> listIterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public ListIterator<T> listIterator(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public T remove(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public T set(int arg0, T arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<T> subList(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean add(T arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean addAll(Collection< ? extends T> arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public void clear() {
// TODO Auto-generated method stub
}
@Override
public boolean contains(Object arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean containsAll(Collection< ? > arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
@Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean remove(Object arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean removeAll(Collection< ? > arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean retainAll(Collection< ? > arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public int size() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object[] toArray() {
// TODO Auto-generated method stub
return null;
}
@Override
@SuppressWarnings("hiding")
public <T> T[] toArray(T[] arg0) {
// TODO Auto-generated method stub
return null;
}
}
@ObjectClassDefinition
static interface CollectionsTest {
Collection<String> collection();
List<String> list();
Set<String> set();
// Queue<String> queue();
// Deque<String> deque();
// Stack<String> stack();
ArrayList<String> arrayList();
LinkedList<String> linkedList();
LinkedHashSet<String> linkedHashSet();
MyList<String> myList();
StringList<String> stringList();
}
public void testCollections() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, CollectionsTest.class.getName());
b.build();
System.out.println(b.getErrors());
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources());
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$CollectionsTest.xml");
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='collection']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='list']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='set']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='arrayList']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='linkedList']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='linkedHashSet']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='myList']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='stringList']/@cardinality");
}
/**
* Test enum handling
*/
@ObjectClassDefinition
public static interface Enums {
enum X {
requireConfiguration, optionalConfiguration, ignoreConfiguration
}
X r();
X i();
X o();
}
private static final String[] optionLabels = {
"requireConfiguration", "optionalConfiguration",
"ignoreConfiguration"
};
private static final String[] optionValues = optionLabels;
private void assertAD(XmlTester xt, String id, String name, String[] optionLabels, String[] optionValues)
throws XPathExpressionException {
assertAD(xt, id, name, null, null, null, 0, "String", null, optionLabels, optionValues);
}
public void testEnum() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, Enums.class.getName() + "*");
b.build();
System.err.println(b.getErrors());
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$Enums.xml");
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
assertAD(xt, "r", "R", optionLabels, optionValues);
assertAD(xt, "i", "I", optionLabels, optionValues);
assertAD(xt, "o", "O", optionLabels, optionValues);
}
/**
* Test the OCD settings
*/
@ObjectClassDefinition(pid = {
"ocdEmptyPid"
})
public static interface OCDEmpty {}
@ObjectClassDefinition(description = "description", pid = {
"ocdDescriptionPid"
})
public static interface OCDDescription {}
@ObjectClassDefinition(pid = {
"ocdDesignatePidOnlyPid"
})
public static interface OCDDesignatePidOnly {}
@ObjectClassDefinition(factoryPid = {
"ocdDesignatePidFactoryFactoryPid"
})
public static interface OCDDesignatePidFactory {}
@ObjectClassDefinition(id = "id", pid = {
"ocdIdPid"
})
public static interface OCDId {}
@ObjectClassDefinition(id = "id2", pid = {
"ocdId2Pid"
})
public static interface OCDIdWithPid {}
@ObjectClassDefinition(localization = "localization", pid = {
"ocdLocalizationPid"
})
public static interface OCDLocalization {}
@ObjectClassDefinition(name = "name", pid = {
"ocdNamePid"
})
public static interface OCDName {}
public void testOCD() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
String name = OCDEmpty.class.getName();
b.setProperty(Constants.METATYPE_ANNOTATIONS, name.substring(0, name.length() - "Empty".length()) + "*");
b.build();
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDEmpty", "test.metatype.SpecMetatypeTest$OCDEmpty",
"Test metatype spec metatype test OCDEmpty", null, "ocdEmptyPid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDName", "test.metatype.SpecMetatypeTest$OCDName", "name", null,
"ocdNamePid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDDescription", "test.metatype.SpecMetatypeTest$OCDDescription",
"Test metatype spec metatype test OCDDescription", "description", "ocdDescriptionPid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDDesignatePidOnly",
"test.metatype.SpecMetatypeTest$OCDDesignatePidOnly",
"Test metatype spec metatype test OCDDesignate pid only", null, "ocdDesignatePidOnlyPid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDDesignatePidFactory",
"test.metatype.SpecMetatypeTest$OCDDesignatePidFactory",
"Test metatype spec metatype test OCDDesignate pid factory", null, "ocdDesignatePidFactoryFactoryPid",
true, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDId", "id", "Id", // 5.2
// name
// is
// derived
// from
// id
null, "ocdIdPid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDIdWithPid", "id2", "Id2", null, "ocdId2Pid", false, null);
assertOCD(b, "test.metatype.SpecMetatypeTest$OCDLocalization", "test.metatype.SpecMetatypeTest$OCDLocalization",
"Test metatype spec metatype test OCDLocalization", null, "ocdLocalizationPid", false, "localization");
}
private void assertOCD(Builder b, String cname, String id, String name, String description, String designate,
boolean factory, String localization) throws Exception {
Resource r = b.getJar().getResource("OSGI-INF/metatype/" + id + ".xml");
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester13(r);
xt.assertExactAttribute(id, "metatype:MetaData/OCD/@id");
xt.assertExactAttribute(name, "metatype:MetaData/OCD/@name");
String expected = localization == null ? "OSGI-INF/I10n/" + cname : localization;
xt.assertExactAttribute(localization == null ? "OSGI-INF/l10n/" + cname : localization,
"metatype:MetaData/@localization");
xt.assertExactAttribute(description == null ? "" : description, "metatype:MetaData/OCD/@description");
if (designate != null) {
if (factory)
xt.assertExactAttribute(designate, "metatype:MetaData/Designate/@factoryPid");
else
xt.assertExactAttribute(designate, "metatype:MetaData/Designate/@pid");
}
xt.assertExactAttribute(id, "metatype:MetaData/Designate/Object/@ocdref");
}
/**
* Test the AD settings.
*/
@ObjectClassDefinition(description = "advariations")
public static interface TestAD {
@AttributeDefinition
String noSettings();
@AttributeDefinition(name = "id")
String withId();
@AttributeDefinition(name = "name")
String withName();
@AttributeDefinition(max = "1")
String withMax();
@AttributeDefinition(min = "-1")
String withMin();
@AttributeDefinition(defaultValue = {
"deflt"
})
String withDefault();
@AttributeDefinition(cardinality = 0)
String[] withC0();
@AttributeDefinition(cardinality = 1)
String[] withC1();
@AttributeDefinition(cardinality = -1)
Collection<String> withC_1();
@AttributeDefinition(cardinality = -1)
String[] withC_1ButArray();
@AttributeDefinition(cardinality = 1)
Collection<String> withC1ButCollection();
@AttributeDefinition(type = AttributeType.STRING)
int withInt();
@AttributeDefinition(type = AttributeType.INTEGER)
String withString();
@AttributeDefinition(description = "description_xxx\"xxx'xxx")
String a();
@AttributeDefinition(options = {
@Option(label = "a", value = "a"), @Option(label = "b", value = "b")
})
String valuesOnly();
@AttributeDefinition(options = {
@Option(label = "a", value = "A"), @Option(label = "b", value = "B")
})
String labelsAndValues();
@AttributeDefinition(required = true)
String required();
@AttributeDefinition(required = false)
String notRequired();
}
public void testAD() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestAD.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestAD.xml");
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
assertAD(xt, "noSettings", "No settings", null, null, null, 0, "String", null, null, null);
assertAD(xt, "withId", "id", null, null, null, 0, "String", null, null, null);
assertAD(xt, "withName", "name", null, null, null, 0, "String", null, null, null);
assertAD(xt, "withMax", "With max", null, "1", null, 0, "String", null, null, null);
assertAD(xt, "withMin", "With min", "-1", null, null, 0, "String", null, null, null);
assertAD(xt, "withC1", "With c1", null, null, null, 1, "String", null, null, null);
assertAD(xt, "withC0", "With c0", null, null, null, 0, "String", null, null, null);
assertAD(xt, "withC.1", "With c 1", null, null, null, -1, "String", null, null, null);
assertAD(xt, "withC.1ButArray", "With c 1 but array", null, null, null, -1, "String", null, null, null);
assertAD(xt, "withC1ButCollection", "With c1 but collection", null, null, null, 1, "String", null, null, null);
assertAD(xt, "withInt", "With int", null, null, null, 0, "String", null, null, null);
assertAD(xt, "withString", "With string", null, null, null, 0, "Integer", null, null, null);
assertAD(xt, "a", "A", null, null, null, 0, "String", "description_xxx\"xxx'xxx", null, null);
assertAD(xt, "valuesOnly", "Values only", null, null, null, 0, "String", null, new String[] {
"a", "b"
}, new String[] {
"a", "b"
});
assertAD(xt, "labelsAndValues", "Labels and values", null, null, null, 0, "String", null, new String[] {
"a", "b"
}, new String[] {
"A", "B"
});
}
private XmlTester xmlTester12(Resource r) throws Exception {
return xmlTester(r, MetatypeVersion.VERSION_1_2);
}
private XmlTester xmlTester13(Resource r) throws Exception {
return xmlTester(r, MetatypeVersion.VERSION_1_3);
}
private XmlTester xmlTester14(Resource r) throws Exception {
return xmlTester(r, MetatypeVersion.VERSION_1_4);
}
private XmlTester xmlTester(Resource r, MetatypeVersion version) throws Exception {
XmlTester xt = new XmlTester(r.openInputStream(), "metatype", version.getNamespace());
xt.assertNamespace(version.getNamespace());
return xt;
}
/**
* Test the AD inheritance.
*/
@ObjectClassDefinition(description = "adinheritance-super-one")
public static interface TestADWithInheritanceSuperOne {
@AttributeDefinition
String fromSuperOne();
}
@ObjectClassDefinition(description = "adinheritance-super")
public static interface TestADWithInheritanceSuperTwo {
@AttributeDefinition
String fromSuperTwo();
}
@ObjectClassDefinition(description = "adinheritance-child")
public static interface TestADWithInheritanceChild
extends TestADWithInheritanceSuperOne, TestADWithInheritanceSuperTwo {
@AttributeDefinition
String fromChild();
}
public void testADWithInheritance() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestADWithInheritanceChild.class.getName().substring(0,
TestADWithInheritanceChild.class.getName().length() - "Child".length()) + "*");
// b.setProperty("-metatypeannotations-inherit", "true");
b.build();
Resource r = b.getJar()
.getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestADWithInheritanceChild.xml");
System.err.println(b.getErrors());
assertEquals(0, b.getErrors().size());
System.err.println(b.getWarnings());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
assertAD(xt, "fromChild", "From child", null, null, null, 0, "String", null, null, null);
assertAD(xt, "fromSuperOne", "From super one", null, null, null, 0, "String", null, null, null);
assertAD(xt, "fromSuperTwo", "From super two", null, null, null, 0, "String", null, null, null);
}
@SuppressWarnings("null")
private void assertAD(XmlTester xt, String id, String name, String min, String max, String deflt, int cardinality,
String type, String description, String[] optionLabels, String[] optionValues)
throws XPathExpressionException {
xt.assertExactAttribute(name, "metatype:MetaData/OCD/AD[@id='" + id + "']/@name");
xt.assertExactAttribute(id, "metatype:MetaData/OCD/AD[@id='" + id + "']/@id");
xt.assertExactAttribute(min == null ? "" : min, "metatype:MetaData/OCD/AD[@id='" + id + "']/@min");
xt.assertExactAttribute(max == null ? "" : max, "metatype:MetaData/OCD/AD[@id='" + id + "']/@max");
xt.assertExactAttribute(deflt == null ? "" : deflt, "metatype:MetaData/OCD/AD[@id='" + id + "']/@default");
if (cardinality == 0) {
xt.assertExactAttribute("", "metatype:MetaData/OCD/AD[@id='" + id + "']/@cardinality");
} else {
xt.assertExactAttribute(cardinality + "", "metatype:MetaData/OCD/AD[@id='" + id + "']/@cardinality");
}
xt.assertExactAttribute(type, "metatype:MetaData/OCD/AD[@id='" + id + "']/@type");
xt.assertExactAttribute(description == null ? "" : description,
"metatype:MetaData/OCD/AD[@id='" + id + "']/@description");
assertEquals(optionLabels == null, optionValues == null);
if (optionLabels != null) {
assertEquals(optionLabels.length, optionValues.length);
// option count is correct
xt.assertNumber(Double.valueOf(optionLabels.length),
"count(metatype:MetaData/OCD/AD[@id='" + id + "']/Option)");
for (int i = 0; i < optionLabels.length; i++) {
String expr = "metatype:MetaData/OCD/AD[@id='" + id + "']/Option[@label='" + optionLabels[i]
+ "']/@value";
xt.assertExactAttribute(optionValues[i], expr);
}
}
}
/**
* Test all the return types.
*/
@ObjectClassDefinition(description = "simple", name = "TestSimple")
public static interface TestReturnTypes {
boolean rpBoolean();
byte rpByte();
char rpCharacter();
short rpShort();
int rpInt();
long rpLong();
float rpFloat();
double rpDouble();
Boolean rBoolean();
Byte rByte();
Character rCharacter();
Short rShort();
Integer rInt();
Long rLong();
Float rFloat();
Double rDouble();
String rString();
URI rURI();
boolean[] rpaBoolean();
byte[] rpaByte();
char[] rpaCharacter();
short[] rpaShort();
int[] rpaInt();
long[] rpaLong();
float[] rpaFloat();
double[] rpaDouble();
Collection<Boolean> rBooleans();
Collection<Byte> rBytes();
Collection<Character> rCharacters();
Collection<Short> rShorts();
Collection<Integer> rInts();
Collection<Long> rLongs();
Collection<Float> rFloats();
Collection<Double> rDoubles();
Collection<String> rStrings();
Collection<URI> rURIs();
Boolean[] raBoolean();
Byte[] raByte();
Character[] raCharacter();
Short[] raShort();
Integer[] raInt();
Long[] raLong();
Float[] raFloat();
Double[] raDouble();
String[] raString();
URI[] raURI();
}
public void testReturnTypes() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestReturnTypes.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestReturnTypes.xml");
System.err.println(b.getErrors());
assertEquals(0, b.getErrors().size());
System.err.println(b.getWarnings());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
// Primitives
xt.assertExactAttribute("Boolean", "metatype:MetaData/OCD/AD[@id='rpBoolean']/@type");
xt.assertExactAttribute("Byte", "metatype:MetaData/OCD/AD[@id='rpByte']/@type");
xt.assertExactAttribute("Char", "metatype:MetaData/OCD/AD[@id='rpCharacter']/@type");
xt.assertExactAttribute("Short", "metatype:MetaData/OCD/AD[@id='rpShort']/@type");
xt.assertExactAttribute("Integer", "metatype:MetaData/OCD/AD[@id='rpInt']/@type");
xt.assertExactAttribute("Long", "metatype:MetaData/OCD/AD[@id='rpLong']/@type");
xt.assertExactAttribute("Float", "metatype:MetaData/OCD/AD[@id='rpFloat']/@type");
xt.assertExactAttribute("Double", "metatype:MetaData/OCD/AD[@id='rpDouble']/@type");
// Primitive Wrappers
xt.assertExactAttribute("Boolean", "metatype:MetaData/OCD/AD[@id='rBoolean']/@type");
xt.assertExactAttribute("Byte", "metatype:MetaData/OCD/AD[@id='rByte']/@type");
xt.assertExactAttribute("Char", "metatype:MetaData/OCD/AD[@id='rCharacter']/@type");
xt.assertExactAttribute("Short", "metatype:MetaData/OCD/AD[@id='rShort']/@type");
xt.assertExactAttribute("Integer", "metatype:MetaData/OCD/AD[@id='rInt']/@type");
xt.assertExactAttribute("Long", "metatype:MetaData/OCD/AD[@id='rLong']/@type");
xt.assertExactAttribute("Float", "metatype:MetaData/OCD/AD[@id='rFloat']/@type");
xt.assertExactAttribute("Double", "metatype:MetaData/OCD/AD[@id='rDouble']/@type");
// Primitive Arrays
xt.assertExactAttribute("Boolean", "metatype:MetaData/OCD/AD[@id='rpaBoolean']/@type");
xt.assertExactAttribute("Byte", "metatype:MetaData/OCD/AD[@id='rpaByte']/@type");
xt.assertExactAttribute("Char", "metatype:MetaData/OCD/AD[@id='rpaCharacter']/@type");
xt.assertExactAttribute("Short", "metatype:MetaData/OCD/AD[@id='rpaShort']/@type");
xt.assertExactAttribute("Integer", "metatype:MetaData/OCD/AD[@id='rpaInt']/@type");
xt.assertExactAttribute("Long", "metatype:MetaData/OCD/AD[@id='rpaLong']/@type");
xt.assertExactAttribute("Float", "metatype:MetaData/OCD/AD[@id='rpaFloat']/@type");
xt.assertExactAttribute("Double", "metatype:MetaData/OCD/AD[@id='rpaDouble']/@type");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaBoolean']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaByte']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaCharacter']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaShort']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaInt']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaLong']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaFloat']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='rpaDouble']/@cardinality");
// Wrapper + Object arrays
xt.assertExactAttribute("Boolean", "metatype:MetaData/OCD/AD[@id='raBoolean']/@type");
xt.assertExactAttribute("Byte", "metatype:MetaData/OCD/AD[@id='raByte']/@type");
xt.assertExactAttribute("Char", "metatype:MetaData/OCD/AD[@id='raCharacter']/@type");
xt.assertExactAttribute("Short", "metatype:MetaData/OCD/AD[@id='raShort']/@type");
xt.assertExactAttribute("Integer", "metatype:MetaData/OCD/AD[@id='raInt']/@type");
xt.assertExactAttribute("Long", "metatype:MetaData/OCD/AD[@id='raLong']/@type");
xt.assertExactAttribute("Float", "metatype:MetaData/OCD/AD[@id='raFloat']/@type");
xt.assertExactAttribute("Double", "metatype:MetaData/OCD/AD[@id='raDouble']/@type");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='raString']/@type");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='raURI']/@type");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raBoolean']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raByte']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raCharacter']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raShort']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raInt']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raLong']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raFloat']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raDouble']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raString']/@cardinality");
xt.assertExactAttribute("2147483647", "metatype:MetaData/OCD/AD[@id='raURI']/@cardinality");
// Wrapper + Object collections
xt.assertExactAttribute("Boolean", "metatype:MetaData/OCD/AD[@id='rBooleans']/@type");
xt.assertExactAttribute("Byte", "metatype:MetaData/OCD/AD[@id='rBytes']/@type");
xt.assertExactAttribute("Char", "metatype:MetaData/OCD/AD[@id='rCharacter']/@type");
xt.assertExactAttribute("Short", "metatype:MetaData/OCD/AD[@id='rShorts']/@type");
xt.assertExactAttribute("Integer", "metatype:MetaData/OCD/AD[@id='rInts']/@type");
xt.assertExactAttribute("Long", "metatype:MetaData/OCD/AD[@id='rLongs']/@type");
xt.assertExactAttribute("Float", "metatype:MetaData/OCD/AD[@id='rFloats']/@type");
xt.assertExactAttribute("Double", "metatype:MetaData/OCD/AD[@id='rDoubles']/@type");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='rStrings']/@type");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='rURIs']/@type");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rBooleans']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rBytes']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rCharacters']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rShorts']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rInts']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rLongs']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rFloats']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rDoubles']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rStrings']/@cardinality");
xt.assertExactAttribute("-2147483648", "metatype:MetaData/OCD/AD[@id='rURIs']/@cardinality");
}
/**
* Test simple
*
* @author aqute
*/
@ObjectClassDefinition(description = "simple", name = "TestSimple", pid = {
"simplePid", "$"
})
public static interface TestSimple {
@AttributeDefinition
String simple();
String[] notSoSimple();
Collection<String> stringCollection();
@AttributeDefinition(defaultValue = {
"true"
}, required = false)
boolean enabled();
}
public void testSimple() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestSimple.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestSimple.xml");
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
testSimple(b, xt);
}
public void testSimple13() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestSimple.class.getName());
b.setProperty(Constants.METATYPE_ANNOTATIONS_OPTIONS, "version;minimum=1.3.0");
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestSimple.xml");
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester13(r);
testSimple(b, xt);
}
private void testSimple(Builder b, XmlTester xt) throws XPathExpressionException {
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
for (String res : b.getJar().getResources().keySet()) {
if (res.endsWith(".xml"))
System.err.println(res);
}
xt.assertExactAttribute("TestSimple", "metatype:MetaData/OCD/@name");
xt.assertExactAttribute("simple", "metatype:MetaData/OCD/@description");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$TestSimple", "metatype:MetaData/OCD/@id");
xt.assertExactAttribute("simplePid", "metatype:MetaData/Designate[1]/@pid");
xt.assertExactAttribute(TestSimple.class.getName(), "metatype:MetaData/Designate[2]/@pid");
xt.assertExactAttribute(TestSimple.class.getName(), "metatype:MetaData/Designate/Object/@ocdref");
xt.assertExactAttribute("simple", "metatype:MetaData/OCD/AD[@id='simple']/@id");
xt.assertExactAttribute("Simple", "metatype:MetaData/OCD/AD[@id='simple']/@name");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='simple']/@type");
xt.assertExactAttribute("false", "metatype:MetaData/OCD/AD[@id='enabled']/@required");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/AD[@id='enabled']/@default");
xt.assertExactAttribute(Integer.MAX_VALUE + "", "metatype:MetaData/OCD/AD[@id='notSoSimple']/@cardinality");
}
@ObjectClassDefinition
public static @interface AnnotationDefaults {
int integer() default 1;
int[] integers() default {
2, 3
};
boolean bool() default true;
boolean[] bools() default {
true, false
};
Class< ? > clazz() default String.class;
Class< ? >[] clazzs() default {
Integer.class, Double.class
};
enum L {
A, B, C
}
L l() default L.A;
L[] ls() default {
L.B, L.C
};
String string() default "foo";
String[] strings() default {
"bar", "baz"
};
}
public void testAnnotationDefaults() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, AnnotationDefaults.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$AnnotationDefaults.xml");
System.err.println(b.getErrors());
assertEquals(0, b.getErrors().size());
System.err.println(b.getWarnings());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
xt.assertExactAttribute("1", "metatype:MetaData/OCD/AD[@id='integer']/@default");
xt.assertExactAttribute("2,3", "metatype:MetaData/OCD/AD[@id='integers']/@default");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/AD[@id='bool']/@default");
xt.assertExactAttribute("true,false", "metatype:MetaData/OCD/AD[@id='bools']/@default");
xt.assertExactAttribute(String.class.getName(), "metatype:MetaData/OCD/AD[@id='clazz']/@default");
xt.assertExactAttribute(Integer.class.getName() + "," + Double.class.getName(),
"metatype:MetaData/OCD/AD[@id='clazzs']/@default");
xt.assertExactAttribute("A", "metatype:MetaData/OCD/AD[@id='l']/@default");
xt.assertExactAttribute("B,C", "metatype:MetaData/OCD/AD[@id='ls']/@default");
xt.assertExactAttribute("foo", "metatype:MetaData/OCD/AD[@id='string']/@default");
xt.assertExactAttribute("bar,baz", "metatype:MetaData/OCD/AD[@id='strings']/@default");
}
@ObjectClassDefinition
public static abstract class Abstract {
}
public void testAbstract() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, Abstract.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$Abstract.xml");
assertEquals(1, b.getErrors().size());
assertNull(r);
}
@ObjectClassDefinition
public static @interface NestedInner {
}
@ObjectClassDefinition
public static @interface NestedOuter {
NestedInner inner();
}
public void testNested() throws Exception {
{
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS,
NestedInner.class.getName() + "," + NestedOuter.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$NestedOuter.xml");
assertEquals(1, b.getErrors().size());
}
{
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS,
NestedInner.class.getName() + "," + NestedOuter.class.getName());
b.setProperty(Constants.METATYPE_ANNOTATIONS_OPTIONS, "nested");
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$NestedOuter.xml");
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='inner']/@type");
}
}
@ObjectClassDefinition
public static @interface DesignateOCD {
}
@Component(configurationPid = "simplePid")
@Designate(ocd = DesignateOCD.class, factory = true)
public static class DesignateComponent {}
@Component(name = "simplePidName")
@Designate(ocd = DesignateOCD.class, factory = true)
public static class DesignateComponent2 {}
@Component
@Designate(ocd = DesignateOCD.class, factory = true)
public static class DesignateComponent3 {}
@Component(configurationPid = "$")
@Designate(ocd = DesignateOCD.class, factory = true)
public static class DesignateComponent4 {}
public void testDesignate() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, "test.metatype.SpecMetatypeTest$Designate*");
b.setProperty(Constants.DSANNOTATIONS, "test.metatype.SpecMetatypeTest$Designate*");
b.build();
{
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$DesignateOCD.xml");
assertEquals(b.getErrors().toString(), 0, b.getErrors().size());
assertEquals(b.getWarnings().toString(), 0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester13(r);
xt.assertExactAttribute("Test metatype spec metatype test designate OCD", "metatype:MetaData/OCD/@name");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$DesignateOCD", "metatype:MetaData/OCD/@id");
xt.assertExactAttribute("simplePid", "metatype:MetaData/Designate[1]/@factoryPid");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$DesignateOCD",
"metatype:MetaData/Designate[1]/Object/@ocdref");
xt.assertExactAttribute("simplePidName", "metatype:MetaData/Designate[2]/@factoryPid");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$DesignateOCD",
"metatype:MetaData/Designate[2]/Object/@ocdref");
xt.assertExactAttribute(DesignateComponent3.class.getName(), "metatype:MetaData/Designate[3]/@factoryPid");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$DesignateOCD",
"metatype:MetaData/Designate[3]/Object/@ocdref");
xt.assertExactAttribute(DesignateComponent4.class.getName(), "metatype:MetaData/Designate[4]/@factoryPid");
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$DesignateOCD",
"metatype:MetaData/Designate[4]/Object/@ocdref");
}
}
@XMLAttribute(namespace = "org.foo.extensions.v1", prefix = "foo", embedIn = "*")
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@interface OCDTestExtensions {
boolean booleanAttr() default true;
String stringAttr();
Foo fooAttr();
String[] stringArrayAttr();
int[] intArrayAttr();
}
@XMLAttribute(namespace = "org.foo.extensions.v1", prefix = "foo", embedIn = "*")
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
@interface ADTestExtensions {
boolean booleanAttr2() default true;
String stringAttr2();
Foo fooAttr2();
Class< ? > classAttr2() default Object.class;
}
@ObjectClassDefinition
@OCDTestExtensions(stringAttr = "ocd", fooAttr = Foo.A, stringArrayAttr = {
"foo", "bar"
}, intArrayAttr = {
1, 2, 3
})
public static interface TestExtensions {
@AttributeDefinition
String simple();
@ADTestExtensions(stringAttr2 = "ad", fooAttr2 = Foo.B, classAttr2 = String.class)
String[] notSoSimple();
Collection<String> stringCollection();
@ADTestExtensions(stringAttr2 = "ad2", fooAttr2 = Foo.A)
@AttributeDefinition(defaultValue = {
"true"
}, required = false)
boolean enabled();
}
public void testExtensions() throws Exception {
MetatypeVersion version = MetatypeVersion.VERSION_1_2;
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, TestExtensions.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$TestExtensions.xml");
assertEquals(0, b.getErrors().size());
assertEquals("warnings: " + b.getWarnings(), 0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = new XmlTester(r.openInputStream(), "metatype", version.getNamespace(), "foo",
"org.foo.extensions.v1");
xt.assertNamespace(version.getNamespace());
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$TestExtensions", "metatype:MetaData/OCD/@id");
xt.assertExactAttribute("simple", "metatype:MetaData/OCD/AD[@id='simple']/@id");
xt.assertExactAttribute("Simple", "metatype:MetaData/OCD/AD[@id='simple']/@name");
xt.assertExactAttribute("String", "metatype:MetaData/OCD/AD[@id='simple']/@type");
xt.assertExactAttribute("false", "metatype:MetaData/OCD/AD[@id='enabled']/@required");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/AD[@id='enabled']/@default");
xt.assertExactAttribute(Integer.MAX_VALUE + "", "metatype:MetaData/OCD/AD[@id='notSoSimple']/@cardinality");
xt.assertCount(8, "metatype:MetaData/OCD/@*");
xt.assertExactAttribute("ocd", "metatype:MetaData/OCD/@foo:stringAttr");
xt.assertExactAttribute("A", "metatype:MetaData/OCD/@foo:fooAttr");
xt.assertExactAttribute("foo bar", "metatype:MetaData/OCD/@foo:stringArrayAttr");
xt.assertExactAttribute("1 2 3", "metatype:MetaData/OCD/@foo:intArrayAttr");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/@foo:booleanAttr");
xt.assertCount(3, "metatype:MetaData/OCD/AD[@id='simple']/@*");
xt.assertCount(8, "metatype:MetaData/OCD/AD[@id='notSoSimple']/@*");
xt.assertExactAttribute("ad", "metatype:MetaData/OCD/AD[@id='notSoSimple']/@foo:stringAttr2");
xt.assertExactAttribute("B", "metatype:MetaData/OCD/AD[@id='notSoSimple']/@foo:fooAttr2");
xt.assertExactAttribute(String.class.getName(), "metatype:MetaData/OCD/AD[@id='notSoSimple']/@foo:classAttr2");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/AD[@id='notSoSimple']/@foo:booleanAttr2");
xt.assertCount(4, "metatype:MetaData/OCD/AD[@id='stringCollection']/@*");
xt.assertCount(9, "metatype:MetaData/OCD/AD[@id='enabled']/@*");
xt.assertExactAttribute("ad2", "metatype:MetaData/OCD/AD[@id='enabled']/@foo:stringAttr2");
xt.assertExactAttribute("A", "metatype:MetaData/OCD/AD[@id='enabled']/@foo:fooAttr2");
xt.assertExactAttribute(Object.class.getName(), "metatype:MetaData/OCD/AD[@id='enabled']/@foo:classAttr2");
xt.assertExactAttribute("true", "metatype:MetaData/OCD/AD[@id='enabled']/@foo:booleanAttr2");
}
@XMLAttribute(namespace = "org.foo.extensions.v1", prefix = "foo", embedIn = "*", mapping = {
"value=simple"
})
@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.TYPE, ElementType.METHOD
})
@interface Simple {
String value() default "default";
}
@Simple
@ObjectClassDefinition
@interface SimpleConfig {
@Simple("value")
@AttributeDefinition
String[] property();
}
public void testSimpleExtensions() throws Exception {
MetatypeVersion version = MetatypeVersion.VERSION_1_2;
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, SimpleConfig.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$SimpleConfig.xml");
assertEquals(0, b.getErrors().size());
assertEquals("warnings: " + b.getWarnings(), 0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = new XmlTester(r.openInputStream(), "metatype", version.getNamespace(), "foo",
"org.foo.extensions.v1");
xt.assertNamespace(version.getNamespace());
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$SimpleConfig", "metatype:MetaData/OCD/@id");
xt.assertCount(4, "metatype:MetaData/OCD/@*");
xt.assertExactAttribute("default", "metatype:MetaData/OCD/@foo:simple");
xt.assertCount(5, "metatype:MetaData/OCD/AD[@id='property']/@*");
xt.assertExactAttribute("value", "metatype:MetaData/OCD/AD[@id='property']/@foo:simple");
}
@XMLAttribute(namespace = "org.foo.extensions.v1", prefix = "foo", embedIn = "*", mapping = {
"a=first", "b=second"
})
@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.TYPE, ElementType.METHOD
})
@interface Mapping {
String a() default "A";
String b() default "B";
}
@Mapping
@ObjectClassDefinition
@interface MappingConfig {
@Mapping(a = "one", b = "two")
@AttributeDefinition
String[] property();
}
public void testMappingExtensions() throws Exception {
MetatypeVersion version = MetatypeVersion.VERSION_1_2;
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, MappingConfig.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$MappingConfig.xml");
assertEquals(0, b.getErrors().size());
assertEquals("warnings: " + b.getWarnings(), 0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = new XmlTester(r.openInputStream(), "metatype", version.getNamespace(), "foo",
"org.foo.extensions.v1");
xt.assertNamespace(version.getNamespace());
xt.assertExactAttribute("test.metatype.SpecMetatypeTest$MappingConfig", "metatype:MetaData/OCD/@id");
xt.assertCount(5, "metatype:MetaData/OCD/@*");
xt.assertExactAttribute("A", "metatype:MetaData/OCD/@foo:first");
xt.assertExactAttribute("B", "metatype:MetaData/OCD/@foo:second");
xt.assertCount(6, "metatype:MetaData/OCD/AD[@id='property']/@*");
xt.assertExactAttribute("one", "metatype:MetaData/OCD/AD[@id='property']/@foo:first");
xt.assertExactAttribute("two", "metatype:MetaData/OCD/AD[@id='property']/@foo:second");
}
@ObjectClassDefinition
@interface Escapes {
@AttributeDefinition(defaultValue = {
" , \\", "a,b", "c,d", "'apostrophe'", "\"quote\"&"
})
String[] escapes();
}
public void testEscapes() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, Escapes.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$Escapes.xml");
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
System.err.println(b.getJar().getResources().keySet());
assertNotNull(r);
IO.copy(r.openInputStream(), System.err);
XmlTester xt = xmlTester12(r);
assertAD(xt, "escapes", "Escapes", null, null, "\\ \\,\\ \\\\,a\\,b,c\\,d,'apostrophe',\"quote\"&",
2147483647, "String", null, null, null);
}
@Mapping
@Meta.OCD
static interface C {
@Meta.AD(required = false)
Integer port();
}
// cf issue 1130
public void testBndAnnoCompatible() throws Exception {
Builder b = new Builder();
b.addClasspath(new File("bin"));
b.setProperty("Export-Package", "test.metatype");
b.setProperty(Constants.METATYPE_ANNOTATIONS, C.class.getName());
b.build();
Resource r = b.getJar().getResource("OSGI-INF/metatype/test.metatype.SpecMetatypeTest$C.xml");
assertEquals(0, b.getErrors().size());
assertEquals(0, b.getWarnings().size());
assertNull(r);
}
}