/*
* 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;
import java.math.BigInteger;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import junit.framework.Assert;
import org.apache.aries.blueprint.CallbackTracker.Callback;
import org.apache.aries.blueprint.container.BlueprintRepository;
import org.apache.aries.blueprint.di.CircularDependencyException;
import org.apache.aries.blueprint.di.Repository;
import org.apache.aries.blueprint.namespace.ComponentDefinitionRegistryImpl;
import org.apache.aries.blueprint.pojos.BeanD;
import org.apache.aries.blueprint.pojos.BeanF;
import org.apache.aries.blueprint.pojos.FITestBean;
import org.apache.aries.blueprint.pojos.Multiple;
import org.apache.aries.blueprint.pojos.PojoA;
import org.apache.aries.blueprint.pojos.PojoB;
import org.apache.aries.blueprint.pojos.PojoGenerics;
import org.apache.aries.blueprint.pojos.PojoListener;
import org.apache.aries.blueprint.pojos.PojoRecursive;
import org.apache.aries.blueprint.pojos.Primavera;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.blueprint.container.ComponentDefinitionException;
public class WiringTest extends AbstractBlueprintTest {
public void testWiring() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-wiring.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
Object obj1 = repository.create("pojoA");
assertNotNull(obj1);
assertTrue(obj1 instanceof PojoA);
PojoA pojoa = (PojoA) obj1;
// test singleton scope
assertTrue(obj1 == repository.create("pojoA"));
Object obj2 = repository.create("pojoB");
assertNotNull(obj2);
assertTrue(obj2 instanceof PojoB);
PojoB pojob = (PojoB) obj2;
assertNotNull(pojoa.getPojob());
assertNotNull(pojoa.getPojob().getUri());
assertNotNull(pojoa.getList());
assertEquals("list value", pojoa.getList().get(0));
assertEquals(new Integer(55), pojoa.getList().get(2));
assertEquals(URI.create("http://geronimo.apache.org"), pojoa.getList().get(3));
Object c0 = pojoa.getList().get(1);
Object c1 = pojoa.getList().get(4);
assertNotNull(c0);
assertNotNull(c1);
assertEquals(PojoB.class, c0.getClass());
assertEquals(PojoB.class, c1.getClass());
assertNotSame(c0, c1);
assertNotNull(pojoa.getArray());
assertEquals("list value", pojoa.getArray()[0]);
assertEquals(pojob, pojoa.getArray()[1]);
assertEquals(new Integer(55), pojoa.getArray()[2]);
assertEquals(URI.create("http://geronimo.apache.org"), pojoa.getArray()[3]);
assertNotNull(pojoa.getSet());
assertTrue(pojoa.getSet().contains("set value"));
assertTrue(pojoa.getSet().contains(pojob));
assertTrue(pojoa.getSet().contains(URI.create("http://geronimo.apache.org")));
assertNotNull(pojoa.getMap());
assertEquals("val", pojoa.getMap().get("key"));
assertEquals(pojob, pojoa.getMap().get(pojob));
assertEquals(URI.create("http://geronimo.apache.org"), pojoa.getMap().get(new Integer(5)));
assertNotNull(pojoa.getProps());
assertEquals("value1", pojoa.getProps().get("key1"));
assertEquals("value2", pojoa.getProps().get("2"));
assertEquals("bar", pojoa.getProps().get("foo"));
assertNotNull(pojoa.getNumber());
assertEquals(new BigInteger("10"), pojoa.getNumber());
assertNotNull(pojoa.getIntArray());
assertEquals(3, pojoa.getIntArray().length);
assertEquals(1, pojoa.getIntArray()[0]);
assertEquals(50, pojoa.getIntArray()[1]);
assertEquals(100, pojoa.getIntArray()[2]);
assertNotNull(pojoa.getNumberArray());
assertEquals(4, pojoa.getNumberArray().length);
assertEquals(new Integer(1), pojoa.getNumberArray()[0]);
assertEquals(new BigInteger("50"), pojoa.getNumberArray()[1]);
assertEquals(new Long(100), pojoa.getNumberArray()[2]);
assertEquals(new Integer(200), pojoa.getNumberArray()[3]);
// test init-method
assertEquals(true, pojob.getInitCalled());
// test service
Object obj3 = repository.create("service1");
assertNotNull(obj3);
assertTrue(obj3 instanceof ServiceRegistration);
// tests 'prototype' scope
Object obj4 = repository.create("pojoC");
assertNotNull(obj4);
assertTrue(obj4 != repository.create("pojoC"));
repository.destroy();
// test destroy-method
assertEquals(true, pojob.getDestroyCalled());
}
public void testFieldInjection() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-wiring.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
Object fiTestBean = repository.create("FITestBean");
assertNotNull(fiTestBean);
assertTrue(fiTestBean instanceof FITestBean);
FITestBean bean = (FITestBean) fiTestBean;
// single field injection
assertEquals("value", bean.getAttr());
// prefer setter injection to field injection
assertEquals("IS_LOWER", bean.getUpperCaseAttr());
// support cascaded injection 'bean.name' via fields
assertEquals("aName", bean.getBeanName());
// fail if field-injection is not specified
try {
repository.create("FIFailureTestBean");
Assert.fail("Expected exception");
} catch (ComponentDefinitionException cde) {}
// fail if field-injection is false
try {
repository.create("FIFailureTest2Bean");
Assert.fail("Expected exception");
} catch (ComponentDefinitionException cde) {}
}
public void testCompoundProperties() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-wiring.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
Object obj5 = repository.create("compound");
assertNotNull(obj5);
assertTrue(obj5 instanceof PojoB);
PojoB pojob = (PojoB) obj5;
assertEquals("hello bean property", pojob.getBean().getName());
Object obj = repository.create("goodIdRef");
assertNotNull(obj);
assertTrue(obj instanceof BeanD);
BeanD bean = (BeanD) obj;
assertEquals("pojoA", bean.getName());
}
public void testIdRefs() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-bad-id-ref.xml");
try {
new TestBlueprintContainer(registry).getRepository();
fail("Did not throw exception");
} catch (RuntimeException e) {
// we expect exception
// TODO: check error string?
}
}
public void testDependencies() throws Exception {
CallbackTracker.clear();
ComponentDefinitionRegistryImpl registry = parse("/test-depends-on.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
Map instances = repository.createAll(Arrays.asList("c", "d", "e"));
List<Callback> callback = CallbackTracker.getCallbacks();
assertEquals(3, callback.size());
checkInitCallback(instances.get("d"), callback.get(0));
checkInitCallback(instances.get("c"), callback.get(1));
checkInitCallback(instances.get("e"), callback.get(2));
repository.destroy();
assertEquals(6, callback.size());
checkDestroyCallback(instances.get("e"), callback.get(3));
checkDestroyCallback(instances.get("c"), callback.get(4));
checkDestroyCallback(instances.get("d"), callback.get(5));
}
private void checkInitCallback(Object obj, Callback callback) {
assertEquals(Callback.INIT, callback.getType());
assertEquals(obj, callback.getObject());
}
private void checkDestroyCallback(Object obj, Callback callback) {
assertEquals(Callback.DESTROY, callback.getType());
assertEquals(obj, callback.getObject());
}
public void testConstructor() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-constructor.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
Object obj1 = repository.create("pojoA");
assertNotNull(obj1);
assertTrue(obj1 instanceof PojoA);
PojoA pojoa = (PojoA) obj1;
Object obj2 = repository.create("pojoB");
testPojoB(obj2, URI.create("urn:myuri"), 10);
assertEquals(obj2, pojoa.getPojob());
assertEquals(new BigInteger("10"), pojoa.getNumber());
Object obj3 = repository.create("pojoC");
testPojoB(obj3, URI.create("urn:myuri-static"), 15);
Object obj4 = repository.create("pojoD");
testPojoB(obj4, URI.create("urn:myuri-static"), 15);
Object obj5 = repository.create("pojoE");
testPojoB(obj5, URI.create("urn:myuri-dynamic"), 20);
Object obj6 = repository.create("multipleInt");
testMultiple(obj6, null, 123, null);
Object obj7 = repository.create("multipleInteger");
testMultiple(obj7, null, -1, new Integer(123));
Object obj8 = repository.create("multipleString");
testMultiple(obj8, "123", -1, null);
// TODO: check the below tests when the incoherence between TCK / spec is solved
// try {
// graph.create("multipleStringConvertable");
// fail("Did not throw exception");
// } catch (RuntimeException e) {
// // we expect exception
// }
Object obj10 = repository.create("multipleFactory1");
testMultiple(obj10, null, 1234, null);
Object obj11 = repository.create("multipleFactory2");
testMultiple(obj11, "helloCreate-boolean", -1, null);
try {
repository.create("multipleFactoryNull");
fail("Did not throw exception");
} catch (RuntimeException e) {
// we expect exception
// TODO: check the exception string?
}
Object obj12 = repository.create("multipleFactoryTypedNull");
testMultiple(obj12, "hello-boolean", -1, null);
// TODO: check the below tests when the incoherence between TCK / spec is solved
// Object obj13 = graph.create("mapConstruction");
// Object obj14 = graph.create("propsConstruction");
BeanF obj15 = (BeanF) repository.create("booleanWrapped");
assertNotNull(obj15.getWrapped());
assertEquals(false, (boolean) obj15.getWrapped());
assertNull(obj15.getPrim());
// TODO: check the below tests when the incoherence between TCK / spec is solved
// BeanF obj16 = (BeanF) graph.create("booleanPrim");
// assertNotNull(obj16.getPrim());
// assertEquals(false, (boolean) obj16.getPrim());
// assertNull(obj16.getWrapped());
}
private void testPojoB(Object obj, URI uri, int intValue) {
assertNotNull(obj);
assertTrue(obj instanceof PojoB);
PojoB pojob = (PojoB) obj;
assertEquals(uri, pojob.getUri());
assertEquals(intValue, pojob.getNumber());
}
private void testMultiple(Object obj, String stringValue, int intValue, Integer integerValue) {
assertNotNull(obj);
assertTrue(obj instanceof Multiple);
assertEquals(intValue, ((Multiple)obj).getInt());
assertEquals(stringValue, ((Multiple)obj).getString());
assertEquals(integerValue, ((Multiple)obj).getInteger());
}
public void testGenerics() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-generics.xml");
Repository repository = new TestBlueprintContainer(registry).getRepository();
List<Integer> expectedList = new ArrayList<Integer>();
expectedList.add(new Integer(10));
expectedList.add(new Integer(20));
expectedList.add(new Integer(50));
Set<Long> expectedSet = new HashSet<Long>();
expectedSet.add(new Long(1000));
expectedSet.add(new Long(2000));
expectedSet.add(new Long(5000));
Map<Short, Boolean> expectedMap = new HashMap<Short, Boolean>();
expectedMap.put(new Short((short)1), Boolean.TRUE);
expectedMap.put(new Short((short)2), Boolean.FALSE);
expectedMap.put(new Short((short)5), Boolean.TRUE);
Object obj;
PojoGenerics pojo;
obj = repository.create("method");
assertTrue(obj instanceof PojoGenerics);
pojo = (PojoGenerics) obj;
assertEquals(expectedList, pojo.getList());
assertEquals(expectedSet, pojo.getSet());
assertEquals(expectedMap, pojo.getMap());
obj = repository.create("constructorList");
assertTrue(obj instanceof PojoGenerics);
pojo = (PojoGenerics) obj;
assertEquals(expectedList, pojo.getList());
obj = repository.create("constructorSet");
assertTrue(obj instanceof PojoGenerics);
pojo = (PojoGenerics) obj;
assertEquals(expectedSet, pojo.getSet());
obj = repository.create("constructorMap");
assertTrue(obj instanceof PojoGenerics);
pojo = (PojoGenerics) obj;
assertEquals(expectedMap, pojo.getMap());
obj = repository.create("genericPojo");
assertTrue(obj instanceof Primavera);
assertEquals("string", ((Primavera) obj).prop);
obj = repository.create("doubleGenericPojo");
assertTrue(obj instanceof Primavera);
assertEquals("stringToo", ((Primavera) obj).prop);
}
public void testCircular() throws Exception {
BlueprintRepository repository = createBlueprintContainer().getRepository();
// this should pass (we allow circular dependencies for components without init method)
Object obj1 = repository.create("a");
// test service and listener circular dependencies
Object obj2 = repository.create("service");
assertNotNull(obj2);
assertTrue(obj2 instanceof ServiceRegistration);
Object obj3 = repository.create("listener");
assertNotNull(obj3);
assertTrue(obj3 instanceof PojoListener);
assertEquals(obj2, ((PojoListener) obj3).getService() );
}
public void testCircularPrototype() throws Exception {
BlueprintRepository repository = createBlueprintContainer().getRepository();
try {
repository.create("circularPrototypeDriver");
fail("Did not throw exception");
} catch (CircularDependencyException e) {
// that's what we expect
}
try {
repository.create("circularPrototype");
fail("Did not throw exception");
} catch (CircularDependencyException e) {
// that's what we expect
}
}
public void testRecursive() throws Exception {
BlueprintRepository repository = createBlueprintContainer().getRepository();
try {
repository.create("recursiveConstructor");
fail("Did not throw exception");
} catch (ComponentDefinitionException e) {
if (e.getCause() instanceof CircularDependencyException) {
// that's what we expect
} else {
fail("Did not throw expected exception");
throw e;
}
}
PojoRecursive pojo;
pojo = (PojoRecursive) repository.create("recursiveSetter");
assertNotNull(pojo);
pojo = (PojoRecursive) repository.create("recursiveInitMethod");
assertNotNull(pojo);
}
public void testCircularBreaking() throws Exception {
BlueprintRepository repository;
repository = createBlueprintContainer().getRepository();
assertNotNull(repository.create("c1"));
repository = createBlueprintContainer().getRepository();
assertNotNull(repository.create("c2"));
repository = createBlueprintContainer().getRepository();
assertNotNull(repository.create("c3"));
}
private TestBlueprintContainer createBlueprintContainer() throws Exception {
ComponentDefinitionRegistryImpl registry = parse("/test-circular.xml");
return new TestBlueprintContainer(registry);
}
}