[KARAF-3646] Add method inheritance support in Cellar DOSGi
Project: http://git-wip-us.apache.org/repos/asf/karaf-cellar/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf-cellar/commit/213e521e Tree: http://git-wip-us.apache.org/repos/asf/karaf-cellar/tree/213e521e Diff: http://git-wip-us.apache.org/repos/asf/karaf-cellar/diff/213e521e Branch: refs/heads/cellar-2.3.x Commit: 213e521e40d35c1e8926e8c28b689aa50fc684a2 Parents: e9d6ee5 Author: Jean-Baptiste Onofré <[email protected]> Authored: Sun Sep 20 21:26:59 2015 +0200 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Sun Sep 20 21:26:59 2015 +0200 ---------------------------------------------------------------------- dosgi/pom.xml | 18 +++++++ .../cellar/dosgi/RemoteServiceCallHandler.java | 56 +++++++++++++++++--- 2 files changed, 67 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/213e521e/dosgi/pom.xml ---------------------------------------------------------------------- diff --git a/dosgi/pom.xml b/dosgi/pom.xml index 53c00a8..53abcbf 100644 --- a/dosgi/pom.xml +++ b/dosgi/pom.xml @@ -50,6 +50,9 @@ <osgi.export> org.apache.karaf.cellar.dosgi*;version="${project.version}" </osgi.export> + <osgi.private> + org.apache.commons.lang3*;-split-package:=merge-first + </osgi.private> </properties> <dependencies> @@ -58,6 +61,21 @@ <groupId>org.apache.karaf.cellar</groupId> <artifactId>org.apache.karaf.cellar.core</artifactId> </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.3.2</version> + </dependency> <!-- Logging Dependencies --> <dependency> http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/213e521e/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/RemoteServiceCallHandler.java ---------------------------------------------------------------------- diff --git a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/RemoteServiceCallHandler.java b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/RemoteServiceCallHandler.java index aa1c484..a76d163 100644 --- a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/RemoteServiceCallHandler.java +++ b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/RemoteServiceCallHandler.java @@ -13,6 +13,7 @@ */ package org.apache.karaf.cellar.dosgi; +import org.apache.commons.lang3.ClassUtils; import org.apache.karaf.cellar.core.CellarSupport; import org.apache.karaf.cellar.core.Configurations; import org.apache.karaf.cellar.core.control.BasicSwitch; @@ -31,6 +32,7 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; /** * Handler for cluster remote service call event. @@ -84,13 +86,7 @@ public class RemoteServiceCallHandler extends CellarSupport implements EventHand RemoteServiceResult result = new RemoteServiceResult(event.getId()); EventProducer producer = eventTransportFactory.getEventProducer(Constants.RESULT_PREFIX + Constants.SEPARATOR + event.getSourceNode().getId() + event.getEndpointId(), false); try { - Method method; - if (classes.length > 0) { - method = targetService.getClass().getMethod(event.getMethod(), classes); - } else { - method = targetService.getClass().getMethod(event.getMethod()); - } - + Method method = getMethod(classes, targetService, event); Object obj = method.invoke(targetService, event.getArguments().toArray()); result.setResult(obj); producer.produce(result); @@ -112,6 +108,52 @@ public class RemoteServiceCallHandler extends CellarSupport implements EventHand } } + /** + * <p>Gets a matching method in the <code>Object targetService<code/>.<br/> + * Inheritance is supported.</p> + * + * @param eventParamTypes + * @param targetService + * @param event + * @return a method instance from the <code>Object targetService<code/> + * @throws NoSuchMethodException + */ + private Method getMethod(Class[] eventParamTypes, Object targetService, RemoteServiceCall event) throws NoSuchMethodException { + + Method result = null; + if (eventParamTypes.length > 0) { + for (Method remoteMethod : targetService.getClass().getMethods()) { + //need to find a method with a matching name and with the same number of parameters + if (remoteMethod.getName().equals(event.getMethod()) && remoteMethod.getParameterTypes().length == eventParamTypes.length) { + boolean allParamsFound = true; + for (int i = 0; i < remoteMethod.getParameterTypes().length; i++) { + allParamsFound = allParamsFound && ClassUtils.isAssignable(eventParamTypes[i], remoteMethod.getParameterTypes()[i]); + } + + // if already found a matching method, no need to continue looking for one + if (allParamsFound) { + result = remoteMethod; + break; + } + } + } + } else { + result = targetService.getClass().getMethod(event.getMethod()); + } + + //if method was not found go out with a bang + if (result == null) { + throw new NoSuchMethodException(String.format("No match for method [%s] %s", event.getMethod(), Arrays.toString(eventParamTypes))); + } + + return result; + } + + /** + * Get the event type that this handler can handle. + * + * @return the remote service call event type. + */ @Override public Class<RemoteServiceCall> getType() { return RemoteServiceCall.class;
