Author: not
Date: Mon Mar 1 23:53:18 2010
New Revision: 917809
URL: http://svn.apache.org/viewvc?rev=917809&view=rev
Log:
ARIES-128 Implement OSGi spec url lookup scheme
Added:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
- copied, changed from r910238,
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
- copied, changed from r910238,
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
- copied, changed from r917002,
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
Removed:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
Modified:
incubator/aries/trunk/jndi/jndi-url/pom.xml
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
+++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar 1 23:53:18 2010
@@ -33,6 +33,10 @@
<dependencies>
<dependency>
+ <groupId>org.apache.aries</groupId>
+ <artifactId>org.apache.aries.util</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<scope>provided</scope>
Modified:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
Mon Mar 1 23:53:18 2010
@@ -18,18 +18,30 @@
*/
package org.apache.aries.jndi.services;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import javax.naming.NamingException;
+
+import org.apache.aries.util.BundleToClassLoaderAdapter;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleReference;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceException;
import org.osgi.framework.ServiceReference;
/**
@@ -47,221 +59,206 @@
*/
public final class ServiceHelper
{
- /** The bundle context used for service registry queries */
- private static BundleContext context;
- /** A cache of what service was returned last time the query was performed */
- private static ConcurrentMap<ServiceKey, Set<ServiceReference>> cache = new
ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
-
- public static void setBundleContext(BundleContext ctx)
+ public static class StackFinder extends SecurityManager
{
- context = ctx;
+ public Class<?>[] getClassContext()
+ {
+ return super.getClassContext();
+ }
}
-
- /**
- * This class is used as the key into the cache. It holds information to identify
- * who performed the query, along with the className and filter used. The thread context
- * class loader is used in the key, so two different modules will
potentially get different
- * services.
- */
- private static final class ServiceKey
+
+ private static class JNDIServiceDamper implements InvocationHandler
{
- /** The class loader of the invoking application */
- private ClassLoader classLoader;
- /** The name of the class being queried from the registry */
- private String className;
- /** the registry filter, this may be null */
+ private BundleContext ctx;
+ private ServicePair pair;
+ private String interfaceName;
private String filter;
- /** The cached hashCode */
- private final int hashCode;
-
- /**
- * Boring unimportant comment.
- *
- * @param cl
- * @param cn
- * @param f
- */
- public ServiceKey(ClassLoader cl, String cn, String f)
+ private boolean dynamic;
+
+ public JNDIServiceDamper(BundleContext context, String i, String f, ServicePair service, boolean d)
{
- classLoader = cl;
- className = cn;
+ ctx = context;
+ pair = service;
+ interfaceName = i;
filter = f;
-
- int classNameHash = (className == null) ? 0 : className.hashCode();
- hashCode = System.identityHashCode(classLoader) * 1000003 +
classNameHash;
+ dynamic = d;
}
-
- @Override
- public int hashCode()
- {
- return hashCode;
- }
-
- @Override
- public boolean equals(Object other)
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
- if (other == this) return true;
- if (other == null) return false;
-
- if (other instanceof ServiceKey) {
- ServiceKey otherKey = (ServiceKey) other;
- if (hashCode != otherKey.hashCode) return false;
-
- if (classLoader != otherKey.classLoader) return false;
- if (!!!comparePossiblyNullObjects(className, otherKey.className))
return false;
- return comparePossiblyNullObjects(filter, otherKey.filter);
- }
-
- return false;
- }
-
- /**
- * Compares two objects where one or other (or both) may be null.
- *
- * @param a the first object to compare.
- * @param b the second object to compare.
- * @return true if they are ==, both null or identity equals, false
otherwise.
- */
- public boolean comparePossiblyNullObjects(Object a, Object b) {
- if (a == b) return true;
- else if (a == null) return false;
- else return a.equals(b);
+ if (pair.ref.getBundle() == null) {
+ if (dynamic) pair = findService(ctx, interfaceName, filter);
+ else pair = null;
+ }
+
+ if (pair == null) {
+ throw new ServiceException(interfaceName,
ServiceException.UNREGISTERED);
+ }
+
+ return method.invoke(pair.service, args);
}
}
-
- /**
- * This method is used to obtain a single instance of a desired service from
the OSGi
- * service registry. If the filter and class name identify multiple services
the first
- * one is returned. If no service is found null will be returned.
- *
- * @param className The class name used to register the desired service. If null is provided
- * then all services are eligible to be returned.
- * @param filter An RFC 1960 query into the properties of the registered
services. e.g.
- * (service.description=really useful)
- * @return The desired service
- *
- * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what
- * it should be.
- */
- public static Object getService(String className, String filter) throws
IllegalArgumentException
+
+ private static class ServicePair
{
- Object service = null;
- try {
- BundleContext callerCtx = getBundleContext();
- ServiceReference[] refs = callerCtx.getServiceReferences(className,
filter);
-
- if (refs != null) {
- // we need to sort the references returned in case they are out of
order
- // we need to sort in the reverse natural order, services with higher
- // ranking or lower id should be processed first so should be earlier in the array.
- Arrays.sort(refs, new Comparator<ServiceReference>() {
- public int compare(ServiceReference o1, ServiceReference o2)
- {
- return o2.compareTo(o1);
- }
- });
-
- for (ServiceReference ref : refs) {
- List<Object> services = getServices(callerCtx, className, filter,
ref);
- if (!!!services.isEmpty()) {
- service = services.get(0);
- break;
- }
- }
- }
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
-
- return service;
+ private ServiceReference ref;
+ private Object service;
}
/**
- * This method is used to obtain a list of service instances from the OSGi
- * service registry. If no service is found an empty list will be returned.
- *
- * @param className The class name used to register the desired service. If null is provided
- * then all services are eligible to be returned.
- * @param filter An RFC 1960 query into the properties of the registered
services. e.g.
- * (service.description=really useful)
- * @return A list of matching services.
- *
- * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what
- * it should be.
+ * @param env
+ * @return the bundle context for the caller.
+ * @throws NamingException
*/
- public static List<?> getServices(String className, String filter)
- throws IllegalArgumentException
+ public static BundleContext getBundleContext(Map<String, Object> env) throws
NamingException
{
- List<Object> services;
- try {
- BundleContext callerCtx = getBundleContext();
- ServiceReference[] refs = callerCtx.getAllServiceReferences(className,
filter);
+ BundleContext result = null;
+
+ Object bc = env.get("osgi.service.jndi.bundleContext");
+
+ if (bc != null && bc instanceof BundleContext) result = (BundleContext) bc;
+ else {
+ ClassLoader cl = AccessController.doPrivileged(new
PrivilegedAction<ClassLoader>() {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
- services = getServices(callerCtx, className, filter, refs);
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
+ result = getBundleContext(cl);
+ }
+
+ if (result == null) {
+ StackTraceElement[] stackTrace = AccessController.doPrivileged(new
PrivilegedAction<StackTraceElement[]>() {
+ public StackTraceElement[] run()
+ {
+ return Thread.currentThread().getStackTrace();
+ }
+ });
+
+ StackFinder finder = new StackFinder();
+ Class<?>[] classStack = finder.getClassContext();
+
+ boolean found = false;
+ boolean foundLookup = false;
+ int i = 0;
+ for (; i < stackTrace.length && !!!found; i++) {
+ if (!!!foundLookup && "lookup".equals(stackTrace[i].getMethodName())) {
+ foundLookup = true;
+ } else if (foundLookup &&
!!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi") ||
+
stackTrace[i].getClassName().startsWith("javax.naming"))) {
+ found = true;
+ }
+ }
+
+ if (found) {
+ Set<Integer> classLoadersChecked = new HashSet<Integer>();
+ for (; i < classStack.length && result == null; i++) {
+ ClassLoader cl = classStack[i].getClassLoader();
+ int hash = System.identityHashCode(cl);
+ if (!!!classLoadersChecked.contains(hash)) {
+ classLoadersChecked.add(hash);
+ result = getBundleContext(cl);
+ }
+ }
+ // Now we walk the stack looking for the BundleContext
+ }
}
- return services;
+ if (result == null) throw new NamingException("Unable to find
BundleContext");
+
+ return result;
}
-
- /**
- * @return the bundle context for the caller.
- */
- private static BundleContext getBundleContext()
+
+ private static BundleContext getBundleContext(ClassLoader cl)
{
BundleContext result = null;
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
while (result == null && cl != null) {
if (cl instanceof BundleReference) {
result = ((BundleReference)cl).getBundle().getBundleContext();
} else if (cl != null) {
cl = cl.getParent();
}
- }
+ }
- if (result == null) result = context;
return result;
}
- /**
- * This worker method obtains the requested service(s) and if the service(s)
- * exist updates the cache and releases the previous service(s).
- *
- * @param callerCtx The caller context.
- * @param className The class name used to query for the service.
- * @param filter The filter name used to query for the service.
- * @param refs The references to get.
- * @return The service, if one was found, or null.
- */
- private static List<Object> getServices(BundleContext callerCtx, String
className, String filter, ServiceReference...refs)
+ public static Object getService(String interface1, String filter, String
serviceName, boolean dynamicRebind, Map<String, Object> env) throws
NamingException
{
- List<Object> data = new LinkedList<Object>();
+ Object result = null;
+
+ BundleContext ctx = getBundleContext(env);
+
+ ServicePair pair = findService(ctx, interface1, filter);
- if (refs != null) {
- Set<ServiceReference> refSet = new HashSet<ServiceReference>();
- for (ServiceReference ref : refs) {
- Object service = callerCtx.getService(ref);
- if (service != null) {
- data.add(service);
- refSet.add(ref);
+ if (pair == null) {
+ interface1 = null;
+ filter = "(osgi.jndi.serviceName=" + serviceName + ")";
+ pair = findService(ctx, interface1, filter);
+ }
+
+ if (pair != null) {
+ String[] interfaces = (String[]) pair.ref.getProperty("objectClass");
+
+ List<Class<?>> clazz = new ArrayList<Class<?>>(interfaces.length);
+
+ Bundle b = ctx.getBundle();
+
+ for (String interfaceName : interfaces) {
+ try {
+ clazz.add(b.loadClass(interfaceName));
+ } catch (ClassNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
}
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- ServiceKey key = new ServiceKey(cl, className, filter);
+ if (clazz.isEmpty()) {
+ throw new IllegalArgumentException();
+ }
- // we do not need any synchronization around this. The map is concurrent
- // and until here we do not touch any shared state.
- refSet = cache.put(key, refSet);
+ InvocationHandler ih = new JNDIServiceDamper(ctx, interface1, filter,
pair, dynamicRebind);
- if (refSet != null) {
- for (ServiceReference ref : refSet) {
- callerCtx.ungetService(ref);
+ result = Proxy.newProxyInstance(new BundleToClassLoaderAdapter(b),
clazz.toArray(new Class<?>[clazz.size()]), ih);
+ }
+
+ return result;
+ }
+
+ private static ServicePair findService(BundleContext ctx, String interface1,
String filter)
+ {
+ ServicePair p = null;
+
+ try {
+ ServiceReference[] refs = ctx.getServiceReferences(interface1, filter);
+
+ if (refs != null) {
+ // natural order is the exact opposite of the order we desire.
+ Arrays.sort(refs, new Comparator<ServiceReference>() {
+ public int compare(ServiceReference o1, ServiceReference o2)
+ {
+ return o2.compareTo(o1);
+ }
+ });
+
+ for (ServiceReference ref : refs) {
+ Object service = ctx.getService(ref);
+
+ if (service != null) {
+ p = new ServicePair();
+ p.ref = ref;
+ p.service = service;
+ break;
+ }
}
}
+
+ } catch (InvalidSyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
- return data;
+ return p;
}
}
Modified:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
Mon Mar 1 23:53:18 2010
@@ -34,8 +34,6 @@
public void start(BundleContext context)
{
- ServiceHelper.setBundleContext(context);
-
Hashtable<Object, Object> props = new Hashtable<Object, Object>();
props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
reg = context.registerService(ObjectFactory.class.getName(), new
OsgiURLContextFactory(), props);
Copied:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
(from r910238,
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
Mon Mar 1 23:53:18 2010
@@ -21,28 +21,104 @@
import java.util.Enumeration;
import javax.naming.CompositeName;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
/**
- * A composite name for the aries namespace. We only have this so that we can
- * provide a nicer toString()
+ * A composite name for the aries namespace. This provides useful utility
methods
+ * for accessing the name.
+ *
+ * component 0: osgi:service, aries:services, osgi:servicelist
+ * component 1: interface
+ * component 2: filter
*/
-public final class ServiceRegistryName extends CompositeName
+public final class OsgiName extends CompositeName
{
/** The serial version UID */
private static final long serialVersionUID = 6617580228852444656L;
+ public static final String OSGI_SCHEME = "osgi";
+ public static final String ARIES_SCHEME = "aries";
+ public static final String SERVICE_PATH = "service";
+ public static final String SERVICES_PATH = "services";
+ public static final String SERVICE_LIST_PATH = "servicelist";
+ public static final String FRAMEWORK_PATH = "framework";
- @Override
- public String toString()
+ public OsgiName(String name) throws InvalidNameException
{
- StringBuilder buffer = new StringBuilder();
+ super(name);
+ }
+
+ public OsgiName(Name name) throws InvalidNameException
+ {
+ this(name.toString());
+ }
+
+ public boolean hasFilter()
+ {
+ return size() == 3;
+ }
+
+ public boolean isServiceNameBased()
+ {
+ return size() > 3;
+ }
+
+ public String getScheme()
+ {
+ String part0 = get(0);
+ int index = part0.indexOf(':');
+
+ String result;
+
+ if (index > 0) {
+ result = part0.substring(0, index);
+ } else {
+ result = null;
+ }
+
+ return result;
+ }
+
+ public String getSchemePath()
+ {
+ String part0 = get(0);
+ int index = part0.indexOf(':');
+
+ String result;
- buffer.append("aries:services");
- Enumeration<String> components = getAll();
- while (components.hasMoreElements()) {
- buffer.append('/');
- buffer.append(components.nextElement());
+ if (index > 0) {
+ result = part0.substring(index + 1);
+ } else {
+ result = null;
}
- return buffer.toString();
+ return result;
+ }
+
+ public String getInterface()
+ {
+ return get(1);
+ }
+
+ public String getFilter()
+ {
+ return hasFilter() ? get(2) : null;
+ }
+
+ public String getServiceName()
+ {
+ Enumeration<String> parts = getAll();
+ parts.nextElement();
+
+ StringBuilder builder = new StringBuilder();
+
+ while (parts.hasMoreElements()) {
+ builder.append(parts.nextElement());
+ builder.append('/');
+ }
+
+ builder.deleteCharAt(builder.length() - 1);
+
+ return builder.toString();
}
}
\ No newline at end of file
Copied:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
(from r910238,
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
Mon Mar 1 23:53:18 2010
@@ -26,31 +26,40 @@
/**
* A parser for the aries namespace
*/
-public final class ServiceRegistryNameParser implements NameParser
+public final class OsgiNameParser implements NameParser
{
-
+ private static final String OSGI_SCHEME = "osgi";
+ private static final String ARIES_SCHEME = "aries";
+ private static final String SERVICE_PATH = "service";
+ private static final String SERVICES_PATH = "services";
+ private static final String SERVICE_LIST_PATH = "servicelist";
+ private static final String FRAMEWORK_PATH = "framework";
+
public Name parse(String name) throws NamingException
{
- if (!!!name.startsWith("aries:services/") &&
- !!!name.startsWith("osgi:services/")) throw new InvalidNameException("The
JNDI name did not start with aries:, or osgi:");
+ OsgiName result = new OsgiName(name);
+
+ if (result.size() < 2) throw new InvalidNameException(name);
- name = name.substring(name.indexOf('/') + 1);
+ String urlScheme = result.getScheme();
+ String schemePath = result.getSchemePath();
- int slashIndex = name.indexOf('/');
- String interfaceName = name;
- String filter = null;
-
- if (slashIndex != -1) {
- interfaceName = name.substring(0, slashIndex);
- filter = name.substring(slashIndex + 1);
+ if (!!!(OSGI_SCHEME.equals(urlScheme) || ARIES_SCHEME.equals(urlScheme))) {
+ throw new InvalidNameException(name);
}
- if (interfaceName.length() == 0) throw new InvalidNameException("No interface name was specified");
+ if (ARIES_SCHEME.equals(urlScheme) && !!!SERVICES_PATH.equals(schemePath))
{
+ throw new InvalidNameException(name);
+ }
+
+ if (OSGI_SCHEME.equals(urlScheme) && !!!( SERVICE_PATH.equals(schemePath) ||
+ SERVICE_LIST_PATH.equals(schemePath) ||
+ FRAMEWORK_PATH.equals(schemePath))) {
+ throw new InvalidNameException(name);
+ }
- Name result = new ServiceRegistryName();
- result.add(interfaceName);
- if (filter != null) {
- result.add(filter);
+ if (result.getInterface() == null || result.getInterface().length() == 0) {
+ throw new InvalidNameException(name);
}
return result;
@@ -59,7 +68,7 @@
@Override
public boolean equals(Object other)
{
- return other instanceof ServiceRegistryNameParser;
+ return other instanceof OsgiNameParser;
}
@Override
Modified:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
Mon Mar 1 23:53:18 2010
@@ -49,7 +49,7 @@
} else if (obj instanceof String[]) {
// Try each URL until either lookup succeeds or they all fail
String[] urls = (String[])obj;
- if (urls.length == 0) throw new
ConfigurationException("ariesURLContextFactory: empty URL array");
+ if (urls.length == 0) throw new ConfigurationException("0");
Context context = new ServiceRegistryContext(environment);
try
{
Modified:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
Mon Mar 1 23:53:18 2010
@@ -42,9 +42,9 @@
{
private static final String ARIES_SERVICES = "aries:services/";
/** The name parser for the service registry name space */
- private NameParser parser = new ServiceRegistryNameParser();
+ private NameParser parser = new OsgiNameParser();
/** The environment for this context */
- private Map<Object, Object> env;
+ private Map<String, Object> env;
/**
* Why Mr Java this class does indeed take a fine copy of the provided
@@ -53,10 +53,11 @@
*
* @param environment
*/
+ @SuppressWarnings("unchecked")
public ServiceRegistryContext(Hashtable<?, ?> environment)
{
- env = new HashMap<Object, Object>();
- env.putAll(environment);
+ env = new HashMap<String, Object>();
+ env.putAll((Map<? extends String, ? extends Object>) environment);
}
public Object addToEnvironment(String propName, Object propVal) throws NamingException
@@ -153,7 +154,7 @@
public NamingEnumeration<NameClassPair> list(final Name name) throws NamingException
{
- throw new NamingException("Not a Context");
+ return new ServiceRegistryListContext(env, convert(name)).list("");
}
public NamingEnumeration<NameClassPair> list(String name) throws NamingException
@@ -163,7 +164,7 @@
public NamingEnumeration<Binding> listBindings(final Name name) throws NamingException
{
- throw new NamingException("Not a Context");
+ return new ServiceRegistryListContext(env, convert(name)).listBindings("");
}
public NamingEnumeration<Binding> listBindings(String name) throws NamingException
@@ -173,28 +174,43 @@
public Object lookup(Name name) throws NamingException
{
- int nameSize = validateName(name);
- String className = name.get(0);
-
- String filter = null;
+ Object result;
+
+ OsgiName validName = convert(name);
- if (nameSize == 2) {
- filter = name.get(1);
+ String pathFragment = validName.getSchemePath();
+ String serviceName = validName.getServiceName();
+ String schemeName = validName.getScheme();
+
+ if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) && "bundleContext".equals(validName.getServiceName())) {
+ result = ServiceHelper.getBundleContext(env);
+ } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
OsgiName.OSGI_SCHEME.equals(schemeName)) ||
+ (OsgiName.SERVICES_PATH.equals(pathFragment) &&
OsgiName.ARIES_SCHEME.equals(schemeName))) {
+ result = ServiceHelper.getService(validName.getInterface(),
validName.getFilter(), serviceName, true, env);
+ } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
+ result = new ServiceRegistryListContext(env, validName);
+ } else {
+ result = null;
}
- try {
- Object result = ServiceHelper.getService(className, filter);
-
- if (result == null) {
- throw new NameNotFoundException("We couldn't find an object in the registry
matching the query " + name);
- }
-
- return result;
- } catch (IllegalArgumentException e) {
- NamingException ne = new NamingException(e.getMessage());
- ne.initCause(e);
- throw ne;
+ if (result == null) {
+ throw new NameNotFoundException(name.toString());
+ }
+
+ return result;
+ }
+
+ private OsgiName convert(Name name) throws InvalidNameException
+ {
+ OsgiName result;
+
+ if (name instanceof OsgiName) {
+ result = (OsgiName) name;
+ } else {
+ result = new OsgiName(name);
}
+
+ return result;
}
public Object lookup(String name) throws NamingException
@@ -246,27 +262,4 @@
{
throw new OperationNotSupportedException();
}
-
- /**
- * Check that the name conforms to the expected format
- * @param name
- * @return the size of the name
- * @throws InvalidNameException
- */
- private int validateName(final Name name) throws InvalidNameException
- {
- int nameSize = name.size();
- if (nameSize == 0) {
- throw new InvalidNameException("The provided name does not have any
components" + name);
- }
-
- if ("aries:services".equals(name.get(0))) {
- throw new InvalidNameException("The composite name should not start with
aries:services");
- }
-
- if (nameSize > 2) {
- throw new InvalidNameException("This JNDI context only expects 2 components,
but it found " + nameSize);
- }
- return nameSize;
- }
}
\ No newline at end of file
Added:
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
(added)
+++
incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
Mon Mar 1 23:53:18 2010
@@ -0,0 +1,197 @@
+/*
+ * 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.jndi.url;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+
+public class ServiceRegistryListContext implements Context
+{
+ private Map<String, Object> env;
+ /** The name parser for the service registry name space */
+ private NameParser parser = new OsgiNameParser();
+
+ public ServiceRegistryListContext(Map<String, Object> env, OsgiName validName)
+ {
+ this.env = new HashMap<String, Object>(env);
+ }
+
+ public Object addToEnvironment(String propName, Object propVal) throws
NamingException
+ {
+ return env.put(propName, propVal);
+ }
+
+ public void bind(Name name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void bind(String name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void close() throws NamingException
+ {
+ env = null;
+ parser = null;
+ }
+
+ public Name composeName(Name name, Name prefix) throws NamingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String composeName(String name, String prefix) throws NamingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Context createSubcontext(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public Context createSubcontext(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void destroySubcontext(Name name) throws NamingException
+ {
+ //No-op we don't support sub-contexts in our context
+ }
+
+ public void destroySubcontext(String name) throws NamingException
+ {
+ //No-op we don't support sub-contexts in our context
+ }
+
+ public Hashtable<?, ?> getEnvironment() throws NamingException
+ {
+ Hashtable<Object, Object> environment = new Hashtable<Object, Object>();
+ environment.putAll(env);
+ return environment;
+ }
+
+ public String getNameInNamespace() throws NamingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public NameParser getNameParser(Name name) throws NamingException
+ {
+ return parser;
+ }
+
+ public NameParser getNameParser(String name) throws NamingException
+ {
+ return parser;
+ }
+
+ public NamingEnumeration<NameClassPair> list(Name name) throws
NamingException
+ {
+ return list(name.toString());
+ }
+
+ public NamingEnumeration<NameClassPair> list(String name) throws
NamingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public NamingEnumeration<Binding> listBindings(Name name) throws
NamingException
+ {
+ return listBindings(name.toString());
+ }
+
+ public NamingEnumeration<Binding> listBindings(String name) throws
NamingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object lookup(Name name) throws NamingException
+ {
+ return lookup(name.toString());
+ }
+
+ public Object lookup(String name) throws NamingException
+ {
+ return null;
+ }
+
+ public Object lookupLink(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public Object lookupLink(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rebind(Name name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rebind(String name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public Object removeFromEnvironment(String propName) throws NamingException
+ {
+ return env.remove(propName);
+ }
+
+ public void rename(Name oldName, Name newName) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rename(String oldName, String newName) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void unbind(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void unbind(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+}
\ No newline at end of file
Copied:
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
(from r917002,
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
Mon Mar 1 23:53:18 2010
@@ -18,11 +18,11 @@
*/
package org.apache.aries.jndi.url;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import javax.naming.InvalidNameException;
-import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingException;
@@ -31,10 +31,10 @@
/**
* This is where we test the service registry name parser.
*/
-public class ServiceRegistryNameParserTest
+public class OsgiNameParserTest
{
/** The parser we are going to use for testing */
- private NameParser parser = new ServiceRegistryNameParser();
+ private NameParser parser = new OsgiNameParser();
/**
* OK, so we check that we can call checkNames multiple times.
@@ -43,8 +43,14 @@
@Test
public void checkValidNames() throws NamingException
{
- checkName("aries:services/java.lang.Runnable/(a=b)");
- checkName("aries:services/java.lang.Runnable");
+ checkName("aries","services","java.lang.Runnable","(a=b)");
+ checkName("aries","services","java.lang.Runnable");
+ checkName("osgi","service","java.lang.Runnable");
+ checkName("osgi","service","java.lang.Runnable", "(a=b)");
+ checkName("osgi","servicelist","java.lang.Runnable");
+ checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
+ checkName("osgi","servicelist","jdbc", "grok", "DataSource");
+ checkName("osgi", "framework", "bundleContext");
}
/**
@@ -54,7 +60,7 @@
@Test(expected=InvalidNameException.class)
public void checkOutsideNamespace() throws NamingException
{
- checkName("java:comp/env/jms/cf");
+ checkName("java","comp","env","jms","cf");
}
/**
@@ -64,7 +70,7 @@
@Test(expected=InvalidNameException.class)
public void checkMissingInterface() throws NamingException
{
- checkName("aries:services");
+ checkName("aries","services");
}
/**
@@ -75,20 +81,64 @@
@Test(expected=InvalidNameException.class)
public void checkMissingInterface2() throws NamingException
{
- checkName("aries:services/");
+ checkName("aries","services", "");
}
-
- /**
- * This method parses the name and then makes sure what was parsed was parsed
- * correctly.
- *
- * @param name
- * @throws NamingException
- */
- private void checkName(String name) throws NamingException
+
+ @Test(expected=InvalidNameException.class)
+ public void checkIncorrectPath() throws NamingException
+ {
+ checkName("osgi", "services", "java.lang.Runnable");
+ }
+
+ @Test(expected=InvalidNameException.class)
+ public void checkIllegalPath() throws NamingException
{
- Name n = parser.parse(name);
- assertNotNull("We got a null name back, which is not allowed.", n);
- assertEquals("The name's toString does not produce the original value",
name, n.toString());
+ checkName("osgi", "wibble", "java.lang.Runnable");
+ }
+
+ private void checkName(String scheme, String path, String ... elements)
+ throws NamingException
+ {
+ StringBuilder builder = new StringBuilder();
+ StringBuilder serviceName = new StringBuilder();
+
+ builder.append(scheme);
+ builder.append(':');
+ builder.append(path);
+
+ if (elements.length > 0) {
+ builder.append('/');
+
+ for (String element : elements) {
+ serviceName.append(element);
+ serviceName.append('/');
+ }
+
+ serviceName.deleteCharAt(serviceName.length() - 1);
+
+ builder.append(serviceName);
+ }
+
+ OsgiName n = (OsgiName) parser.parse(builder.toString());
+
+ assertEquals(scheme, n.getScheme());
+ assertEquals(path, n.getSchemePath());
+
+ if (elements.length > 1) {
+ assertEquals(elements[0], n.getInterface());
+ }
+
+ if (elements.length == 1) {
+ assertFalse(n.hasFilter());
+ }
+
+ if (elements.length > 2) {
+ if (elements.length == 2) {
+ assertTrue(n.hasFilter());
+ assertEquals(elements[1], n.getFilter());
+ } else assertFalse(n.hasFilter());
+ }
+
+ assertEquals(serviceName.toString(), n.getServiceName());
}
}
\ No newline at end of file
Modified:
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
==============================================================================
---
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
(original)
+++
incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
Mon Mar 1 23:53:18 2010
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
@@ -37,6 +36,12 @@
import javax.naming.NamingException;
import javax.naming.spi.ObjectFactory;
+import org.apache.aries.jndi.ContextHelper;
+import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
+import org.apache.aries.mocks.BundleContextMock;
+import org.apache.aries.mocks.BundleMock;
+import org.apache.aries.unittest.mocks.MethodCall;
+import org.apache.aries.unittest.mocks.Skeleton;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -47,22 +52,13 @@
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-import org.apache.aries.unittest.mocks.MethodCall;
-import org.apache.aries.unittest.mocks.Skeleton;
-import org.apache.aries.jndi.ContextHelper;
-import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
-import org.apache.aries.jndi.services.ServiceHelper;
-import org.apache.aries.jndi.url.Activator;
-import org.apache.aries.mocks.BundleContextMock;
-import org.apache.aries.mocks.BundleMock;
-
/**
* Tests for our JNDI implementation for the service registry.
*/
public class ServiceRegistryContextTest
{
/** The service we register by default */
- private Thread service;
+ private Runnable service;
/** The bundle context for the test */
private BundleContext bc;
/** The service registration for the service */
@@ -83,10 +79,7 @@
new Activator().start(bc);
new org.apache.aries.jndi.startup.Activator().start(bc);
- Field f = ServiceHelper.class.getDeclaredField("context");
- f.setAccessible(true);
- f.set(null, bc);
- f = ContextHelper.class.getDeclaredField("context");
+ Field f = ContextHelper.class.getDeclaredField("context");
f.setAccessible(true);
f.set(null, bc);
f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
@@ -94,7 +87,7 @@
f.set(null, bc);
- service = new Thread();
+ service = Skeleton.newMock(Runnable.class);
registerService(service);
}
@@ -104,7 +97,7 @@
*
* @param service2 The service to register.
*/
- private void registerService(Thread service2)
+ private void registerService(Runnable service2)
{
ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
Skeleton skel = Skeleton.getSkeleton(factory);
@@ -159,11 +152,13 @@
Thread.currentThread().setContextClassLoader(mock.getClassLoader());
- Object s = ctx.lookup("aries:services/java.lang.Runnable");
+ Runnable s = (Runnable) ctx.lookup("aries:services/java.lang.Runnable");
assertNotNull("We didn't get a service back from our lookup :(", s);
- assertEquals("The SR did not return the object we expected", service, s);
+ s.run();
+
+ Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new MethodCall(Runnable.class, "run"), 1);
Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
@@ -173,7 +168,7 @@
Thread.currentThread().setContextClassLoader(mock.getClassLoader());
- s = ctx.lookup("osgi:services/java.lang.Runnable");
+ s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
// Check we have the packages set correctly
@@ -181,10 +176,11 @@
assertTrue(ctx.getEnvironment().containsValue(packages));
-
assertNotNull("We didn't get a service back from our lookup :(", s);
+
+ s.run();
- assertEquals("The SR did not return the object we expected", service, s);
+ Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
MethodCall(Runnable.class, "run"), 2);
skel = Skeleton.getSkeleton(mock.getBundleContext());
skel.assertCalled(new MethodCall(BundleContext.class, "getServiceReferences",
"java.lang.Runnable", null));
@@ -201,15 +197,21 @@
@Test
public void jndiLookupWithFilter() throws NamingException
{
+ BundleMock mock = new BundleMock("scooby.doo", new Properties());
+
+ Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
InitialContext ctx = new InitialContext();
Object s = ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
assertNotNull("We didn't get a service back from our lookup :(", s);
- assertEquals("The SR did not return the object we expected", service, s);
+ service.run();
- Skeleton.getSkeleton(bc).assertCalled(new MethodCall(BundleContext.class, "getServiceReferences", "java.lang.Runnable", "(rubbish=smelly)"));
+ Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
MethodCall(Runnable.class, "run"), 1);
+
+ Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new MethodCall(BundleContext.class,
"getServiceReferences", "java.lang.Runnable", "(rubbish=smelly)"));
}
/**
@@ -222,6 +224,11 @@
public void testLookupWhenServiceHasBeenRemoved() throws NamingException
{
reg.unregister();
+
+ BundleMock mock = new BundleMock("scooby.doo", new Properties());
+
+ Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
InitialContext ctx = new InitialContext();
ctx.lookup("aries:services/java.lang.Runnable");
@@ -236,6 +243,10 @@
@Test(expected=NameNotFoundException.class)
public void testLookupForServiceWeNeverHad() throws NamingException
{
+ BundleMock mock = new BundleMock("scooby.doo", new Properties());
+
+ Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
InitialContext ctx = new InitialContext();
ctx.lookup("aries:services/java.lang.Integer");
@@ -271,14 +282,53 @@
}
@Test
+ public void checkProxyDynamism() throws NamingException
+ {
+ BundleMock mock = new BundleMock("scooby.doo", new Properties());
+
+ Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
+ InitialContext ctx = new InitialContext();
+
+ String className = Runnable.class.getName();
+
+ Runnable t = Skeleton.newMock(Runnable.class);
+ Runnable t2 = Skeleton.newMock(Runnable.class);
+
+ // we don't want the default service
+ reg.unregister();
+
+ ServiceRegistration reg = bc.registerService(className, t, null);
+ bc.registerService(className, t2, null);
+
+ Runnable r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
+
+ r.run();
+
+ Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new MethodCall(Runnable.class, "run"), 1);
+ Skeleton.getSkeleton(t2).assertNotCalled(new MethodCall(Runnable.class,
"run"));
+
+ reg.unregister();
+
+ r.run();
+
+ Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new MethodCall(Runnable.class, "run"), 1);
+ Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
MethodCall(Runnable.class, "run"), 1);
+ }
+
+ @Test
public void checkServiceOrderObserved() throws NamingException
{
+ BundleMock mock = new BundleMock("scooby.doo", new Properties());
+
+ Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
InitialContext ctx = new InitialContext();
String className = Runnable.class.getName();
- Thread t = new Thread();
- Thread t2 = new Thread();
+ Runnable t = Skeleton.newMock(Runnable.class);
+ Runnable t2 = Skeleton.newMock(Runnable.class);
// we don't want the default service
reg.unregister();
@@ -286,9 +336,12 @@
ServiceRegistration reg = bc.registerService(className, t, null);
ServiceRegistration reg2 = bc.registerService(className, t2, null);
- Runnable r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
+ Runnable r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
- assertSame("The wrong runnable was returned", t, r);
+ r.run();
+
+ Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new MethodCall(Runnable.class, "run"), 1);
+ Skeleton.getSkeleton(t2).assertNotCalled(new MethodCall(Runnable.class,
"run"));
reg.unregister();
reg2.unregister();
@@ -296,12 +349,18 @@
Hashtable<String, Object> props = new Hashtable<String, Object>();
props.put(Constants.SERVICE_RANKING, 55);
+ t = Skeleton.newMock(Runnable.class);
+ t2 = Skeleton.newMock(Runnable.class);
+
reg = bc.registerService(className, t, null);
reg2 = bc.registerService(className, t2, props);
- r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
+ r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
+
+ r.run();
- assertSame("The wrong runnable was returned", t2, r);
+ Skeleton.getSkeleton(t).assertNotCalled(new MethodCall(Runnable.class,
"run"));
+ Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
MethodCall(Runnable.class, "run"), 1);
}
/**