use of org.apache.felix.scr.impl.inject.BindMethod.ParamType in project felix by apache.
the class BindMethod method getParameters.
@Override
protected Object[] getParameters(Method method, BindParameters bp) {
ComponentContextImpl key = bp.getComponentContext();
Object[] result = new Object[m_paramTypes.size()];
RefPair<?, ?> refPair = bp.getRefPair();
int i = 0;
for (ParamType pt : m_paramTypes) {
switch(pt) {
case serviceReference:
result[i++] = refPair.getRef();
break;
case serviceObjects:
result[i++] = bp.getComponentContext().getComponentServiceObjectsHelper().getServiceObjects(refPair.getRef());
break;
case map:
result[i++] = new ReadOnlyDictionary(refPair.getRef());
break;
case serviceType:
result[i++] = refPair.getServiceObject(key);
break;
default:
throw new IllegalStateException("unexpected ParamType: " + pt);
}
}
return result;
}
use of org.apache.felix.scr.impl.inject.BindMethod.ParamType in project felix by apache.
the class BindMethod method doFindMethod.
/**
* Finds the method named in the {@link #m_methodName} field in the given
* <code>targetClass</code>. If the target class has no acceptable method
* the class hierarchy is traversed until a method is found or the root
* of the class hierarchy is reached without finding a method.
*
* @param targetClass The class in which to look for the method
* @param acceptPrivate <code>true</code> if private methods should be
* considered.
* @param acceptPackage <code>true</code> if package private methods should
* be considered.
* @param logger
* @return The requested method or <code>null</code> if no acceptable method
* can be found in the target class or any super class.
* @throws InvocationTargetException If an unexpected Throwable is caught
* trying to find the requested method.
*/
@Override
protected MethodInfo<List<ParamType>> doFindMethod(final Class<?> targetClass, final boolean acceptPrivate, final boolean acceptPackage, final SimpleLogger logger) throws SuitableMethodNotAccessibleException, InvocationTargetException {
// 112.3.1 The method is searched for using the following priority
// 1 - ServiceReference single parameter
// 2 - DS 1.3+ : ComponentServiceObjects single parameter
// 3 - Service object single parameter
// 4 - Service interface assignment compatible single parameter
// 5 - DS 1.3+ : Single argument with Map
// 6 - DS 1.1/DS 1.2 : two parameters, first the type of or assignment compatible with the service, the second Map
// 7 - DS 1.3+ : one or more parameters of types ServiceReference, ServiceObjects, interface type,
// or assignment compatible to interface type, in any order.
// flag indicating a suitable but inaccessible method has been found
boolean suitableMethodNotAccessible = false;
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Looking for method " + targetClass.getName() + "." + getMethodName(), null);
}
// Case 1 - Service reference parameter
Method method;
try {
method = getServiceReferenceMethod(targetClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
return new MethodInfo<List<ParamType>>(method, Collections.singletonList(ParamType.serviceReference));
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
// Case 2 - ComponentServiceObjects parameter
if (getDSVersion().isDS13()) {
try {
method = getComponentObjectsMethod(targetClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
return new MethodInfo<List<ParamType>>(method, Collections.singletonList(ParamType.serviceObjects));
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
}
// for further methods we need the class of the service object
final Class<?> parameterClass = ClassUtils.getClassFromComponentClassLoader(targetClass, m_referenceClassName, logger);
if (parameterClass != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: No method taking ServiceReference found, checking method taking " + parameterClass.getName(), null);
}
// Case 3 - Service object parameter
try {
method = getServiceObjectMethod(targetClass, parameterClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
return new MethodInfo<List<ParamType>>(method, Collections.singletonList(ParamType.serviceType));
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
// Case 4 - Service interface assignment compatible methods
try {
method = getServiceObjectAssignableMethod(targetClass, parameterClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
return new MethodInfo<List<ParamType>>(method, Collections.singletonList(ParamType.serviceType));
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
// Case 5 - DS 1.3+ : Single argument with Map
if (getDSVersion().isDS13()) {
try {
method = getMapMethod(targetClass, parameterClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
return new MethodInfo<List<ParamType>>(method, Collections.singletonList(ParamType.map));
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
}
// signatures taking a map are only supported starting with DS 1.1
if (getDSVersion().isDS11() && !getDSVersion().isDS13()) {
// Case 6 - same as case 3, but + Map param (DS 1.1 only)
try {
method = getServiceObjectWithMapMethod(targetClass, parameterClass, acceptPrivate, acceptPackage, logger);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
List<ParamType> paramTypes = new ArrayList<ParamType>(2);
paramTypes.add(ParamType.serviceType);
paramTypes.add(ParamType.map);
return new MethodInfo<List<ParamType>>(method, paramTypes);
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
// Case 6 - same as case 4, but + Map param (DS 1.1 only)
try {
method = getServiceObjectAssignableWithMapMethod(targetClass, parameterClass, acceptPrivate, acceptPackage);
if (method != null) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null);
}
List<ParamType> paramTypes = new ArrayList<ParamType>(2);
paramTypes.add(ParamType.serviceType);
paramTypes.add(ParamType.map);
return new MethodInfo<List<ParamType>>(method, paramTypes);
}
} catch (SuitableMethodNotAccessibleException ex) {
suitableMethodNotAccessible = true;
}
}
// Case 7 - Multiple parameters
if (getDSVersion().isDS13()) {
for (Method m : targetClass.getDeclaredMethods()) {
if (getMethodName().equals(m.getName())) {
Class<?>[] parameterTypes = m.getParameterTypes();
boolean matches = true;
boolean specialMatch = true;
List<ParamType> paramTypes = new ArrayList<ParamType>(parameterTypes.length);
for (Class<?> paramType : parameterTypes) {
if (paramType == ClassUtils.SERVICE_REFERENCE_CLASS) {
if (specialMatch && parameterClass == ClassUtils.SERVICE_REFERENCE_CLASS) {
specialMatch = false;
paramTypes.add(ParamType.serviceType);
} else {
paramTypes.add(ParamType.serviceReference);
}
} else if (paramType == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS) {
if (specialMatch && parameterClass == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS) {
specialMatch = false;
paramTypes.add(ParamType.serviceType);
} else {
paramTypes.add(ParamType.serviceObjects);
}
} else if (paramType == Map.class) {
if (specialMatch && parameterClass == Map.class) {
specialMatch = false;
paramTypes.add(ParamType.serviceType);
} else {
paramTypes.add(ParamType.map);
}
} else if (paramType.isAssignableFrom(parameterClass)) {
paramTypes.add(ParamType.serviceType);
} else {
matches = false;
break;
}
}
if (matches) {
if (accept(m, acceptPrivate, acceptPackage, returnValue())) {
if (logger.isLogEnabled(LogService.LOG_DEBUG)) {
logger.log(LogService.LOG_DEBUG, "doFindMethod: Found Method " + m, null);
}
return new MethodInfo<List<ParamType>>(m, paramTypes);
}
suitableMethodNotAccessible = true;
}
}
}
}
} else if (logger.isLogEnabled(LogService.LOG_WARNING)) {
logger.log(LogService.LOG_WARNING, "doFindMethod: Cannot check for methods taking parameter class " + m_referenceClassName + ": " + targetClass.getName() + " does not see it", null);
}
// the suitable methods are accessible, we have to terminate
if (suitableMethodNotAccessible) {
logger.log(LogService.LOG_ERROR, "doFindMethod: Suitable but non-accessible method found in class {0}", new Object[] { targetClass.getName() }, null);
throw new SuitableMethodNotAccessibleException();
}
// no method found
return null;
}
Aggregations