/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.aries.blueprint.container;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Constructor;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import junit.framework.TestCase;
import org.apache.aries.blueprint.TestBlueprintContainer;
import org.apache.aries.blueprint.pojos.PojoGenerics2.MyClass;
import org.apache.aries.blueprint.pojos.PojoGenerics2.MyObject;
import org.apache.aries.blueprint.pojos.PojoGenerics2.Tata;
import org.apache.aries.blueprint.pojos.PojoGenerics2.Toto;
import org.osgi.service.blueprint.container.ReifiedType;
import org.osgi.service.blueprint.container.Converter;
public class AggregateConverterTest extends TestCase {
private AggregateConverter service;
protected void setUp() throws Exception {
service = new AggregateConverter(new TestBlueprintContainer(null));
}
public void testConvertNumbers() throws Exception {
assertEquals(1, service.convert(1.46f, int.class));
assertEquals(1.0d, service.convert(1, double.class));
}
public void testConvertSimpleTypes() throws Exception {
assertEquals(123, service.convert("123", int.class));
assertEquals(123, service.convert("123", Integer.class));
assertEquals(123l, service.convert("123", long.class));
assertEquals(123l, service.convert("123", Long.class));
assertEquals((short) 123, service.convert("123", short.class));
assertEquals((short) 123, service.convert("123", Short.class));
assertEquals(1.5f, service.convert("1.5", float.class));
assertEquals(1.5f, service.convert("1.5", Float.class));
assertEquals(1.5, service.convert("1.5", double.class));
assertEquals(1.5, service.convert("1.5", Double.class));
}
public void testConvertCharacter() throws Exception {
assertEquals('c', service.convert("c", char.class));
assertEquals('c', service.convert("c", Character.class));
assertEquals('\u00F6', service.convert("\\u00F6", char.class));
assertEquals('\u00F6', service.convert("\\u00F6", Character.class));
}
public void testConvertBoolean() throws Exception {
assertEquals(Boolean.TRUE, service.convert("true", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("yes", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("on", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("TRUE", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("YES", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("ON", Boolean.class));
assertEquals(Boolean.TRUE, service.convert("true", boolean.class));
assertEquals(Boolean.TRUE, service.convert("yes", boolean.class));
assertEquals(Boolean.TRUE, service.convert("on", boolean.class));
assertEquals(Boolean.TRUE, service.convert("TRUE", boolean.class));
assertEquals(Boolean.TRUE, service.convert("YES", boolean.class));
assertEquals(Boolean.TRUE, service.convert("ON", boolean.class));
assertEquals(Boolean.FALSE, service.convert("false", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("no", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("off", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("FALSE", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("NO", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("OFF", Boolean.class));
assertEquals(Boolean.FALSE, service.convert("false", boolean.class));
assertEquals(Boolean.FALSE, service.convert("no", boolean.class));
assertEquals(Boolean.FALSE, service.convert("off", boolean.class));
assertEquals(Boolean.FALSE, service.convert("FALSE", boolean.class));
assertEquals(Boolean.FALSE, service.convert("NO", boolean.class));
assertEquals(Boolean.FALSE, service.convert("OFF", boolean.class));
assertEquals(Boolean.FALSE, service.convert(false, boolean.class));
assertEquals(Boolean.TRUE, service.convert(true, boolean.class));
assertEquals(Boolean.FALSE, service.convert(false, Boolean.class));
assertEquals(Boolean.TRUE, service.convert(true, Boolean.class));
}
public void testConvertOther() throws Exception {
assertEquals(URI.create("urn:test"), service.convert("urn:test", URI.class));
assertEquals(new URL("file:/test"), service.convert("file:/test", URL.class));
assertEquals(new BigInteger("12345"), service.convert("12345", BigInteger.class));
}
public void testConvertProperties() throws Exception {
Properties props = new Properties();
props.setProperty("key", "value");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.store(baos, null);
props = (Properties) service.convert(baos.toString(), Properties.class);
assertEquals(1, props.size());
assertEquals("value", props.getProperty("key"));
}
public void testConvertLocale() throws Exception {
Object result;
result = service.convert("en", Locale.class);
assertTrue(result instanceof Locale);
assertEquals(new Locale("en"), result);
result = service.convert("de_DE", Locale.class);
assertTrue(result instanceof Locale);
assertEquals(new Locale("de", "DE"), result);
result = service.convert("_GB", Locale.class);
assertTrue(result instanceof Locale);
assertEquals(new Locale("", "GB"), result);
result = service.convert("en_US_WIN", Locale.class);
assertTrue(result instanceof Locale);
assertEquals(new Locale("en", "US", "WIN"), result);
result = service.convert("de__POSIX", Locale.class);
assertTrue(result instanceof Locale);
assertEquals(new Locale("de", "", "POSIX"), result);
}
public void testConvertClass() throws Exception {
assertEquals(this, service.convert(this, AggregateConverterTest.class));
assertEquals(AggregateConverterTest.class, service.convert(this.getClass().getName(), Class.class));
assertEquals(int[].class, service.convert("int[]", Class.class));
assertEquals(RegionIterable.class, service.convert(RegionIterable.class.getName(), new GenericType(Class.class, new GenericType(RegionIterable.class))));
assertTrue(AggregateConverter.isAssignable(RegionIterable.class, new GenericType(Class.class, new GenericType(RegionIterable.class))));
}
public void testConvertArray() throws Exception {
Object obj = service.convert(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4)),
GenericType.parse("java.util.List<java.lang.Integer>[]", getClass().getClassLoader()));
assertNotNull(obj);
assertTrue(obj.getClass().isArray());
Object[] o = (Object[]) obj;
assertEquals(2, o.length);
assertNotNull(o[0]);
assertTrue(o[0] instanceof List);
assertEquals(2, ((List) o[0]).size());
assertEquals(1, ((List) o[0]).get(0));
assertEquals(2, ((List) o[0]).get(1));
assertNotNull(o[0]);
assertTrue(o[1] instanceof List);
assertEquals(2, ((List) o[1]).size());
assertEquals(3, ((List) o[1]).get(0));
assertEquals(4, ((List) o[1]).get(1));
//assertEquals((Object) new int[] { 1, 2 }, (Object) service.convert(Arrays.asList(1, 2), int[].class));
}
public void testCustom() throws Exception {
AggregateConverter s = new AggregateConverter(new TestBlueprintContainer(null));
s.registerConverter(new RegionConverter());
s.registerConverter(new EuRegionConverter());
// lookup on a specific registered converter type
Object result;
result = s.convert(new Object(), Region.class);
assertTrue(result instanceof Region);
assertFalse(result instanceof EuRegion);
result = s.convert(new Object(), EuRegion.class);
assertTrue(result instanceof EuRegion);
// find first converter that matches the type
s = new AggregateConverter(new TestBlueprintContainer(null));
s.registerConverter(new AsianRegionConverter());
s.registerConverter(new EuRegionConverter());
s.registerConverter(new NullMarkerConverter());
result = s.convert(new Object(), Region.class);
// TODO: check with the spec about the result
//assertTrue(result instanceof AsianRegion || result instanceof EuRegion);
result = s.convert(new Object(), NullMarker.class);
assertNull(result);
}
public void testGenericWilcard() throws Exception {
Constructor cns = MyClass.class.getConstructor(MyObject.class);
assertTrue(AggregateConverter.isAssignable(new Toto(), new GenericType(cns.getGenericParameterTypes()[0])));
cns = Tata.class.getConstructor(MyObject.class);
assertTrue(AggregateConverter.isAssignable(new Toto(), new GenericType(cns.getGenericParameterTypes()[0])));
}
public void testGenericAssignable() throws Exception {
AggregateConverter s = new AggregateConverter(new TestBlueprintContainer(null));
assertNotNull(s.convert(new RegionIterable(), new GenericType(Iterable.class, new GenericType(Region.class))));
try {
s.convert(new ArrayList<Region>(), new GenericType(Iterable.class, new GenericType(Region.class)));
fail("Conversion should have thrown an exception");
} catch (Exception e) {
// Ignore
}
assertTrue(Iterable.class.isAssignableFrom(RegionIterable.class));
// note that method signature is fromType, toType - reverse than above
assertTrue("Type should be assignable.", AggregateConverter.isTypeAssignable(new GenericType(RegionIterable.class), new GenericType(Iterable.class)));
}
public void testGenericCollection() throws Exception {
AggregateConverter s = new AggregateConverter(new TestBlueprintContainer(null));
try {
s.convert(new ArrayList(), new GenericType(Iterable.class, new GenericType(Region.class)));
fail("Conversion should have thrown an exception");
} catch (Exception e) {
// Ignore
}
try {
s.convert(Arrays.asList(0l), new GenericType(Iterable.class, new GenericType(Region.class)));
fail("Conversion should have thrown an exception");
} catch (Exception e) {
// Ignore
}
assertNotNull(s.convert(Arrays.asList(new EuRegion() {}), new GenericType(List.class, new GenericType(Region.class))));
}
public void testConvertCompatibleCollections() throws Exception {
Object org = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));
Object obj = service.convert(org,
GenericType.parse("java.util.List<java.util.List<java.lang.Integer>>", getClass().getClassLoader()));
assertSame(org, obj);
org = Collections.singletonMap("foo", 1);
obj = service.convert(org,
GenericType.parse("java.util.Map<java.lang.String,java.lang.Integer>", getClass().getClassLoader()));
assertSame(org, obj);
org = new int[] { 1, 2 };
obj = service.convert(org,
GenericType.parse("int[]", getClass().getClassLoader()));
assertSame(org, obj);
org = new Object[] { 1, 2 };
obj = service.convert(org,
GenericType.parse("int[]", getClass().getClassLoader()));
assertNotSame(org, obj);
Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
ht.put("foo", 1);
org = ht;
obj = service.convert(org, GenericType.parse("java.util.Dictionary<java.lang.String,java.lang.Integer>", getClass().getClassLoader()));
assertSame(org, obj);;
}
private interface Region {}
private interface EuRegion extends Region {}
private interface AsianRegion extends Region {}
private interface NullMarker {}
private static class RegionConverter implements Converter {
public boolean canConvert(Object fromValue, ReifiedType toType) {
return Region.class == toType.getRawClass();
}
public Object convert(Object source, ReifiedType toType) throws Exception {
return new Region() {} ;
}
}
private static class EuRegionConverter implements Converter {
public boolean canConvert(Object fromValue, ReifiedType toType) {
return toType.getRawClass().isAssignableFrom(EuRegion.class);
}
public Object convert(Object source, ReifiedType toType) throws Exception {
return new EuRegion() {} ;
}
}
private static class AsianRegionConverter implements Converter {
public boolean canConvert(Object fromValue, ReifiedType toType) {
return toType.getRawClass().isAssignableFrom(AsianRegion.class);
}
public Object convert(Object source, ReifiedType toType) throws Exception {
return new AsianRegion() {} ;
}
}
private static class NullMarkerConverter implements Converter {
public boolean canConvert(Object fromValue, ReifiedType toType) {
return toType.getRawClass().isAssignableFrom(NullMarker.class);
}
public Object convert(Object source, ReifiedType toType) throws Exception {
return null;
}
}
private static class RegionIterable implements Iterable<Region> {
public Iterator<Region> iterator() {
return null;
}
}
}