Search in sources :

Example 11 with ReifiedType

use of org.osgi.service.blueprint.container.ReifiedType in project aries by apache.

the class BeanRecipe method getInstance.

private Object getInstance() throws ComponentDefinitionException {
    Object instance;
    // Instanciate arguments
    List<Object> args = new ArrayList<Object>();
    List<ReifiedType> argTypes = new ArrayList<ReifiedType>();
    if (arguments != null) {
        for (int i = 0; i < arguments.size(); i++) {
            Object arg = arguments.get(i);
            if (arg instanceof Recipe) {
                args.add(((Recipe) arg).create());
            } else {
                args.add(arg);
            }
            if (this.argTypes != null) {
                argTypes.add(this.argTypes.get(i) != null ? loadType(this.argTypes.get(i)) : null);
            }
        }
    }
    if (factory != null) {
        // look for instance method on factory object
        Object factoryObj = factory.create();
        /* BLUEPRINT-NOOSGI
            if (factoryObj instanceof ReferenceRecipe.ServiceProxyWrapper) {
                try {
                    factoryObj = ((ReferenceRecipe.ServiceProxyWrapper) factoryObj).convert(new ReifiedType(Object.class));
                } catch (Exception e) {
                    throw new ComponentDefinitionException("Error when instantiating bean " + getName() + " of class " + getType(), getRealCause(e));
                }
            } else*/
        if (factoryObj instanceof UnwrapperedBeanHolder) {
            factoryObj = wrap((UnwrapperedBeanHolder) factoryObj, Object.class);
        }
        // Map of matching methods
        Map<Method, List<Object>> matches = findMatchingMethods(factoryObj.getClass(), factoryMethod, true, args, argTypes);
        if (matches.size() == 1) {
            try {
                Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
                instance = invoke(match.getKey(), factoryObj, match.getValue().toArray());
            } catch (Throwable e) {
                throw new ComponentDefinitionException("Error when instantiating bean " + getName() + " of class " + getType(), getRealCause(e));
            }
        } else if (matches.size() == 0) {
            throw new ComponentDefinitionException("Unable to find a matching factory method " + factoryMethod + " on class " + factoryObj.getClass().getName() + " for arguments " + args + " when instanciating bean " + getName());
        } else {
            throw new ComponentDefinitionException("Multiple matching factory methods " + factoryMethod + " found on class " + factoryObj.getClass().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
        }
    } else if (factoryMethod != null) {
        // Map of matching methods
        Map<Method, List<Object>> matches = findMatchingMethods(getType(), factoryMethod, false, args, argTypes);
        if (matches.size() == 1) {
            try {
                Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
                instance = invoke(match.getKey(), null, match.getValue().toArray());
            } catch (Throwable e) {
                throw new ComponentDefinitionException("Error when instanciating bean " + getName() + " of class " + getType(), getRealCause(e));
            }
        } else if (matches.size() == 0) {
            throw new ComponentDefinitionException("Unable to find a matching factory method " + factoryMethod + " on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName());
        } else {
            throw new ComponentDefinitionException("Multiple matching factory methods " + factoryMethod + " found on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
        }
    } else {
        if (getType() == null) {
            throw new ComponentDefinitionException("No factoryMethod nor class is defined for this bean");
        }
        // Map of matching constructors
        Map<Constructor, List<Object>> matches = findMatchingConstructors(getType(), args, argTypes);
        if (matches.size() == 1) {
            try {
                Map.Entry<Constructor, List<Object>> match = matches.entrySet().iterator().next();
                instance = newInstance(match.getKey(), match.getValue().toArray());
            } catch (Throwable e) {
                throw new ComponentDefinitionException("Error when instanciating bean " + getName() + " of class " + getType(), getRealCause(e));
            }
        } else if (matches.size() == 0) {
            throw new ComponentDefinitionException("Unable to find a matching constructor on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName());
        } else {
            throw new ComponentDefinitionException("Multiple matching constructors found on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
        }
    }
    return instance;
}
Also used : ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException) Recipe(org.apache.aries.blueprint.di.Recipe) AbstractRecipe(org.apache.aries.blueprint.di.AbstractRecipe) ReifiedType(org.osgi.service.blueprint.container.ReifiedType) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 12 with ReifiedType

use of org.osgi.service.blueprint.container.ReifiedType in project aries by apache.

the class BeanRecipe method findMatchingMethods.

private Map<Method, List<Object>> findMatchingMethods(Class type, String name, boolean instance, List<Object> args, List<ReifiedType> types) {
    Map<Method, List<Object>> matches = new HashMap<Method, List<Object>>();
    // Get constructors
    List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods()));
    // Discard any signature with wrong cardinality
    for (Iterator<Method> it = methods.iterator(); it.hasNext(); ) {
        Method mth = it.next();
        if (!mth.getName().equals(name)) {
            it.remove();
        } else if (mth.getParameterTypes().length != args.size()) {
            it.remove();
        } else if (instance ^ !Modifier.isStatic(mth.getModifiers())) {
            it.remove();
        } else if (mth.isBridge()) {
            it.remove();
        }
    }
    // to reduce ambiguity
    if (!instance) {
        methods = applyStaticHidingRules(methods);
    }
    // Find a direct match with assignment
    if (matches.size() != 1) {
        Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
        for (Method mth : methods) {
            boolean found = true;
            List<Object> match = new ArrayList<Object>();
            for (int i = 0; i < args.size(); i++) {
                ReifiedType argType = new GenericType(mth.getGenericParameterTypes()[i]);
                if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
                    found = false;
                    break;
                }
                //If the arg is an Unwrappered bean then we need to do the assignment check against the
                //unwrappered bean itself.
                Object arg = args.get(i);
                Object argToTest = arg;
                if (arg instanceof UnwrapperedBeanHolder)
                    argToTest = ((UnwrapperedBeanHolder) arg).unwrapperedBean;
                if (!AggregateConverter.isAssignable(argToTest, argType)) {
                    found = false;
                    break;
                }
                try {
                    match.add(convert(arg, mth.getGenericParameterTypes()[i]));
                } catch (Throwable t) {
                    found = false;
                    break;
                }
            }
            if (found) {
                nmatches.put(mth, match);
            }
        }
        if (nmatches.size() > 0) {
            matches = nmatches;
        }
    }
    // Find a direct match with conversion
    if (matches.size() != 1) {
        Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
        for (Method mth : methods) {
            boolean found = true;
            List<Object> match = new ArrayList<Object>();
            for (int i = 0; i < args.size(); i++) {
                ReifiedType argType = new GenericType(mth.getGenericParameterTypes()[i]);
                if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
                    found = false;
                    break;
                }
                try {
                    Object val = convert(args.get(i), argType);
                    match.add(val);
                } catch (Throwable t) {
                    found = false;
                    break;
                }
            }
            if (found) {
                nmatches.put(mth, match);
            }
        }
        if (nmatches.size() > 0) {
            matches = nmatches;
        }
    }
    // Start reordering with assignment
    if (matches.size() != 1 && reorderArguments && args.size() > 1) {
        Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
        for (Method mth : methods) {
            ArgumentMatcher matcher = new ArgumentMatcher(mth.getGenericParameterTypes(), false);
            List<Object> match = matcher.match(args, types);
            if (match != null) {
                nmatches.put(mth, match);
            }
        }
        if (nmatches.size() > 0) {
            matches = nmatches;
        }
    }
    // Start reordering with conversion
    if (matches.size() != 1 && reorderArguments && args.size() > 1) {
        Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
        for (Method mth : methods) {
            ArgumentMatcher matcher = new ArgumentMatcher(mth.getGenericParameterTypes(), true);
            List<Object> match = matcher.match(args, types);
            if (match != null) {
                nmatches.put(mth, match);
            }
        }
        if (nmatches.size() > 0) {
            matches = nmatches;
        }
    }
    return matches;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ReifiedType(org.osgi.service.blueprint.container.ReifiedType) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with ReifiedType

use of org.osgi.service.blueprint.container.ReifiedType in project aries by apache.

the class ReflectionUtilsTest method before.

@BeforeClass
public static void before() throws ClassNotFoundException {
    mockBlueprint = EasyMock.createNiceMock(ExtendedBlueprintContainer.class);
    final Capture<String> nameCapture = new Capture<String>();
    EasyMock.expect(mockBlueprint.loadClass(EasyMock.capture(nameCapture))).andAnswer(new IAnswer<Class<?>>() {

        public Class<?> answer() throws Throwable {
            return Thread.currentThread().getContextClassLoader().loadClass(nameCapture.getValue());
        }
    });
    EasyMock.replay(mockBlueprint);
    ExecutionContext.Holder.setContext(new ExecutionContext() {

        public void addPartialObject(String name, Object object) {
        }

        public boolean containsObject(String name) {
            return false;
        }

        public Object convert(Object value, ReifiedType type) throws Exception {
            if (type.getRawClass().equals(Inconvertible.class))
                throw new Exception();
            else if (type.getRawClass().equals(String.class))
                return String.valueOf(value);
            else if (type.getRawClass().equals(List.class)) {
                if (value == null)
                    return null;
                else if (value instanceof Collection)
                    return new ArrayList((Collection) value);
                else
                    throw new Exception();
            } else if (value == null)
                return null;
            else if (type.getRawClass().isInstance(value))
                return value;
            else
                throw new Exception();
        }

        public boolean canConvert(Object value, ReifiedType type) {
            if (value instanceof Inconvertible)
                return false;
            else if (type.getRawClass().equals(String.class))
                return true;
            else if (type.getRawClass().equals(List.class) && (value == null || value instanceof Collection))
                return true;
            else
                return false;
        }

        public Object getObject(String name) {
            return null;
        }

        public Object getPartialObject(String name) {
            return null;
        }

        public Recipe getRecipe(String name) {
            return null;
        }

        public Class loadClass(String className) throws ClassNotFoundException {
            return null;
        }

        public Recipe pop() {
            return null;
        }

        public void push(Recipe recipe) throws CircularDependencyException {
        }

        public void removePartialObject(String name) {
        }

        public Future<Object> addFullObject(String name, Future<Object> object) {
            return null;
        }
    });
}
Also used : Recipe(org.apache.aries.blueprint.di.Recipe) ReifiedType(org.osgi.service.blueprint.container.ReifiedType) ArrayList(java.util.ArrayList) Capture(org.easymock.Capture) CircularDependencyException(org.apache.aries.blueprint.di.CircularDependencyException) ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException) ExecutionContext(org.apache.aries.blueprint.di.ExecutionContext) Collection(java.util.Collection) Future(java.util.concurrent.Future) BeforeClass(org.junit.BeforeClass) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ExtendedBlueprintContainer(org.apache.aries.blueprint.services.ExtendedBlueprintContainer) CircularDependencyException(org.apache.aries.blueprint.di.CircularDependencyException) BeforeClass(org.junit.BeforeClass)

Example 14 with ReifiedType

use of org.osgi.service.blueprint.container.ReifiedType in project aries by apache.

the class ServiceRecipe method createService.

private void createService() {
    try {
        if (service == null) {
            LOGGER.debug("Creating service instance");
            //We can't use the BlueprintRepository because we don't know what interfaces
            //to use yet! We have to be a bit smarter.
            ExecutionContext old = ExecutionContext.Holder.setContext(blueprintContainer.getRepository());
            try {
                Object o = serviceRecipe.create();
                if (o instanceof Convertible) {
                    o = blueprintContainer.getRepository().convert(o, new ReifiedType(Object.class));
                    validateClasses(o);
                } else if (o instanceof UnwrapperedBeanHolder) {
                    UnwrapperedBeanHolder holder = (UnwrapperedBeanHolder) o;
                    if (holder.unwrapperedBean instanceof ServiceFactory) {
                        //If a service factory is used, make sure the proxy classes implement this
                        //interface so that later on, internalGetService will create the real
                        //service from it.
                        LOGGER.debug("{} implements ServiceFactory, creating proxy that also implements this", holder.unwrapperedBean);
                        Collection<Class<?>> cls = getClassesForProxying(holder.unwrapperedBean);
                        cls.add(blueprintContainer.loadClass("org.osgi.framework.ServiceFactory"));
                        o = BeanRecipe.wrap(holder, cls);
                    } else {
                        validateClasses(holder.unwrapperedBean);
                        o = BeanRecipe.wrap(holder, getClassesForProxying(holder.unwrapperedBean));
                    }
                } else if (!(o instanceof ServiceFactory)) {
                    validateClasses(o);
                }
                service = o;
            } catch (Exception e) {
                LOGGER.error("Error retrieving service from " + this, e);
                throw new ComponentDefinitionException(e);
            } finally {
                ExecutionContext.Holder.setContext(old);
            }
            LOGGER.debug("Service created: {}", service);
        }
        // When the service is first requested, we need to create listeners and call them
        if (!initialServiceRegistration && listeners == null) {
            LOGGER.debug("Creating listeners");
            if (listenersRecipe != null) {
                listeners = (List) createRecipe(listenersRecipe);
            } else {
                listeners = Collections.emptyList();
            }
            LOGGER.debug("Listeners created: {}", listeners);
            if (registration.get() != null) {
                LOGGER.debug("Calling listeners for initial service registration");
                for (ServiceListener listener : listeners) {
                    listener.register(service, registrationProperties);
                }
            } else {
                LOGGER.debug("Calling listeners for initial service unregistration");
                for (ServiceListener listener : listeners) {
                    listener.unregister(service, registrationProperties);
                }
            }
        }
    } catch (RuntimeException e) {
        LOGGER.error("Error retrieving service from " + this, e);
        throw e;
    }
}
Also used : ExecutionContext(org.apache.aries.blueprint.di.ExecutionContext) Convertible(org.apache.aries.blueprint.container.AggregateConverter.Convertible) ServiceListener(org.apache.aries.blueprint.utils.ServiceListener) ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException) ServiceFactory(org.osgi.framework.ServiceFactory) ReifiedType(org.osgi.service.blueprint.container.ReifiedType) Collection(java.util.Collection) ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException) UnwrapperedBeanHolder(org.apache.aries.blueprint.container.BeanRecipe.UnwrapperedBeanHolder)

Example 15 with ReifiedType

use of org.osgi.service.blueprint.container.ReifiedType in project aries by apache.

the class ArrayRecipe method internalCreate.

protected Object internalCreate() throws ComponentDefinitionException {
    ReifiedType type;
    if (this.type instanceof Class) {
        type = new ReifiedType((Class) this.type);
    } else if (this.type instanceof String) {
        type = loadType((String) this.type);
    } else {
        type = new ReifiedType(Object.class);
    }
    // create array instance
    Object array;
    try {
        array = Array.newInstance(type.getRawClass(), list.size());
    } catch (Exception e) {
        throw new ComponentDefinitionException("Error while creating array instance: " + type);
    }
    int index = 0;
    for (Recipe recipe : list) {
        Object value;
        if (recipe != null) {
            try {
                value = convert(recipe.create(), type);
            } catch (Exception e) {
                throw new ComponentDefinitionException("Unable to convert value " + recipe + " to type " + type, e);
            }
        } else {
            value = null;
        }
        Array.set(array, index, value);
        index++;
    }
    return array;
}
Also used : ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException) ReifiedType(org.osgi.service.blueprint.container.ReifiedType) ComponentDefinitionException(org.osgi.service.blueprint.container.ComponentDefinitionException)

Aggregations

ReifiedType (org.osgi.service.blueprint.container.ReifiedType)16 HashMap (java.util.HashMap)6 ComponentDefinitionException (org.osgi.service.blueprint.container.ComponentDefinitionException)6 ArrayList (java.util.ArrayList)5 Collection (java.util.Collection)5 List (java.util.List)5 Map (java.util.Map)5 LinkedHashMap (java.util.LinkedHashMap)4 Method (java.lang.reflect.Method)3 Dictionary (java.util.Dictionary)3 Enumeration (java.util.Enumeration)3 Type (java.lang.reflect.Type)2 ExecutionContext (org.apache.aries.blueprint.di.ExecutionContext)2 Recipe (org.apache.aries.blueprint.di.Recipe)2 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 AbstractMap (java.util.AbstractMap)1 Hashtable (java.util.Hashtable)1 LinkedHashSet (java.util.LinkedHashSet)1