From b099739d69690535623b126b37f47bfdfecf040f Mon Sep 17 00:00:00 2001 From: rfeng Date: Wed, 20 May 2009 16:46:55 +0000 Subject: Refactoring a few methods on the ServiceDiscover Adding an OSGi service registry based ExtensionPointRegistry implementation git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@776759 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/core/DefaultExtensionPointRegistry.java | 52 ++++++++++++++-------- .../sca/core/DefaultFactoryExtensionPoint.java | 2 +- .../core/DefaultModuleActivatorExtensionPoint.java | 25 ++++++----- .../sca/core/DefaultUtilityExtensionPoint.java | 2 +- .../ContextClassLoaderServiceDiscoverer.java | 22 ++++----- .../sca/extensibility/ServiceDiscoverer.java | 6 +-- .../sca/extensibility/ServiceDiscovery.java | 45 +++++++++++++------ ...ontextClassLoaderServiceDiscovererTestCase.java | 20 ++++----- 8 files changed, 104 insertions(+), 70 deletions(-) (limited to 'java/sca/modules/extensibility/src') diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java index 12979723b1..3ed134dcec 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java @@ -6,15 +6,15 @@ * 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. + * under the License. */ package org.apache.tuscany.sca.core; @@ -41,9 +41,9 @@ import org.apache.tuscany.sca.extensibility.ServiceDiscovery; */ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { private Map, Object> extensionPoints = new HashMap, Object>(); - + /** - * Constructs a new registry. + * Constructs a new registry. */ public DefaultExtensionPointRegistry() { } @@ -56,17 +56,25 @@ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { * * @throws IllegalArgumentException if extensionPoint is null */ - public void addExtensionPoint(Object extensionPoint) { + public synchronized void addExtensionPoint(Object extensionPoint) { + addExtensionPoint(extensionPoint, null); + } + + public synchronized void addExtensionPoint(Object extensionPoint, ServiceDeclaration declaration) { if (extensionPoint == null) { throw new IllegalArgumentException("Cannot register null as an ExtensionPoint"); } Set> interfaces = getAllInterfaces(extensionPoint.getClass()); for (Class i : interfaces) { - extensionPoints.put(i, extensionPoint); + registerExtensionPoint(i, extensionPoint, declaration); } } - + + protected void registerExtensionPoint(Class i, Object extensionPoint, ServiceDeclaration declaration) { + extensionPoints.put(i, extensionPoint); + } + private Constructor getConstructor(Constructor[] constructors, Class[] paramTypes) { for (Constructor c : constructors) { Class[] types = c.getParameterTypes(); @@ -94,20 +102,20 @@ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { * * @throws IllegalArgumentException if extensionPointType is null */ - public T getExtensionPoint(Class extensionPointType) { + public synchronized T getExtensionPoint(Class extensionPointType) { if (extensionPointType == null) { throw new IllegalArgumentException("Cannot lookup ExtensionPoint of type null"); } - Object extensionPoint = extensionPoints.get(extensionPointType); + Object extensionPoint = findExtensionPoint(extensionPointType); if (extensionPoint == null) { - - // Dynamically load an extension point class declared under META-INF/services + + // Dynamically load an extension point class declared under META-INF/services try { - ServiceDeclaration extensionPointDeclaration = ServiceDiscovery.getInstance().getFirstServiceDeclaration(extensionPointType.getName()); + ServiceDeclaration extensionPointDeclaration = ServiceDiscovery.getInstance().getServiceDeclaration(extensionPointType.getName()); if (extensionPointDeclaration != null) { Class extensionPointClass = extensionPointDeclaration.loadClass(); - + // Construct the extension point Constructor[] constructors = extensionPointClass.getConstructors(); Constructor constructor = getConstructor(constructors, new Class[] {ExtensionPointRegistry.class}); @@ -122,9 +130,9 @@ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { "No valid constructor is found for " + extensionPointClass); } } - + // Cache the loaded extension point - addExtensionPoint(extensionPoint); + addExtensionPoint(extensionPoint, extensionPointDeclaration); } } catch (InvocationTargetException e) { throw new IllegalArgumentException(e); @@ -141,6 +149,10 @@ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { return extensionPointType.cast(extensionPoint); } + protected Object findExtensionPoint(Class extensionPointType) { + return extensionPoints.get(extensionPointType); + } + /** * Remove an extension point based on the interface that it implements * @@ -148,17 +160,21 @@ public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { * * @throws IllegalArgumentException if extensionPoint is null */ - public void removeExtensionPoint(Object extensionPoint) { + public synchronized void removeExtensionPoint(Object extensionPoint) { if (extensionPoint == null) { throw new IllegalArgumentException("Cannot remove null as an ExtensionPoint"); } Set> interfaces = getAllInterfaces(extensionPoint.getClass()); for (Class i : interfaces) { - extensionPoints.remove(i); + unregisterExtensionPoint(i); } } + protected void unregisterExtensionPoint(Class i) { + extensionPoints.remove(i); + } + /** * Returns the set of interfaces implemented by the given class and its * ancestors or a blank set if none diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java index 80c4e2b69d..54d0d118bb 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java @@ -109,7 +109,7 @@ public class DefaultFactoryExtensionPoint implements FactoryExtensionPoint { // Dynamically load a factory class declared under META-INF/services try { ServiceDeclaration factoryDeclaration = - ServiceDiscovery.getInstance().getFirstServiceDeclaration(factoryInterface.getName()); + ServiceDiscovery.getInstance().getServiceDeclaration(factoryInterface.getName()); if (factoryDeclaration != null) { Class factoryClass = factoryDeclaration.loadClass(); try { diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java index f5aced9b50..c19949d77f 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java @@ -6,23 +6,23 @@ * 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. + * under the License. */ package org.apache.tuscany.sca.core; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import java.util.Set; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; @@ -35,9 +35,9 @@ import org.apache.tuscany.sca.extensibility.ServiceDiscovery; public class DefaultModuleActivatorExtensionPoint implements ModuleActivatorExtensionPoint { private List activators = new ArrayList(); private boolean loadedActivators; - + /** - * Constructs a new extension point. + * Constructs a new extension point. */ public DefaultModuleActivatorExtensionPoint() { } @@ -45,12 +45,12 @@ public class DefaultModuleActivatorExtensionPoint implements ModuleActivatorExte public void addModuleActivator(ModuleActivator activator) { activators.add(activator); } - + public List getModuleActivators() { loadModuleActivators(); return activators; } - + public void removeModuleActivator(Object activator) { activators.remove(activator); } @@ -63,13 +63,14 @@ public class DefaultModuleActivatorExtensionPoint implements ModuleActivatorExte return; // Get the activator service declarations - Set activatorDeclarations; + Collection activatorDeclarations; try { - activatorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ModuleActivator.class.getName()); + // Load the module activators by ranking + activatorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ModuleActivator.class.getName(), true); } catch (IOException e) { throw new IllegalStateException(e); } - + // Load and instantiate module activators for (ServiceDeclaration activatorDeclaration: activatorDeclarations) { ModuleActivator activator; @@ -85,7 +86,7 @@ public class DefaultModuleActivatorExtensionPoint implements ModuleActivatorExte } addModuleActivator(activator); } - + loadedActivators = true; } diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java index fd85c5afa0..e059a55ad0 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java @@ -153,7 +153,7 @@ public class DefaultUtilityExtensionPoint implements UtilityExtensionPoint { // Dynamically load a utility class declared under META-INF/services/"utilityType" try { - ServiceDeclaration utilityDeclaration =ServiceDiscovery.getInstance().getFirstServiceDeclaration(utilityType.getName()); + ServiceDeclaration utilityDeclaration =ServiceDiscovery.getInstance().getServiceDeclaration(utilityType.getName()); if (utilityDeclaration != null) { Class utilityClass = utilityDeclaration.loadClass(); diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java index 41764f35b9..13f967c053 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java @@ -6,15 +6,15 @@ * 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. + * under the License. */ package org.apache.tuscany.sca.extensibility; @@ -30,13 +30,13 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; @@ -129,7 +129,7 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { /** * Parse a service declaration in the form class;attr=value,attr=value and * return a map of attributes - * + * * @param declaration * @return a map of attributes */ @@ -161,8 +161,8 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { return attributes; } - public ServiceDeclaration getFirstServiceDeclaration(String name) throws IOException { - Set declarations = getServiceDeclarations(name); + public ServiceDeclaration getServiceDeclaration(String name) throws IOException { + Collection declarations = getServiceDeclarations(name); if (declarations.isEmpty()) { return null; } else { @@ -170,8 +170,8 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { } } - public Set getServiceDeclarations(String serviceName) { - Set descriptors = new HashSet(); + public Collection getServiceDeclarations(String serviceName) { + Collection descriptors = new HashSet(); // http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPathFactory.html boolean isPropertyFile = "javax.xml.xpath.XPathFactory".equals(serviceName); @@ -192,9 +192,9 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { URLConnection connection = url.openConnection(); // TUSCANY-2539 // Don't cache connections by default to stop Tuscany locking contribution jar files - // done here as this is one of the first places we open a stream and the only way to + // done here as this is one of the first places we open a stream and the only way to // set the default is to set it on an instance of URLConnection - connection.setDefaultUseCaches(false); + connection.setDefaultUseCaches(false); connection.setUseCaches(false); return url.openStream(); } diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java index 6adf083411..9b939e8228 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java @@ -20,7 +20,7 @@ package org.apache.tuscany.sca.extensibility; import java.io.IOException; -import java.util.Set; +import java.util.Collection; /** * A SPI that allows different implementations of discovering service declarations @@ -34,7 +34,7 @@ public interface ServiceDiscoverer { * @return set of service declarations * @throws IOException */ - public Set getServiceDeclarations(String name) throws IOException; + public Collection getServiceDeclarations(String name) throws IOException; /** * Get first service declaration class for the given interface @@ -44,6 +44,6 @@ public interface ServiceDiscoverer { * @throws IOException * @throws ClassNotFoundException */ - public ServiceDeclaration getFirstServiceDeclaration(String name) throws IOException; + public ServiceDeclaration getServiceDeclaration(String name) throws IOException; } diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java index 131c2b5041..3857151bec 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java @@ -21,11 +21,10 @@ package org.apache.tuscany.sca.extensibility; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Set; -import java.util.logging.Logger; /** * Service discovery for Tuscany based on J2SE Jar service provider spec. @@ -36,8 +35,6 @@ import java.util.logging.Logger; * @version $Rev$ $Date$ */ public final class ServiceDiscovery implements ServiceDiscoverer { - private static final Logger logger = Logger.getLogger(ServiceDiscovery.class.getName()); - private final static ServiceDiscovery INSTANCE = new ServiceDiscovery(); private ServiceDiscoverer discoverer; @@ -60,7 +57,7 @@ public final class ServiceDiscovery implements ServiceDiscoverer { return discoverer; } try { - //FIXME Remove that upside-down dependency + // FIXME: This is a hack to trigger the activation of the extensibility-equinox bundle in OSGi Class.forName("org.apache.tuscany.sca.extensibility.equinox.EquinoxServiceDiscoverer"); if (discoverer != null) { return discoverer; @@ -78,26 +75,46 @@ public final class ServiceDiscovery implements ServiceDiscoverer { discoverer = sd; } - public Set getServiceDeclarations(String name) throws IOException { - Set services = getServiceDiscoverer().getServiceDeclarations(name); - return services; + public Collection getServiceDeclarations(String name) throws IOException { + return getServiceDeclarations(name, false); + } + + public Collection getServiceDeclarations(String name, boolean byRanking) throws IOException { + Collection declarations = getServiceDiscoverer().getServiceDeclarations(name); + if (!byRanking) { + return declarations; + } + if (!declarations.isEmpty()) { + List declarationList = new ArrayList(declarations); + Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); + return declarationList; + } else { + return Collections.emptyList(); + } } - public ServiceDeclaration getFirstServiceDeclaration(final String name) throws IOException { + /** + * Get the service declaration. If there are more than one services, the one with highest ranking will + * be returned. + */ + public ServiceDeclaration getServiceDeclaration(final String name) throws IOException { // ServiceDeclaration service = getServiceDiscoverer().getFirstServiceDeclaration(name); // return service; - Set declarations = getServiceDeclarations(name); + Collection declarations = getServiceDeclarations(name); if (!declarations.isEmpty()) { List declarationList = new ArrayList(declarations); - Collections.sort(declarationList, ServiceComparator.INSTANCE); - return declarationList.get(declarationList.size() - 1); + Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); + return declarationList.get(0); } else { return null; } } + /** + * Compare service declarations by ranking + */ private static class ServiceComparator implements Comparator { - private final static ServiceComparator INSTANCE = new ServiceComparator(); + private final static Comparator DESCENDING_ORDER = new ServiceComparator(); public int compare(ServiceDeclaration o1, ServiceDeclaration o2) { int rank1 = 0; @@ -110,7 +127,7 @@ public final class ServiceDiscovery implements ServiceDiscoverer { if (r2 != null) { rank2 = Integer.parseInt(r2); } - return rank1 - rank2; + return rank2 - rank1; // descending } } diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscovererTestCase.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscovererTestCase.java index cfab64bef7..c0aac21596 100644 --- a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscovererTestCase.java +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscovererTestCase.java @@ -6,21 +6,21 @@ * 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. + * under the License. */ package org.apache.tuscany.sca.extensibility; import java.io.IOException; -import java.util.Set; +import java.util.Collection; import org.junit.AfterClass; import org.junit.Assert; @@ -43,26 +43,26 @@ public class ContextClassLoaderServiceDiscovererTestCase { @Test public void testDiscovery() { - Set discriptors = + Collection discriptors = discover.getServiceDeclarations("org.apache.tuscany.sca.core.ModuleActivatorExtensionPoint"); Assert.assertEquals(1, discriptors.size()); discriptors = discover.getServiceDeclarations("notthere"); Assert.assertEquals(0, discriptors.size()); } - + @Test public void testDiscoveryFirst() throws IOException { ServiceDeclaration descriptor = - discover.getFirstServiceDeclaration("org.apache.tuscany.sca.core.ModuleActivatorExtensionPoint"); + discover.getServiceDeclaration("org.apache.tuscany.sca.core.ModuleActivatorExtensionPoint"); Assert.assertNotNull(descriptor); - descriptor = discover.getFirstServiceDeclaration("notthere"); + descriptor = discover.getServiceDeclaration("notthere"); Assert.assertNull(descriptor); } - + @Test public void testXPathFactory() { - Set discriptors = discover.getServiceDeclarations("javax.xml.xpath.XPathFactory"); + Collection discriptors = discover.getServiceDeclarations("javax.xml.xpath.XPathFactory"); if (!discriptors.isEmpty()) { ServiceDeclaration d = discriptors.iterator().next(); Assert.assertNotNull(d.getClassName()); -- cgit v1.2.3