You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by zo...@apache.org on 2011/02/27 22:21:22 UTC
svn commit: r1075149 [18/23] - in /aries/tags/blueprint-0.3.1: ./
blueprint-annotation-api/ blueprint-annotation-api/src/
blueprint-annotation-api/src/main/ blueprint-annotation-api/src/main/java/
blueprint-annotation-api/src/main/java/org/ blueprint-a...
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,580 @@
+/**
+ * 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.utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.container.GenericType;
+import org.apache.aries.blueprint.di.ExecutionContext;
+import org.osgi.framework.BundleReference;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+
+/**
+ * TODO: javadoc
+ *
+ * @version $Rev: 1055827 $, $Date: 2011-01-06 11:03:36 +0000 (Thu, 06 Jan 2011) $
+ */
+public class ReflectionUtils {
+
+ // TODO: MLK: PropertyDescriptor holds a reference to Method which holds a reference to the Class itself
+ private static Map<Class<?>, PropertyDescriptor[][]> beanInfos = Collections.synchronizedMap(new WeakHashMap<Class<?>, PropertyDescriptor[][]>());
+
+ public static boolean hasDefaultConstructor(Class type) {
+ if (!Modifier.isPublic(type.getModifiers())) {
+ return false;
+ }
+ if (Modifier.isAbstract(type.getModifiers())) {
+ return false;
+ }
+ Constructor[] constructors = type.getConstructors();
+ for (Constructor constructor : constructors) {
+ if (Modifier.isPublic(constructor.getModifiers()) &&
+ constructor.getParameterTypes().length == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Set<String> getImplementedInterfaces(Set<String> classes, Class clazz) {
+ if (clazz != null && clazz != Object.class) {
+ for (Class itf : clazz.getInterfaces()) {
+ if (Modifier.isPublic(itf.getModifiers())) {
+ classes.add(itf.getName());
+ }
+ getImplementedInterfaces(classes, itf);
+ }
+ getImplementedInterfaces(classes, clazz.getSuperclass());
+ }
+ return classes;
+ }
+
+ public static Set<String> getSuperClasses(Set<String> classes, Class clazz) {
+ if (clazz != null && clazz != Object.class) {
+ if (Modifier.isPublic(clazz.getModifiers())) {
+ classes.add(clazz.getName());
+ }
+ getSuperClasses(classes, clazz.getSuperclass());
+ }
+ return classes;
+ }
+
+ public static Method getLifecycleMethod(Class clazz, String name) {
+ if (name != null) {
+ try {
+ Method method = clazz.getMethod(name);
+ if (Void.TYPE.equals(method.getReturnType())) {
+ return method;
+ }
+ } catch (NoSuchMethodException e) {
+ // fall thru
+ }
+ }
+ return null;
+ }
+
+ public static List<Method> findCompatibleMethods(Class clazz, String name, Class[] paramTypes) {
+ List<Method> methods = new ArrayList<Method>();
+ for (Method method : clazz.getMethods()) {
+ Class[] methodParams = method.getParameterTypes();
+ if (name.equals(method.getName()) && Void.TYPE.equals(method.getReturnType()) && methodParams.length == paramTypes.length && !method.isBridge()) {
+ boolean assignable = true;
+ for (int i = 0; i < paramTypes.length && assignable; i++) {
+ assignable &= paramTypes[i] == null || methodParams[i].isAssignableFrom(paramTypes[i]);
+ }
+ if (assignable) {
+ methods.add(method);
+ }
+ }
+ }
+ return methods;
+ }
+
+ public static PropertyDescriptor[] getPropertyDescriptors(Class clazz, boolean allowFieldInjection) {
+ PropertyDescriptor[][] properties = beanInfos.get(clazz);
+ int index = allowFieldInjection ? 0 : 1;
+
+ if (properties == null) {
+ properties = new PropertyDescriptor[2][];
+ beanInfos.put(clazz, properties);
+ }
+
+ if (properties[index] == null) {
+ Set<String> propertyNames = new HashSet<String>();
+ Map<String,Method> getters = new HashMap<String, Method>();
+ Map<String,List<Method>> setters = new HashMap<String, List<Method>>();
+ Set<String> illegalProperties = new HashSet<String>();
+
+ for (Method method : clazz.getMethods()) {
+ if (Modifier.isStatic(method.getModifiers()) || method.isBridge()) continue;
+
+ String name = method.getName();
+ Class<?> argTypes[] = method.getParameterTypes();
+ Class<?> resultType = method.getReturnType();
+
+ if (name.length() > 3 && name.startsWith("set") && resultType == Void.TYPE && argTypes.length == 1) {
+ name = decapitalize(name.substring(3));
+ if (!!!setters.containsKey(name)) setters.put(name, new ArrayList<Method>());
+ setters.get(name).add(method);
+ propertyNames.add(name);
+ } else if (name.length() > 3 && name.startsWith("get") && resultType != Void.TYPE && argTypes.length == 0) {
+ name = decapitalize(name.substring(3));
+
+ if (getters.containsKey(name)) illegalProperties.add(name);
+ else propertyNames.add(name);
+
+ getters.put(name, method);
+ } else if (name.length() > 2 && name.startsWith("is") && argTypes.length == 0 && resultType == boolean.class) {
+ name = decapitalize(name.substring(2));
+
+ if (getters.containsKey(name)) illegalProperties.add(name);
+ else propertyNames.add(name);
+
+ getters.put(name, method);
+ }
+
+ }
+
+ Map<String, PropertyDescriptor> props = new HashMap<String, PropertyDescriptor>();
+ for (String propName : propertyNames) {
+ props.put(propName,
+ new MethodPropertyDescriptor(propName, getters.get(propName), setters.get(propName)));
+ }
+
+ if (allowFieldInjection) {
+ for (Class cl = clazz; cl != null && cl != Object.class; cl = cl.getSuperclass()) {
+ for (Field field : cl.getDeclaredFields()) {
+ if (!!!Modifier.isStatic(field.getModifiers())) {
+ String name = decapitalize(field.getName());
+ PropertyDescriptor desc = props.get(name);
+ if (desc == null) {
+ props.put(name, new FieldPropertyDescriptor(name, field));
+ } else if (desc instanceof MethodPropertyDescriptor) {
+ props.put(name,
+ new JointPropertyDescriptor((MethodPropertyDescriptor) desc,
+ new FieldPropertyDescriptor(name, field)));
+ } else {
+ illegalProperties.add(name);
+ }
+ }
+ }
+ }
+ }
+
+ List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>();
+ for (PropertyDescriptor prop : props.values()) {
+ if (!!!illegalProperties.contains(prop.getName())) result.add(prop);
+ }
+
+ properties[index] = result.toArray(new PropertyDescriptor[result.size()]);
+ }
+ return properties[index];
+ }
+
+ private static String decapitalize(String name) {
+ if (name == null || name.length() == 0) {
+ return name;
+ }
+ if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
+ Character.isUpperCase(name.charAt(0))) {
+ return name;
+ }
+ char chars[] = name.toCharArray();
+ chars[0] = Character.toLowerCase(chars[0]);
+ return new String(chars);
+ }
+
+ public static Object invoke(AccessControlContext acc, final Method method, final Object instance, final Object... args) throws Exception {
+ if (acc == null) {
+ return method.invoke(instance, args);
+ } else {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return method.invoke(instance, args);
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
+ }
+
+ public static Object newInstance(AccessControlContext acc, final Class clazz) throws Exception {
+ if (acc == null) {
+ return clazz.newInstance();
+ } else {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return clazz.newInstance();
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
+ }
+
+ public static Object newInstance(AccessControlContext acc, final Constructor constructor, final Object... args) throws Exception {
+ if (acc == null) {
+ return constructor.newInstance(args);
+ } else {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return constructor.newInstance(args);
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
+ }
+
+ public static abstract class PropertyDescriptor {
+ private final String name;
+
+ public PropertyDescriptor(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public abstract boolean allowsGet();
+ public abstract boolean allowsSet();
+
+ protected abstract Object internalGet(ExtendedBlueprintContainer container, Object instance) throws Exception;
+ protected abstract void internalSet(ExtendedBlueprintContainer container, Object instance, Object value) throws Exception;
+
+ public Object get(final Object instance, final ExtendedBlueprintContainer container) throws Exception {
+ if (container.getAccessControlContext() == null) {
+ return internalGet(container, instance);
+ } else {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return internalGet(container, instance);
+ }
+ }, container.getAccessControlContext());
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
+ }
+
+ public void set(final Object instance, final Object value, final ExtendedBlueprintContainer container) throws Exception {
+ if (container.getAccessControlContext() == null) {
+ internalSet(container, instance, value);
+ } else {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ internalSet(container, instance, value);
+ return null;
+ }
+ }, container.getAccessControlContext());
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
+ }
+
+ protected Object convert(Object obj, Type type) throws Exception {
+ return ExecutionContext.Holder.getContext().convert(obj, new GenericType(type));
+ }
+ }
+
+ private static class JointPropertyDescriptor extends PropertyDescriptor {
+ private final MethodPropertyDescriptor mpd;
+ private final FieldPropertyDescriptor fpd;
+
+ public JointPropertyDescriptor(MethodPropertyDescriptor mpd, FieldPropertyDescriptor fpd) {
+ super(mpd.getName());
+ this.mpd = mpd;
+ this.fpd = fpd;
+ }
+
+ @Override
+ public boolean allowsGet() {
+ return mpd.allowsGet() || fpd.allowsGet();
+ }
+
+ @Override
+ public boolean allowsSet() {
+ return mpd.allowsSet() || fpd.allowsSet();
+ }
+
+ @Override
+ protected Object internalGet(ExtendedBlueprintContainer container, Object instance) throws Exception {
+ if (mpd.allowsGet()) return mpd.internalGet(container, instance);
+ else if (fpd.allowsGet()) return fpd.internalGet(container, instance);
+ else throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void internalSet(ExtendedBlueprintContainer container, Object instance, Object value) throws Exception {
+ if (mpd.allowsSet()) mpd.internalSet(container, instance, value);
+ else if (fpd.allowsSet()) fpd.internalSet(container, instance, value);
+ else throw new UnsupportedOperationException();
+ }
+ }
+
+ private static class FieldPropertyDescriptor extends PropertyDescriptor {
+ private final Field field;
+
+ public FieldPropertyDescriptor(String name, Field field) {
+ super(name);
+ this.field = field;
+ }
+
+ public boolean allowsGet() {
+ return true;
+ }
+
+ public boolean allowsSet() {
+ return true;
+ }
+
+ protected Object internalGet(ExtendedBlueprintContainer container, final Object instance) throws IllegalArgumentException, IllegalAccessException {
+ if (useContainersPermission(container)) {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ field.setAccessible(true);
+ return field.get(instance);
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ Exception e = pae.getException();
+ if (e instanceof IllegalAccessException) throw (IllegalAccessException) e;
+ else throw (RuntimeException) e;
+ }
+ } else {
+ field.setAccessible(true);
+ return field.get(instance);
+ }
+ }
+
+ protected void internalSet(ExtendedBlueprintContainer container, final Object instance, Object value) throws Exception {
+ final Object convertedValue = convert(value, field.getGenericType());
+ if (useContainersPermission(container)) {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ field.setAccessible(true);
+ field.set(instance, convertedValue);
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ throw pae.getException();
+ }
+ } else {
+ field.setAccessible(true);
+ field.set(instance, convertedValue);
+ }
+ }
+
+ /**
+ * Determine whether the field access (in particular the call to {@link Field#setAccessible(boolean)} should be done with the Blueprint extender's
+ * permissions, rather than the joint (more restrictive) permissions of the extender plus the Blueprint bundle.
+ *
+ * We currently only allow this for classes that originate from inside the Blueprint bundle. Otherwise this would open a potential security hole.
+ * @param container
+ * @return
+ */
+ private boolean useContainersPermission(ExtendedBlueprintContainer container) {
+ ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return field.getDeclaringClass().getClassLoader();
+ }
+ });
+
+ if (loader == null) return false;
+
+ if (loader instanceof BundleReference) {
+ BundleReference ref = (BundleReference) loader;
+ return ref.getBundle().equals(container.getBundleContext().getBundle());
+ }
+
+ return false;
+ }
+ }
+
+ private static class MethodPropertyDescriptor extends PropertyDescriptor {
+ private final Method getter;
+ private final Collection<Method> setters;
+
+ private MethodPropertyDescriptor(String name, Method getter, Collection<Method> setters) {
+ super(name);
+ this.getter = getter;
+ this.setters = (setters != null) ? setters : Collections.<Method>emptyList();
+ }
+
+ public boolean allowsGet() {
+ return getter != null;
+ }
+
+ public boolean allowsSet() {
+ return !!!setters.isEmpty();
+ }
+
+ protected Object internalGet(ExtendedBlueprintContainer container, Object instance)
+ throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ if (getter != null) {
+ return getter.invoke(instance);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ protected void internalSet(ExtendedBlueprintContainer container, Object instance, Object value) throws Exception {
+
+ Method setterMethod = findSetter(value);
+
+ if (setterMethod != null) {
+ setterMethod.invoke(instance, convert(value, setterMethod.getGenericParameterTypes()[0]));
+ } else {
+ throw new ComponentDefinitionException(
+ "No converter available to convert value "+value+" into a form applicable for the " +
+ "setters of property "+getName());
+ }
+ }
+
+ private Method findSetter(Object value) {
+ Class<?> valueType = (value == null) ? null : value.getClass();
+
+ Method result = findMethodByClass(valueType);
+
+ if (result == null) result = findMethodWithConversion(value);
+
+ return result;
+ }
+
+ private Method findMethodByClass(Class<?> arg)
+ throws ComponentDefinitionException {
+ Method result = null;
+
+ if (!hasSameTypeSetter()) {
+ throw new ComponentDefinitionException(
+ "At least one Setter method has to match the type of the Getter method for property "
+ + getName());
+ }
+
+ if (setters.size() == 1) {
+ return setters.iterator().next();
+ }
+
+ for (Method m : setters) {
+ Class<?> paramType = m.getParameterTypes()[0];
+
+ if ((arg == null && Object.class.isAssignableFrom(paramType))
+ || (arg != null && paramType.isAssignableFrom(arg))) {
+
+ // pick the method that has the more specific parameter if
+ // any
+ if (result != null) {
+ Class<?> oldParamType = result.getParameterTypes()[0];
+ if (paramType.isAssignableFrom(oldParamType)) {
+ // do nothing, result is correct
+ } else if (oldParamType.isAssignableFrom(paramType)) {
+ result = m;
+ } else {
+ throw new ComponentDefinitionException(
+ "Ambiguous setter method for property "
+ + getName()
+ + ". More than one method matches the parameter type "
+ + arg);
+ }
+ } else {
+ result = m;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ // ensure there is a setter that matches the type of the getter
+ private boolean hasSameTypeSetter() {
+ if (getter == null) {
+ return true;
+ }
+ Iterator<Method> it = setters.iterator();
+ while (it.hasNext()) {
+ Method m = it.next();
+ if (m.getParameterTypes()[0].equals(getter.getReturnType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Method findMethodWithConversion(Object value) throws ComponentDefinitionException {
+ ExecutionContext ctx = ExecutionContext.Holder.getContext();
+ List<Method> matchingMethods = new ArrayList<Method>();
+ for (Method m : setters) {
+ Type paramType = m.getGenericParameterTypes()[0];
+ if (ctx.canConvert(value, new GenericType(paramType))) matchingMethods.add(m);
+ }
+
+ if (matchingMethods.isEmpty()) return null;
+ else if (matchingMethods.size() == 1) return matchingMethods.get(0);
+ else throw new ComponentDefinitionException(
+ "Ambiguous setter method for property "+ getName() +
+ ". More than one method matches the parameter "+value+" after applying conversion.");
+ }
+
+ public String toString() {
+ return "PropertyDescriptor <name: "+getName()+", getter: "+getter+", setter: "+setters;
+ }
+ }
+
+ public static Throwable getRealCause(Throwable t) {
+ if (t instanceof InvocationTargetException && t.getCause() != null) {
+ return t.getCause();
+ }
+ return t;
+ }
+
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml Sun Feb 27 21:21:05 2011
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
+
+ <service interface="org.apache.aries.blueprint.NamespaceHandler">
+ <service-properties>
+ <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"/>
+ </service-properties>
+ <bean class="org.apache.aries.blueprint.ext.ExtNamespaceHandler"/>
+ </service>
+
+</blueprint>
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/permissions.perm
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/permissions.perm?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/permissions.perm (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/OSGI-INF/permissions.perm Sun Feb 27 21:21:05 2011
@@ -0,0 +1,26 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+# Lines beginning with '#' or '//' are comments
+#
+# This file contains the permissions to be granted.
+# The permissions are listed one per
+# line in PermissionInfo encoded format.
+# See org.osgi.service.permissionadmin.PermissionInfo
+
+(java.security.AllPermission "" "")
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext.xsd
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext.xsd?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext.xsd (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext.xsd Sun Feb 27 21:21:05 2011
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0.0">
+
+ <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0"/>
+
+ <!-- property placeholder -->
+
+ <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
+
+ <xsd:complexType name="TpropertyPlaceholder">
+ <xsd:complexContent>
+ <xsd:extension base="bp:Tcomponent">
+ <xsd:sequence>
+ <!-- nested properties declaration -->
+ <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="location" minOccurs="0" maxOccurs="unbounded" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
+ <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
+ <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+ <xsd:attribute name="ignore-missing-locations" type="xsd:boolean" use="optional" default="false"/>
+ <xsd:attribute name="system-properties" use="optional" default="fallback">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="never"/>
+ <xsd:enumeration value="fallback"/>
+ <xsd:enumeration value="override"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="TdefaultProperties">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="property" type="bp:Tproperty"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- proxy method -->
+
+ <xsd:attribute name="proxy-method" default="default">
+ <xsd:simpleType>
+ <xsd:restriction>
+ <xsd:simpleType>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="default"/>
+ <xsd:enumeration value="classes"/>
+ <xsd:enumeration value="greedy"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ <xsd:minLength value="1"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <!-- role -->
+
+ <xsd:attribute name="role">
+ <xsd:simpleType>
+ <xsd:restriction>
+ <xsd:simpleType>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="processor"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <!-- CM property placeholder extenstion -->
+
+ <xsd:element name="location" type="xsd:string"/>
+ <xsd:attribute name="ignore-missing-locations" type="xsd:boolean" default="false"/>
+ <xsd:attribute name="system-properties" default="fallback">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="never"/>
+ <xsd:enumeration value="fallback"/>
+ <xsd:enumeration value="override"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <xsd:attribute name="field-injection" type="xsd:boolean" default="false" />
+
+</xsd:schema>
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/nls/BlueprintMessages.properties
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/nls/BlueprintMessages.properties?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/nls/BlueprintMessages.properties (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/resources/org/apache/aries/blueprint/nls/BlueprintMessages.properties Sun Feb 27 21:21:05 2011
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+duplicate.component=The component name {0} is already in use.
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,75 @@
+/*
+ * 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.io.IOException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.xml.validation.Schema;
+
+import junit.framework.TestCase;
+
+import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
+import org.apache.aries.blueprint.container.Parser;
+import org.apache.aries.blueprint.ext.ExtNamespaceHandler;
+import org.apache.aries.blueprint.namespace.ComponentDefinitionRegistryImpl;
+import org.xml.sax.SAXException;
+
+public abstract class AbstractBlueprintTest extends TestCase {
+
+ protected ComponentDefinitionRegistryImpl parse(String name) throws Exception {
+ final URI extensionHandler = new URI("http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0");
+ NamespaceHandlerRegistry.NamespaceHandlerSet handlers = new NamespaceHandlerRegistry.NamespaceHandlerSet() {
+ public Set<URI> getNamespaces() {
+ return null;
+ }
+ public NamespaceHandler getNamespaceHandler(URI namespace) {
+ if (namespace.equals(extensionHandler)) {
+ return new ExtNamespaceHandler();
+ } else {
+ return null;
+ }
+ }
+ public void removeListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+ public Schema getSchema() throws SAXException, IOException {
+ return null;
+ }
+ public boolean isComplete() {
+ return false;
+ }
+ public void addListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+ public void destroy() {
+ }
+ };
+ return parse(name, handlers);
+ }
+
+ protected ComponentDefinitionRegistryImpl parse(String name, NamespaceHandlerRegistry.NamespaceHandlerSet handlers) throws Exception {
+ ComponentDefinitionRegistryImpl registry = new ComponentDefinitionRegistryImpl();
+ Parser parser = new Parser();
+ parser.parse(Collections.singletonList(getClass().getResource(name)));
+ parser.populate(handlers, registry);
+ return registry;
+ }
+
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/CallbackTracker.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/CallbackTracker.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/CallbackTracker.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/CallbackTracker.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,66 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+public class CallbackTracker {
+
+ private static List<Callback> callbacks = new ArrayList<Callback>();
+
+ public static void add(Callback callback) {
+ callbacks.add(callback);
+ }
+
+ public static List<Callback> getCallbacks() {
+ return callbacks;
+ }
+
+ public static void clear() {
+ callbacks.clear();
+ }
+
+ public static class Callback {
+
+ public static int INIT = 1;
+ public static int DESTROY = 2;
+
+ private Object object;
+ private int type;
+
+ public Callback(int type, Object object) {
+ this.type = type;
+ this.object = object;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public Object getObject() {
+ return object;
+ }
+
+ public String toString() {
+ return type + " " + object;
+ }
+
+ }
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,299 @@
+/*
+ * 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.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.io.IOException;
+
+import javax.xml.validation.Schema;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
+import org.apache.aries.blueprint.reflect.BeanMetadataImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.reflect.BeanArgument;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
+import org.osgi.service.blueprint.reflect.CollectionMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.NullMetadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.xml.sax.SAXException;
+
+/**
+ * TODO: constructor injection
+ * TODO: Dependency#setMethod
+ */
+public class ParserTest extends AbstractBlueprintTest {
+
+ public void test() {
+ Integer[] oo = new Integer[1];
+ Object[] ii = oo;
+ }
+
+ public void testParseComponent() throws Exception {
+ ComponentDefinitionRegistry registry = parse("/test-simple-component.xml");
+ assertNotNull(registry);
+ ComponentMetadata component = registry.getComponentDefinition("pojoA");
+ assertNotNull(component);
+ assertEquals("pojoA", component.getId());
+ assertTrue(component instanceof BeanMetadata);
+ BeanMetadata local = (BeanMetadata) component;
+ List<String> deps = local.getDependsOn();
+ assertNotNull(deps);
+ assertEquals(2, deps.size());
+ assertTrue(deps.contains("pojoB"));
+ assertTrue(deps.contains("pojoC"));
+ assertEquals("org.apache.aries.blueprint.pojos.PojoA", local.getClassName());
+ List<BeanArgument> params = local.getArguments();
+ assertNotNull(params);
+ assertEquals(6, params.size());
+ BeanArgument param = params.get(0);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertNull(param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof ValueMetadata);
+ assertEquals("val0", ((ValueMetadata) param.getValue()).getStringValue());
+ assertNull(((ValueMetadata) param.getValue()).getType());
+ param = params.get(1);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertNull(param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof RefMetadata);
+ assertEquals("val1", ((RefMetadata) param.getValue()).getComponentId());
+ param = params.get(2);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertNull(param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof NullMetadata);
+ param = params.get(3);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertEquals("java.lang.String", param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof ValueMetadata);
+ assertEquals("val3", ((ValueMetadata) param.getValue()).getStringValue());
+ assertNull(((ValueMetadata) param.getValue()).getType());
+ param = params.get(4);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertNull(param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof CollectionMetadata);
+ CollectionMetadata array = (CollectionMetadata) param.getValue();
+ assertNull(array.getValueType());
+ assertNotNull(array.getValues());
+ assertEquals(3, array.getValues().size());
+ assertTrue(array.getValues().get(0) instanceof ValueMetadata);
+ assertTrue(array.getValues().get(1) instanceof ComponentMetadata);
+ assertTrue(array.getValues().get(2) instanceof NullMetadata);
+ param = params.get(5);
+ assertNotNull(param);
+ assertEquals(-1, param.getIndex());
+ assertNull(param.getValueType());
+ assertNotNull(param.getValue());
+ assertTrue(param.getValue() instanceof RefMetadata);
+ assertEquals("pojoB", ((RefMetadata) param.getValue()).getComponentId());
+
+ assertEquals(null, local.getInitMethod());
+ assertEquals(null, local.getDestroyMethod());
+
+ // test pojoB
+ ComponentMetadata pojoB = registry.getComponentDefinition("pojoB");
+ assertNotNull(pojoB);
+ assertEquals("pojoB", pojoB.getId());
+ assertTrue(pojoB instanceof BeanMetadata);
+ BeanMetadata pojoBLocal = (BeanMetadata) pojoB;
+ assertEquals("initPojo", pojoBLocal.getInitMethod());
+// assertEquals("", pojoBLocal.getDestroyMethod());
+
+ params = pojoBLocal.getArguments();
+ assertNotNull(params);
+ assertEquals(2, params.size());
+ param = params.get(0);
+ assertNotNull(param);
+ assertEquals(1, param.getIndex());
+ param = params.get(1);
+ assertNotNull(param);
+ assertEquals(0, param.getIndex());
+ }
+
+ public void testParse() throws Exception {
+ parse("/test.xml");
+ }
+
+
+ public void testCustomNodes() throws Exception {
+ ComponentDefinitionRegistry registry = parse("/test-custom-nodes.xml", new TestNamespaceHandlerSet());
+
+ ComponentMetadata metadata;
+
+ metadata = registry.getComponentDefinition("fooService");
+ assertNotNull(metadata);
+ assertTrue(metadata instanceof MyLocalComponentMetadata);
+ MyLocalComponentMetadata comp1 = (MyLocalComponentMetadata) metadata;
+ assertEquals(true, comp1.getCacheReturnValues());
+ assertEquals("getVolatile", comp1.getOperation());
+
+ metadata = registry.getComponentDefinition("barService");
+ assertNotNull(metadata);
+ assertTrue(metadata instanceof BeanMetadata);
+ BeanMetadata comp2 = (BeanMetadata) metadata;
+ assertEquals(1, comp2.getProperties().size());
+ BeanProperty propertyMetadata = comp2.getProperties().get(0);
+ assertEquals("localCache", propertyMetadata.getName());
+ Metadata propertyValue = propertyMetadata.getValue();
+ assertTrue(propertyValue instanceof BeanMetadata);
+ BeanMetadata innerComp = (BeanMetadata) propertyValue;
+ assertEquals("org.apache.aries.CacheProperty", innerComp.getClassName());
+
+ metadata = registry.getComponentDefinition("myCache");
+ assertNotNull(metadata);
+ assertTrue(metadata instanceof BeanMetadata);
+ BeanMetadata comp3 = (BeanMetadata) metadata;
+ assertEquals("org.apache.aries.Cache", comp3.getClassName());
+ }
+
+ private static class TestNamespaceHandlerSet implements NamespaceHandlerRegistry.NamespaceHandlerSet {
+
+ private TestNamespaceHandlerSet() {
+ }
+
+ public Set<URI> getNamespaces() {
+ return Collections.singleton(URI.create("http://cache.org"));
+ }
+
+ public boolean isComplete() {
+ return true;
+ }
+
+ public NamespaceHandler getNamespaceHandler(URI namespace) {
+ URI u = URI.create("http://cache.org");
+ if (u.equals(namespace)) {
+ return new TestNamespaceHandler();
+ } else {
+ return null;
+ }
+ }
+
+ public Schema getSchema() throws SAXException, IOException {
+ return null;
+ }
+
+ public void addListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+
+ public void removeListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+
+ public void destroy() {
+ }
+ }
+
+ private static class TestNamespaceHandler implements NamespaceHandler {
+
+ public URL getSchemaLocation(String namespace) {
+ return getClass().getResource("/cache.xsd");
+ }
+
+ public Set<Class> getManagedClasses() {
+ return new HashSet<Class>();
+ }
+
+ public ComponentMetadata decorate(Node node,
+ ComponentMetadata component,
+ ParserContext context) {
+ //System.out.println("decorate: " + node + " " + component + " " + container.getEnclosingComponent().getId());
+
+ if (node instanceof Attr) {
+ Attr attr = (Attr) node;
+ MyLocalComponentMetadata decoratedComp = new MyLocalComponentMetadata((BeanMetadata)component);
+ decoratedComp.setCacheReturnValues(Boolean.parseBoolean(attr.getValue()));
+ return decoratedComp;
+ } else if (node instanceof Element) {
+ Element element = (Element) node;
+ MyLocalComponentMetadata decoratedComp = (MyLocalComponentMetadata) component;
+ decoratedComp.setOperation(element.getAttribute("name"));
+ return decoratedComp;
+ } else {
+ throw new RuntimeException("Unhandled node: " + node);
+ }
+ }
+
+ public Metadata parse(Element element, ParserContext context) {
+ String comp = (context.getEnclosingComponent() == null) ? null : context.getEnclosingComponent().getId();
+ //System.out.println("parse: " + element.getLocalName() + " " + comp);
+
+ String className;
+ if (context.getEnclosingComponent() == null) {
+ className = "org.apache.aries.Cache";
+ } else {
+ className = "org.apache.aries.CacheProperty";
+ }
+
+ BeanMetadataImpl p = new BeanMetadataImpl();
+ p.setId(element.getAttribute("id"));
+ p.setClassName(className);
+
+ return p;
+ }
+
+ }
+
+ private static class MyLocalComponentMetadata extends BeanMetadataImpl {
+
+ private boolean cacheReturnValues;
+ private String operation;
+
+ public MyLocalComponentMetadata(BeanMetadata impl) {
+ super(impl);
+ }
+
+ public boolean getCacheReturnValues() {
+ return cacheReturnValues;
+ }
+
+ public void setCacheReturnValues(boolean value) {
+ cacheReturnValues = value;
+ }
+
+ public void setOperation(String operation) {
+ this.operation = operation;
+ }
+
+ public String getOperation() {
+ return this.operation;
+ }
+ }
+
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.aries.blueprint.container.BlueprintContainerImpl;
+import org.apache.aries.blueprint.namespace.ComponentDefinitionRegistryImpl;
+import org.apache.aries.blueprint.reflect.PassThroughMetadataImpl;
+
+public class TestBlueprintContainer extends BlueprintContainerImpl {
+
+ private ComponentDefinitionRegistryImpl registry;
+
+ public TestBlueprintContainer(ComponentDefinitionRegistryImpl registry) {
+ super(new TestBundleContext(), null, null, null, null, null);
+ this.registry = registry;
+ if (registry != null) {
+ registry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintContainer", this));
+ registry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundle", getBundleContext().getBundle()));
+ registry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundleContext", getBundleContext()));
+ registry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintConverter", getConverter()));
+ }
+ }
+
+ @Override
+ public Class loadClass(String name) throws ClassNotFoundException {
+ return Thread.currentThread().getContextClassLoader().loadClass(name);
+ }
+
+ @Override
+ public ComponentDefinitionRegistryImpl getComponentDefinitionRegistry() {
+ return registry;
+ }
+
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBundleContext.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBundleContext.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBundleContext.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBundleContext.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,122 @@
+/*
+ * 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.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+public class TestBundleContext implements BundleContext {
+
+ public void addBundleListener(BundleListener arg0) {
+ }
+
+ public void addFrameworkListener(FrameworkListener arg0) {
+ }
+
+ public void addServiceListener(ServiceListener arg0) {
+ }
+
+ public void addServiceListener(ServiceListener arg0, String arg1)
+ throws InvalidSyntaxException {
+ }
+
+ public Filter createFilter(String arg0) throws InvalidSyntaxException {
+ return null;
+ }
+
+ public ServiceReference[] getAllServiceReferences(String arg0, String arg1)
+ throws InvalidSyntaxException {
+ return null;
+ }
+
+ public Bundle getBundle() {
+ return null;
+ }
+
+ public Bundle getBundle(long arg0) {
+ return null;
+ }
+
+ public Bundle[] getBundles() {
+ return null;
+ }
+
+ public File getDataFile(String arg0) {
+ return null;
+ }
+
+ public String getProperty(String arg0) {
+ return null;
+ }
+
+ public Object getService(ServiceReference arg0) {
+ return null;
+ }
+
+ public ServiceReference getServiceReference(String arg0) {
+ return null;
+ }
+
+ public ServiceReference[] getServiceReferences(String arg0, String arg1)
+ throws InvalidSyntaxException {
+ return null;
+ }
+
+ public Bundle installBundle(String arg0) throws BundleException {
+ return null;
+ }
+
+ public Bundle installBundle(String arg0, InputStream arg1) throws BundleException {
+ return null;
+ }
+
+ public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {
+ return null;
+ }
+
+ public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
+ return null;
+ }
+
+ public void removeBundleListener(BundleListener arg0) {
+ }
+
+ public void removeFrameworkListener(FrameworkListener arg0) {
+ }
+
+ public void removeServiceListener(ServiceListener arg0) {
+ }
+
+ public boolean ungetService(ServiceReference arg0) {
+ return false;
+ }
+
+}
Added: aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/WiringTest.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/WiringTest.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/WiringTest.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/test/java/org/apache/aries/blueprint/WiringTest.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,471 @@
+/*
+ * 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.AmbiguousPojo;
+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 testSetterDisambiguation() throws Exception {
+ ComponentDefinitionRegistryImpl registry = parse("/test-wiring.xml");
+ Repository repository = new TestBlueprintContainer(registry).getRepository();
+
+ AmbiguousPojo pojo = (AmbiguousPojo) repository.create("ambiguousViaInt");
+ assertEquals(5, pojo.getSum());
+
+ pojo = (AmbiguousPojo) repository.create("ambiguousViaList");
+ assertEquals(7, pojo.getSum());
+
+
+ }
+
+ 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);
+ }
+
+}