You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gn...@apache.org on 2009/04/20 13:19:48 UTC
svn commit: r766653 - in /geronimo/sandbox/blueprint:
blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/
blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/
blueprint-sample/src/main/java/org/apache/geronimo/blueprint/...
Author: gnodet
Date: Mon Apr 20 11:19:48 2009
New Revision: 766653
URL: http://svn.apache.org/viewvc?rev=766653&view=rev
Log:
Commit work on UnaryServiceReference
Added:
geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestModuleContext.java
- copied, changed from r766585, geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/Test.java
geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/BindingListener.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java (contents, props changed)
- copied, changed from r766585, geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooListener.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/InterfaceA.java
Removed:
geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/Test.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooListener.java
Modified:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleDelegatingClassLoader.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ModuleContextImpl.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleDelegatingClassLoader.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleDelegatingClassLoader.java?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleDelegatingClassLoader.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleDelegatingClassLoader.java Mon Apr 20 11:19:48 2009
@@ -33,9 +33,15 @@
public class BundleDelegatingClassLoader extends ClassLoader {
private final Bundle bundle;
+ private final ClassLoader classLoader;
public BundleDelegatingClassLoader(Bundle bundle) {
+ this(bundle, null);
+ }
+
+ public BundleDelegatingClassLoader(Bundle bundle, ClassLoader classLoader) {
this.bundle = bundle;
+ this.classLoader = classLoader;
}
protected Class findClass(String name) throws ClassNotFoundException {
@@ -43,7 +49,11 @@
}
protected URL findResource(String name) {
- return bundle.getResource(name);
+ URL resource = findResource(name);
+ if (classLoader != null && resource == null) {
+ resource = classLoader.getResource(name);
+ }
+ return resource;
}
protected Enumeration findResources(String name) throws IOException {
@@ -51,7 +61,16 @@
}
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
- Class clazz = findClass(name);
+ Class clazz;
+ try {
+ clazz = findClass(name);
+ }
+ catch (ClassNotFoundException cnfe) {
+ if (classLoader != null)
+ clazz = classLoader.loadClass(name);
+ else
+ throw cnfe;
+ }
if (resolve) {
resolveClass(clazz);
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java Mon Apr 20 11:19:48 2009
@@ -58,6 +58,7 @@
import org.osgi.service.blueprint.reflect.Value;
import org.osgi.service.blueprint.reflect.UnaryServiceReferenceComponentMetadata;
import org.osgi.service.blueprint.reflect.CollectionBasedServiceReferenceComponentMetadata;
+import org.osgi.service.blueprint.reflect.BindingListenerMetadata;
/**
* TODO: javadoc
@@ -148,8 +149,8 @@
recipe.allow(Option.PRIVATE_PROPERTIES);
recipe.setName(component.getName());
recipe.setProperty("moduleContext", moduleContext);
- LocalComponentMetadata exportedComponent = getServiceComponent(serviceExport.getExportedComponent());
- if (LocalComponentMetadata.SCOPE_BUNDLE.equals(exportedComponent.getScope())) {
+ LocalComponentMetadata exportedComponent = getLocalServiceComponent(serviceExport.getExportedComponent());
+ if (exportedComponent != null && LocalComponentMetadata.SCOPE_BUNDLE.equals(exportedComponent.getScope())) {
Recipe exportedComponentRecipe = createRecipe(exportedComponent);
recipe.setProperty("service", new BundleScopeServiceFactory(moduleContext, exportedComponentRecipe));
} else {
@@ -171,8 +172,20 @@
}
return recipe;
} else if (component instanceof UnaryServiceReferenceComponentMetadata) {
- // TODO
- throw new IllegalStateException("Unsupported component type " + component.getClass());
+ UnaryServiceReferenceComponentMetadata metadata = (UnaryServiceReferenceComponentMetadata) component;
+ CollectionRecipe cr = null;
+ if (metadata.getBindingListeners() != null) {
+ cr = new CollectionRecipe(ArrayList.class);;
+ for (BindingListenerMetadata listener : (Collection<BindingListenerMetadata>) metadata.getBindingListeners()) {
+ cr.add(createRecipe(listener));
+ }
+ }
+ ReferenceServiceRecipe recipe = new ReferenceServiceRecipe(moduleContext,
+ moduleContext.getSender(),
+ metadata,
+ cr);
+ recipe.setName(component.getName());
+ return recipe;
} else if (component instanceof CollectionBasedServiceReferenceComponentMetadata) {
// TODO
throw new IllegalStateException("Unsupported component type " + component.getClass());
@@ -188,17 +201,29 @@
recipe.setProperty("metadata", listener);
return recipe;
}
-
- private LocalComponentMetadata getServiceComponent(Value value) throws Exception {
+
+ private Recipe createRecipe(BindingListenerMetadata listener) throws Exception {
+ ObjectRecipe recipe = new ObjectRecipe(ReferenceServiceRecipe.Listener.class);
+ recipe.allow(Option.PRIVATE_PROPERTIES);
+ recipe.setProperty("listener", getValue(listener.getListenerComponent(), null));
+ recipe.setProperty("metadata", listener);
+ return recipe;
+ }
+
+ private LocalComponentMetadata getLocalServiceComponent(Value value) throws Exception {
+ ComponentMetadata metadata = null;
if (value instanceof ReferenceValue) {
ReferenceValue ref = (ReferenceValue) value;
ComponentDefinitionRegistry registry = getComponentDefinitionRegistry();
- return (LocalComponentMetadata) registry.getComponentDefinition(ref.getComponentName());
+ metadata = registry.getComponentDefinition(ref.getComponentName());
} else if (value instanceof ComponentValue) {
ComponentValue comp = (ComponentValue) value;
- return (LocalComponentMetadata) comp.getComponentMetadata();
+ metadata = comp.getComponentMetadata();
+ }
+ if (metadata instanceof LocalComponentMetadata) {
+ return (LocalComponentMetadata) metadata;
} else {
- throw new RuntimeException("Unexpected component value: " + value);
+ return null;
}
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ModuleContextImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ModuleContextImpl.java?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ModuleContextImpl.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ModuleContextImpl.java Mon Apr 20 11:19:48 2009
@@ -77,6 +77,10 @@
this.componentDefinitionRegistry = new ComponentDefinitionRegistryImpl();
}
+ public ModuleContextEventSender getSender() {
+ return sender;
+ }
+
private void checkDirectives() {
Bundle bundle = bundleContext.getBundle();
Dictionary headers = bundle.getHeaders();
@@ -109,7 +113,7 @@
// TODO: handle scopes and such
Map instances = objectGraph.createAll(new ArrayList<String>(componentDefinitionRegistry.getComponentDefinitionNames()));
- System.out.println(instances);
+ //System.out.println(instances);
registerAllServices();
@@ -126,9 +130,8 @@
sender.sendWaiting(this, e.getServiceObjectClass(), e.getServiceFilter());
// TODO: wait for dependency
} catch (Exception e) {
- e.printStackTrace();
- // TODO: pass the exception to the event
sender.sendFailure(this, e);
+ e.printStackTrace(); // TODO: log failure
}
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java Mon Apr 20 11:19:48 2009
@@ -19,68 +19,108 @@
package org.apache.geronimo.blueprint.context;
import java.lang.reflect.Type;
+import java.lang.reflect.Method;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
+import java.util.Collection;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
import org.apache.xbean.recipe.AbstractRecipe;
import org.apache.xbean.recipe.ConstructionException;
+import org.apache.xbean.recipe.Recipe;
+import org.apache.xbean.recipe.CollectionRecipe;
+import org.apache.xbean.recipe.ExecutionContext;
import org.apache.geronimo.blueprint.LifeCycle;
import org.apache.geronimo.blueprint.BlueprintConstants;
+import org.apache.geronimo.blueprint.ModuleContextEventSender;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.service.blueprint.reflect.ServiceReferenceComponentMetadata;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.blueprint.reflect.UnaryServiceReferenceComponentMetadata;
+import org.osgi.service.blueprint.reflect.BindingListenerMetadata;
import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.osgi.service.blueprint.context.ModuleContext;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import net.sf.cglib.proxy.ProxyRefDispatcher;
import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Dispatcher;
/**
- * A recipe to create an OSGi service reference
+ * A recipe to create an unary OSGi service reference.
+ *
+ * TODO: check synchronization / thread safety
*
* @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
* @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
*/
-public class ReferenceServiceRecipe extends AbstractRecipe implements ProxyRefDispatcher, LifeCycle, ServiceTrackerCustomizer {
+public class ReferenceServiceRecipe extends AbstractRecipe implements Dispatcher, LifeCycle, ServiceListener {
- private final BundleContext bundleContext;
+ private final ModuleContext moduleContext;
+ private final ModuleContextEventSender sender;
private final UnaryServiceReferenceComponentMetadata metadata;
- private ServiceTracker tracker;
- private Class type;
+ private final CollectionRecipe listenersRecipe;
+ private Class proxyClass;
private String filter;
+ private List<Listener> listeners;
- public ReferenceServiceRecipe(BundleContext bundleContext, UnaryServiceReferenceComponentMetadata metadata) {
- this.bundleContext = bundleContext;
+ private volatile ServiceReference trackedServiceReference;
+ private volatile Object trackedService;
+ private final Object monitor = new Object();
+
+ public ReferenceServiceRecipe(ModuleContext moduleContext,
+ ModuleContextEventSender sender,
+ UnaryServiceReferenceComponentMetadata metadata,
+ CollectionRecipe listenersRecipe) {
+ this.moduleContext = moduleContext;
+ this.sender = sender;
this.metadata = metadata;
+ this.listenersRecipe = listenersRecipe;
}
protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
- // TODO: bindingListeners
// TODO: serviceAvailabilitySpecification
try {
- ClassLoader classLoader = new BundleDelegatingClassLoader(bundleContext.getBundle());
+ ClassLoader classLoader = new BundleDelegatingClassLoader(moduleContext.getBundleContext().getBundle(),
+ getClass().getClassLoader());
Enhancer e = new Enhancer();
e.setClassLoader(classLoader);
- type = getTargetClass(classLoader);
- e.setSuperclass(type);
+ e.setSuperclass(getTargetClass(classLoader));
e.setInterfaces(getInterfaces(classLoader));
e.setInterceptDuringConstruction(false);
e.setCallback(this);
e.setUseFactory(false);
Object obj = e.create();
+ proxyClass = obj.getClass();
+
+ if (listenersRecipe != null) {
+ listeners = (List<Listener>) listenersRecipe.create(classLoader);
+ for (Listener listener : listeners) {
+ listener.init(proxyClass);
+ }
+ } else {
+ listeners = Collections.emptyList();
+ }
filter = getOsgiFilter();
- tracker = new ServiceTracker(bundleContext, FrameworkUtil.createFilter(filter), this);
- tracker.open();
+ moduleContext.getBundleContext().addServiceListener(this, filter);
+ retrack();
+
+ if (getName() != null) {
+ ExecutionContext.getContext().addObject(getName(), obj);
+ }
return obj;
- } catch (Exception e) {
- throw new ConstructionException(e);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new ConstructionException(t);
}
}
@@ -134,6 +174,10 @@
for (String name : (Set<String>) metadata.getInterfaceNames()) {
Class clazz = classLoader.loadClass(name);
if (!clazz.isInterface()) {
+ if (root == Object.class) {
+ root = clazz;
+ continue;
+ }
// Check that all classes are in the same hierarchy
for (Class p = clazz; p != Object.class; p = p.getSuperclass()) {
if (p == root) {
@@ -156,14 +200,18 @@
return true;
}
- public Object loadObject(Object proxy) throws Exception {
- Object svc = tracker.getService();
+ public Object loadObject() throws Exception {
+ Object svc = trackedService;
if (svc == null && metadata.getTimeout() > 0) {
- // TODO: send WAIT event
- svc = tracker.waitForService(metadata.getTimeout());
+ Set<String> interfaces = (Set<String>) metadata.getInterfaceNames();
+ sender.sendWaiting(moduleContext, interfaces.toArray(new String[interfaces.size()]), filter);
+ synchronized (monitor) {
+ monitor.wait(metadata.getTimeout());
+ }
+ svc = trackedService;
}
if (svc == null) {
- throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", type, filter);
+ throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", proxyClass.getSuperclass(), filter);
}
return svc;
}
@@ -172,22 +220,186 @@
}
public void destroy() throws Exception {
- ServiceTracker t = tracker;
- tracker = null;
- if (t != null) {
- t.close();
+ moduleContext.getBundleContext().removeServiceListener(this);
+ }
+
+ private ServiceReference getBestServiceReference(ServiceReference[] references) {
+ int length = (references == null) ? 0 : references.length;
+ if (length == 0) { /* if no service is being tracked */
+ return null;
+ }
+ int index = 0;
+ if (length > 1) { /* if more than one service, select highest ranking */
+ int rankings[] = new int[length];
+ int count = 0;
+ int maxRanking = Integer.MIN_VALUE;
+ for (int i = 0; i < length; i++) {
+ Object property = references[i].getProperty(Constants.SERVICE_RANKING);
+ int ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+ rankings[i] = ranking;
+ if (ranking > maxRanking) {
+ index = i;
+ maxRanking = ranking;
+ count = 1;
+ } else {
+ if (ranking == maxRanking) {
+ count++;
+ }
+ }
+ }
+ if (count > 1) { /* if still more than one service, select lowest id */
+ long minId = Long.MAX_VALUE;
+ for (int i = 0; i < length; i++) {
+ if (rankings[i] == maxRanking) {
+ long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
+ if (id < minId) {
+ index = i;
+ minId = id;
+ }
+ }
+ }
+ }
}
+ return references[index];
}
- public Object addingService(ServiceReference reference) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ private void retrack() {
+ try {
+ ServiceReference[] refs = moduleContext.getBundleContext().getServiceReferences(null, filter);
+ ServiceReference ref = getBestServiceReference(refs);
+ if (ref != null) {
+ bind(ref);
+ } else {
+ unbind();
+ }
+ } catch (InvalidSyntaxException e) {
+ // Ignore, should never happen
+ }
}
- public void modifiedService(ServiceReference reference, Object service) {
- //To change body of implemented methods use File | Settings | File Templates.
+ private void track(ServiceReference ref) {
+ if (trackedServiceReference == null) {
+ bind(ref);
+ } else {
+ Object property = trackedServiceReference.getProperty(Constants.SERVICE_RANKING);
+ int trackedRanking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+ property = ref.getProperty(Constants.SERVICE_RANKING);
+ int newRanking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+ if (trackedRanking > newRanking) {
+ return;
+ } else if (trackedRanking == newRanking) {
+ long trackedId = ((Long) (trackedServiceReference.getProperty(Constants.SERVICE_ID))).longValue();
+ long newId = ((Long) (ref.getProperty(Constants.SERVICE_ID))).longValue();
+ if (trackedId < newId) {
+ return;
+ }
+ }
+ bind(ref);
+ }
}
- public void removedService(ServiceReference reference, Object service) {
- //To change body of implemented methods use File | Settings | File Templates.
+ private void bind(ServiceReference ref) {
+ synchronized (monitor) {
+ if (trackedServiceReference != null) {
+ moduleContext.getBundleContext().ungetService(trackedServiceReference);
+ }
+ trackedServiceReference = ref;
+ trackedService = moduleContext.getBundleContext().getService(trackedServiceReference);
+ for (Listener listener : listeners) {
+ listener.bind(trackedServiceReference, trackedService);
+ }
+ }
+ }
+
+ private void unbind() {
+ synchronized (monitor) {
+ if (trackedServiceReference != null) {
+ for (Listener listener : listeners) {
+ listener.unbind(trackedServiceReference, trackedService);
+ }
+ moduleContext.getBundleContext().ungetService(trackedServiceReference);
+ trackedServiceReference = null;
+ trackedService = null;
+ }
+ }
+ }
+
+ public void serviceChanged(ServiceEvent event) {
+ int eventType = event.getType();
+ ServiceReference ref = event.getServiceReference();
+ switch (eventType) {
+ case ServiceEvent.REGISTERED:
+ case ServiceEvent.MODIFIED:
+ track(ref);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ retrack();
+ break;
+ }
+ }
+
+ public static class Listener {
+
+ private Object listener;
+ private BindingListenerMetadata metadata;
+ private List<Method> bindMethodsOneArg;
+ private List<Method> bindMethodsTwoArgs;
+ private List<Method> unbindMethodsOneArg;
+ private List<Method> unbindMethodsTwoArgs;
+
+ public void init(Class proxyClass) {
+ Class listenerClass = listener.getClass();
+ Class[] oneArgParams = new Class[] { ServiceReference.class };
+ Class[] twoArgsParams = new Class[] { proxyClass, Map.class };
+ String bindName = metadata.getBindMethodName();
+ if (bindName != null) {
+ bindMethodsOneArg = ReflectionUtils.findCompatibleMethods(listenerClass, bindName, oneArgParams);
+ bindMethodsTwoArgs = ReflectionUtils.findCompatibleMethods(listenerClass, bindName, twoArgsParams);
+ } else {
+ bindMethodsOneArg = Collections.emptyList();
+ bindMethodsTwoArgs = Collections.emptyList();
+ }
+ String unbindName = metadata.getUnbindMethodName();
+ if (unbindName != null) {
+ unbindMethodsOneArg = ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, oneArgParams);
+ unbindMethodsTwoArgs = ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, twoArgsParams);
+ } else {
+ unbindMethodsOneArg = Collections.emptyList();
+ unbindMethodsTwoArgs = Collections.emptyList();
+ }
+ }
+
+ public void bind(ServiceReference reference, Object service) {
+ invokeMethods(bindMethodsOneArg, bindMethodsTwoArgs, reference, service);
+ }
+
+ public void unbind(ServiceReference reference, Object service) {
+ invokeMethods(unbindMethodsOneArg, unbindMethodsTwoArgs, reference, service);
+ }
+
+ private void invokeMethods(List<Method> oneArgMethods, List<Method> twoArgsMethods, ServiceReference reference, Object service) {
+ for (Method method : oneArgMethods) {
+ try {
+ method.invoke(listener, reference);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ Map<String, Object> props = null;
+ for (Method method : twoArgsMethods) {
+ if (props == null) {
+ props = new HashMap<String, Object>();
+ for (String name : reference.getPropertyKeys()) {
+ props.put(name, reference.getProperty(name));
+ }
+ }
+ try {
+ method.invoke(listener, service, props);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
}
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java Mon Apr 20 11:19:48 2009
@@ -20,6 +20,8 @@
import java.lang.reflect.Method;
import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
/**
* TODO: javadoc
@@ -48,15 +50,15 @@
return classes;
}
- public static Method findMethod(Class clazz, String name, Class[] paramTypes) {
+ public static Method findMethod(Class clazz, String name, Class[] paramTypes) {
try {
return clazz.getMethod(name, paramTypes);
} catch (NoSuchMethodException e) {
- return findCompatibileMethod(clazz, name, paramTypes);
+ return findCompatibleMethod(clazz, name, paramTypes);
}
}
- public static Method findCompatibileMethod(Class clazz, String name, Class[] paramTypes) {
+ public static Method findCompatibleMethod(Class clazz, String name, Class[] paramTypes) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
Class[] methodParams = method.getParameterTypes();
@@ -71,5 +73,23 @@
}
}
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()) && methodParams.length == paramTypes.length) {
+ boolean assignable = true;
+ for (int i = 0; i < paramTypes.length && assignable; i++) {
+ assignable = methodParams[i].isAssignableFrom(paramTypes[i]);
+ }
+ if (assignable) {
+ methods.add(method);
+ }
+ }
+ }
+ return methods;
+ }
+
}
Copied: geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestModuleContext.java (from r766585, geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/Test.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestModuleContext.java?p2=geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestModuleContext.java&p1=geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/Test.java&r1=766585&r2=766653&rev=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/Test.java (original)
+++ geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestModuleContext.java Mon Apr 20 11:19:48 2009
@@ -19,16 +19,22 @@
package org.apache.geronimo.blueprint.itests;
import java.net.URLDecoder;
+import java.util.Properties;
+import java.util.Hashtable;
import org.apache.servicemix.kernel.testing.support.AbstractIntegrationTest;
import org.apache.geronimo.blueprint.sample.Foo;
import org.apache.geronimo.blueprint.sample.Bar;
+import org.apache.geronimo.blueprint.sample.InterfaceA;
import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Constants;
import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.context.ServiceUnavailableException;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
-public class Test extends AbstractIntegrationTest {
+public class TestModuleContext extends AbstractIntegrationTest {
public void test() throws Exception {
Resource res = locateBundle(getBundle("org.apache.geronimo", "blueprint-sample"));
@@ -61,6 +67,10 @@
}
}
+ public void testUnaryReference() throws Exception {
+
+ }
+
/**
* The manifest to use for the "virtual bundle" created
* out of the test classes and resources in this project
Added: geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java?rev=766653&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java (added)
+++ geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java Mon Apr 20 11:19:48 2009
@@ -0,0 +1,144 @@
+/*
+ * 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.geronimo.blueprint.itests;
+
+import java.net.URLDecoder;
+import java.util.Properties;
+import java.util.Hashtable;
+
+import org.apache.servicemix.kernel.testing.support.AbstractIntegrationTest;
+import org.apache.geronimo.blueprint.sample.Foo;
+import org.apache.geronimo.blueprint.sample.Bar;
+import org.apache.geronimo.blueprint.sample.InterfaceA;
+import org.apache.geronimo.blueprint.sample.BindingListener;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Constants;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+public class TestReferences extends AbstractIntegrationTest {
+
+ public void testUnaryReference() throws Exception {
+ ModuleContext moduleContext = getOsgiService(ModuleContext.class, 5000);
+ assertNotNull(moduleContext);
+
+ BindingListener listener = (BindingListener) moduleContext.getComponent("bindingListener");
+ assertNull(listener.getA());
+ assertNull(listener.getReference());
+
+ InterfaceA a = (InterfaceA) moduleContext.getComponent("ref2");
+ try {
+ a.hello("world");
+ fail("A ServiceUnavailableException should have been thrown");
+ } catch (ServiceUnavailableException e) {
+ // Ignore, expected
+ }
+
+ ServiceRegistration reg1 = bundleContext.registerService(InterfaceA.class.getName(), new InterfaceA() {
+ public String hello(String msg) {
+ return "Hello " + msg + "!";
+ }
+ }, null);
+ assertNotNull(listener.getA());
+ assertNotNull(listener.getReference());
+ assertEquals("Hello world!", a.hello("world"));
+
+ Hashtable props = new Hashtable();
+ props.put(Constants.SERVICE_RANKING, Integer.valueOf(1));
+ ServiceRegistration reg2 = bundleContext.registerService(InterfaceA.class.getName(), new InterfaceA() {
+ public String hello(String msg) {
+ return "Good morning " + msg + "!";
+ }
+ }, props);
+ assertNotNull(listener.getA());
+ assertNotNull(listener.getReference());
+ assertEquals("Good morning world!", a.hello("world"));
+
+ reg2.unregister();
+ assertNotNull(listener.getA());
+ assertNotNull(listener.getReference());
+ assertEquals("Hello world!", a.hello("world"));
+
+ reg1.unregister();
+ assertNull(listener.getA());
+ assertNull(listener.getReference());
+ try {
+ a.hello("world");
+ fail("A ServiceUnavailableException should have been thrown");
+ } catch (ServiceUnavailableException e) {
+ // Ignore, expected
+ }
+ }
+
+ /**
+ * The manifest to use for the "virtual bundle" created
+ * out of the test classes and resources in this project
+ *
+ * This is actually the boilerplate manifest with one additional
+ * import-package added. We should provide a simpler customization
+ * point for such use cases that doesn't require duplication
+ * of the entire manifest...
+ */
+ protected String getManifestLocation() {
+ return "classpath:org/apache/geronimo/blueprint/MANIFEST.MF";
+ }
+
+ /**
+ * The location of the packaged OSGi bundles to be installed
+ * for this test. Values are Spring resource paths. The bundles
+ * we want to use are part of the same multi-project maven
+ * build as this project is. Hence we use the localMavenArtifact
+ * helper method to find the bundles produced by the package
+ * phase of the maven build (these tests will run after the
+ * packaging phase, in the integration-test phase).
+ *
+ * JUnit, commons-logging, spring-core and the spring OSGi
+ * test bundle are automatically included so do not need
+ * to be specified here.
+ */
+ protected String[] getTestBundlesNames() {
+ return new String[] {
+ getBundle("org.apache.geronimo", "blueprint-bundle"),
+ getBundle("org.apache.geronimo", "blueprint-sample"),
+ };
+ }
+
+ private Bundle installBundle(Resource location) throws Exception {
+ Assert.notNull(bundleContext);
+ Assert.notNull(location);
+ if (logger.isDebugEnabled())
+ logger.debug("Installing bundle from location " + location.getDescription());
+
+ String bundleLocation;
+
+ try {
+ bundleLocation = URLDecoder.decode(location.getURL().toExternalForm(), "UTF-8");
+ }
+ catch (Exception ex) {
+ // the URL cannot be created, fall back to the description
+ bundleLocation = location.getDescription();
+ }
+
+ return bundleContext.installBundle(bundleLocation, location.getInputStream());
+ }
+
+}
\ No newline at end of file
Added: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/BindingListener.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/BindingListener.java?rev=766653&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/BindingListener.java (added)
+++ geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/BindingListener.java Mon Apr 20 11:19:48 2009
@@ -0,0 +1,59 @@
+/**
+ * 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.geronimo.blueprint.sample;
+
+import java.util.Map;
+import java.io.Serializable;
+
+import org.osgi.framework.ServiceReference;
+
+public class BindingListener {
+
+ private InterfaceA a;
+ private Map props;
+ private ServiceReference reference;
+
+ public InterfaceA getA() {
+ return a;
+ }
+
+ public Map getProps() {
+ return props;
+ }
+
+ public ServiceReference getReference() {
+ return reference;
+ }
+
+ public void bind(InterfaceA a, Map props) {
+ this.a = a;
+ this.props = props;
+ }
+
+ public void bind(ServiceReference ref) {
+ this.reference = ref;
+ }
+
+ public void unbind(InterfaceA a, Map props) {
+ this.a = null;
+ this.props = null;
+ }
+
+ public void unbind(ServiceReference ref) {
+ this.reference = null;
+ }
+}
Copied: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java (from r766585, geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooListener.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java?p2=geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java&p1=geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooListener.java&r1=766585&r2=766653&rev=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooListener.java (original)
+++ geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java Mon Apr 20 11:19:48 2009
@@ -19,7 +19,7 @@
import java.io.Serializable;
import java.util.Map;
-public class FooListener {
+public class FooRegistrationListener {
public void serviceRegistered(Serializable foo, Map props) {
System.out.println("Service registration notification: " + foo + " " + props);
Propchange: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/FooRegistrationListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/InterfaceA.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/InterfaceA.java?rev=766653&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/InterfaceA.java (added)
+++ geronimo/sandbox/blueprint/blueprint-sample/src/main/java/org/apache/geronimo/blueprint/sample/InterfaceA.java Mon Apr 20 11:19:48 2009
@@ -0,0 +1,22 @@
+/**
+ * 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.geronimo.blueprint.sample;
+
+public interface InterfaceA {
+
+ String hello(String msg);
+}
Modified: geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml?rev=766653&r1=766652&r2=766653&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml (original)
+++ geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml Mon Apr 20 11:19:48 2009
@@ -35,16 +35,24 @@
<component id="converter2" class="org.apache.geronimo.blueprint.sample.CurrencyTypeConverter"/>
<service ref="foo" auto-export="all-classes">
- <registration-listener ref="fooListener"
- registration-method="serviceRegistered"
- unregistration-method="serviceUnregistered"/>
-
<service-properties>
<entry key="key" value="value"/>
</service-properties>
+ <registration-listener ref="fooRegistrationListener"
+ registration-method="serviceRegistered"
+ unregistration-method="serviceUnregistered"/>
</service>
- <component id="fooListener" class="org.apache.geronimo.blueprint.sample.FooListener"/>
-
+ <component id="fooRegistrationListener" class="org.apache.geronimo.blueprint.sample.FooRegistrationListener"/>
+
+ <reference id="ref" interface="org.apache.geronimo.blueprint.sample.Foo">
+ </reference>
+
+ <reference id="ref2" interface="org.apache.geronimo.blueprint.sample.InterfaceA" timeout="100">
+ <listener bind-method="bind" unbind-method="unbind" ref="bindingListener" />
+ </reference>
+
+ <component id="bindingListener" class="org.apache.geronimo.blueprint.sample.BindingListener"/>
+
</components>