From 12b7cae9bf154e509f3769404f090ce15d1e3b77 Mon Sep 17 00:00:00 2001 From: rfeng Date: Fri, 31 Jul 2009 01:59:16 +0000 Subject: Enhance the service discovery by testing the types Add more test cases Improve the syntax parsing for service declarations git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@799486 13f79535-47bb-0310-9956-ffa450edef68 --- .../equinox/EquinoxServiceDiscoverer.java | 50 +--- .../equinox/EquinoxServiceDiscoveryActivator.java | 6 +- .../equinox/EquinoxServiceDiscovererTestCase.java | 2 + .../ContextClassLoaderServiceDiscoverer.java | 52 +--- .../sca/extensibility/ServiceDeclaration.java | 11 + .../extensibility/ServiceDeclarationParser.java | 264 +++++++++++++++++++++ .../sca/extensibility/ServiceDiscovery.java | 47 +++- .../extensibility/ServiceDiscoveryTestCase.java | 68 ++++++ .../tuscany/sca/extensibility/test/DummyImpl.java | 31 +++ .../tuscany/sca/extensibility/test/Test2Impl.java | 34 +++ .../tuscany/sca/extensibility/test/TestImpl.java | 34 +++ .../sca/extensibility/test/TestInterface.java | 27 +++ ...he.tuscany.sca.extensibility.test.TestInterface | 19 ++ 13 files changed, 560 insertions(+), 85 deletions(-) create mode 100644 java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceDiscoveryTestCase.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/DummyImpl.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java create mode 100644 java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface (limited to 'java') diff --git a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java index 930b308dfc..61bba30719 100644 --- a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java +++ b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java @@ -19,6 +19,8 @@ package org.apache.tuscany.sca.extensibility.equinox; +import static org.apache.tuscany.sca.extensibility.ServiceDeclarationParser.parseDeclaration; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -35,7 +37,6 @@ import java.util.HashSet; 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; @@ -122,6 +123,15 @@ public class EquinoxServiceDiscoverer implements ServiceDiscoverer { return bundle; } + public boolean isAssignableTo(Class serviceType) { + try { + loadClass(); + } catch (ClassNotFoundException e) { + // Ignore + } + return (javaClass != null && serviceType.isAssignableFrom(javaClass)); + } + } /** @@ -156,40 +166,6 @@ public class EquinoxServiceDiscoverer 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 - */ - private static Map parseServiceDeclaration(String declaration) { - Map attributes = new HashMap(); - int index = declaration.indexOf(';'); - if (index != -1) { - attributes.put("class", declaration.substring(0, index).trim()); - declaration = declaration.substring(index); - } else { - int j = declaration.indexOf('='); - if (j == -1) { - attributes.put("class", declaration.trim()); - return attributes; - } else { - declaration = ";" + declaration; - } - } - StringTokenizer tokens = new StringTokenizer(declaration); - for (; tokens.hasMoreTokens();) { - String key = tokens.nextToken("=").substring(1).trim(); - if (key == null) - break; - String value = tokens.nextToken(",").substring(1).trim(); - if (value == null) - break; - attributes.put(key, value); - } - return attributes; - } public ServiceDeclaration getServiceDeclaration(String name) throws IOException { Collection declarations = getServiceDeclarations(name); @@ -285,7 +261,7 @@ public class EquinoxServiceDiscoverer implements ServiceDiscoverer { attributes.put(key, value); attributes.put("uri", key); } - attributes.put("class", value); + attributes.putAll(parseDeclaration(value)); ServiceDeclarationImpl descriptor = new ServiceDeclarationImpl(bundle, url, value, attributes); descriptors.add(descriptor); } @@ -306,7 +282,7 @@ public class EquinoxServiceDiscoverer implements ServiceDiscoverer { logger.fine("Registering service provider: " + reg); } - Map attributes = parseServiceDeclaration(reg); + Map attributes = parseDeclaration(reg); String className = attributes.get("class"); if (className == null) { // Add a unique class name to prevent equals() from returning true diff --git a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoveryActivator.java b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoveryActivator.java index d5d7b92022..a9a0d6d3f6 100644 --- a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoveryActivator.java +++ b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoveryActivator.java @@ -19,8 +19,6 @@ package org.apache.tuscany.sca.extensibility.equinox; -import java.util.logging.Logger; - import org.apache.tuscany.sca.extensibility.ServiceDiscovery; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -31,12 +29,12 @@ import org.osgi.framework.BundleContext; * @version $Rev$ $Date$ */ public class EquinoxServiceDiscoveryActivator implements BundleActivator { - private static final Logger logger = Logger.getLogger(EquinoxServiceDiscoveryActivator.class.getName()); + // private static final Logger logger = Logger.getLogger(EquinoxServiceDiscoveryActivator.class.getName()); public void start(BundleContext context) throws Exception { EquinoxServiceDiscoverer discoverer = new EquinoxServiceDiscoverer(context); ServiceDiscovery.getInstance().setServiceDiscoverer(discoverer); - logger.info("Equinox-based service discoverer is now configured."); + // logger.info("Equinox-based service discoverer is now configured."); } public void stop(BundleContext context) throws Exception { diff --git a/java/sca/modules/extensibility-equinox/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java b/java/sca/modules/extensibility-equinox/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java index 2ed3cfd82c..deb4221f4f 100644 --- a/java/sca/modules/extensibility-equinox/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java +++ b/java/sca/modules/extensibility-equinox/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java @@ -108,6 +108,7 @@ public class EquinoxServiceDiscovererTestCase { for (Bundle b : bundles) { b.start(); System.out.println("Started "+b.getSymbolicName() + " [" + getState(b) + "]"); + /* // Get the Platform.getExtensionRegistry() if ("org.eclipse.core.runtime".equals(b.getSymbolicName())) { // The Platform class loaded by the bundle is different that the one @@ -117,6 +118,7 @@ public class EquinoxServiceDiscovererTestCase { Object reg = m.invoke(cls); System.out.println(reg); } + */ } } 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 13f967c053..3d733d042e 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 @@ -19,6 +19,8 @@ package org.apache.tuscany.sca.extensibility; +import static org.apache.tuscany.sca.extensibility.ServiceDeclarationParser.parseDeclaration; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -37,7 +39,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; @@ -104,6 +105,14 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { }); } + public boolean isAssignableTo(Class serviceType) { + try { + loadClass(); + } catch (ClassNotFoundException e) { + // Ignore + } + return (javaClass != null && serviceType.isAssignableFrom(javaClass)); + } } private WeakReference classLoaderReference; @@ -126,41 +135,6 @@ 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 - */ - private static Map parseServiceDeclaration(String declaration) { - Map attributes = new HashMap(); - int index = declaration.indexOf(';'); - if (index != -1) { - attributes.put("class", declaration.substring(0, index).trim()); - declaration = declaration.substring(index); - } else { - int j = declaration.indexOf('='); - if (j == -1) { - attributes.put("class", declaration.trim()); - return attributes; - } else { - declaration = ";" + declaration; - } - } - StringTokenizer tokens = new StringTokenizer(declaration); - for (; tokens.hasMoreTokens();) { - String key = tokens.nextToken("=").substring(1).trim(); - if (key == null) - break; - String value = tokens.nextToken(",").substring(1).trim(); - if (value == null) - break; - attributes.put(key, value); - } - return attributes; - } - public ServiceDeclaration getServiceDeclaration(String name) throws IOException { Collection declarations = getServiceDeclarations(name); if (declarations.isEmpty()) { @@ -212,7 +186,7 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { String key = (String)e.getKey(); String value = (String)e.getValue(); // Unfortunately, the xalan file only has the classname - if ("".equals(value)) { + if (value == null || "".equals(value)) { value = key; key = ""; } @@ -220,7 +194,7 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { attributes.put(key, value); attributes.put("uri", key); } - attributes.put("class", value); + attributes.putAll(parseDeclaration(value)); ServiceDeclarationImpl descriptor = new ServiceDeclarationImpl(url, value, attributes); descriptors.add(descriptor); } @@ -241,7 +215,7 @@ public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { logger.fine("Registering service provider: " + reg); } - Map attributes = parseServiceDeclaration(reg); + Map attributes = parseDeclaration(reg); String className = attributes.get("class"); if (className == null) { // Add a unique class name to prevent equals() from returning true diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java index d7ac8b449f..209a30b08e 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java @@ -50,8 +50,19 @@ public interface ServiceDeclaration { */ Map getAttributes(); + /** + * Check if the service implementation class is a type of the service + * @param serviceType The java class of the service SPI + * @return true if the implementation class is a type of the service + */ + boolean isAssignableTo(Class serviceType); + URL getLocation(); + /** + * Return the class name for the service provider + * @return + */ String getClassName(); URL getResource(String name); diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java new file mode 100644 index 0000000000..537aac2e64 --- /dev/null +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java @@ -0,0 +1,264 @@ +/* + * 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.tuscany.sca.extensibility; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Parser for the service descriptors. The syntax of the service declaration is similar with the OSGi + * headers with the following exceptions: + *
    + *
  • Tuscany uses , and ; as the separator for attibutes + *
  • Tuscany + */ +public class ServiceDeclarationParser { + + // private static final String PATH_SEPARATOR = ","; // OSGi style + private static final String PATH_SEPARATOR = "|"; + + // private static final String SEGMENT_SEPARATOR = ";"; // OSGi style + private static final String SEGMENT_SEPARATOR = ";,"; + + private static final String ATTRIBUTE_SEPARATOR = "="; + private static final String DIRECTIVE_SEPARATOR = ":="; + + private static final char QUOTE_CHAR = '"'; + private static final String QUOTE = "\""; + + // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2, + // path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2 + public static List parse(String header) { + + if (header != null) { + if (header.length() == 0) { + throw new IllegalArgumentException("A header cannot be an empty string."); + } + + String[] clauseStrings = parseDelimitedString(header, PATH_SEPARATOR); + + List completeList = new ArrayList(); + for (int i = 0; (clauseStrings != null) && (i < clauseStrings.length); i++) { + completeList.add(parseClause(clauseStrings[i])); + } + + return completeList; + } + + return null; + + } + + /** + * Parse the declaration into a map of name/value pairs. The class name is added under "class" + * and directives are added using @ as the key. + * @param declaration + * @return A map of attributes + */ + public static Map parseDeclaration(String declaration) { + List descriptors = parse(declaration); + Descriptor descriptor = descriptors.get(0); + Map map = new HashMap(); + map.putAll(descriptor.getAttributes()); + map.put("class", descriptor.getValue()); + for (Map.Entry e : descriptor.getDirectives().entrySet()) { + // For directives, add @ as the prefix for the key + map.put("@" + e.getKey(), e.getValue()); + } + return map; + } + + // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2 + private static Descriptor parseClause(String clauseString) throws IllegalArgumentException { + // Break string into semi-colon delimited pieces. + String[] pieces = parseDelimitedString(clauseString, SEGMENT_SEPARATOR); + + // Count the number of different paths; paths + // will not have an '=' in their string. This assumes + // that paths come first, before directives and + // attributes. + int pathCount = 0; + for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++) { + if (pieces[pieceIdx].indexOf('=') >= 0) { + break; + } + pathCount++; + } + + // Create an array of paths. + String[] paths = new String[pathCount]; + System.arraycopy(pieces, 0, paths, 0, pathCount); + + // Parse the directives/attributes. + Map dirsMap = new HashMap(); + Map attrsMap = new HashMap(); + int idx = -1; + String sep = null; + for (int pieceIdx = pathCount; pieceIdx < pieces.length; pieceIdx++) { + // Check if it is a directive. + if ((idx = pieces[pieceIdx].indexOf(DIRECTIVE_SEPARATOR)) >= 0) { + sep = DIRECTIVE_SEPARATOR; + } + // Check if it is an attribute. + else if ((idx = pieces[pieceIdx].indexOf(ATTRIBUTE_SEPARATOR)) >= 0) { + sep = ATTRIBUTE_SEPARATOR; + } + // It is an error. + else { + throw new IllegalArgumentException("Not a directive/attribute: " + clauseString); + } + + String key = pieces[pieceIdx].substring(0, idx).trim(); + String value = pieces[pieceIdx].substring(idx + sep.length()).trim(); + + // Remove quotes, if value is quoted. + if (value.startsWith(QUOTE) && value.endsWith(QUOTE)) { + value = value.substring(1, value.length() - 1); + } + + // Save the directive/attribute in the appropriate array. + if (sep.equals(DIRECTIVE_SEPARATOR)) { + // Check for duplicates. + if (dirsMap.get(key) != null) { + throw new IllegalArgumentException("Duplicate directive: " + key); + } + dirsMap.put(key, value); + } else { + // Check for duplicates. + if (attrsMap.get(key) != null) { + throw new IllegalArgumentException("Duplicate attribute: " + key); + } + attrsMap.put(key, value); + } + } + + StringBuffer path = new StringBuffer(); + for (int i = 0; i < paths.length; i++) { + path.append(paths[i]); + if (i != paths.length - 1) { + path.append(';'); + } + } + + Descriptor descriptor = new Descriptor(); + descriptor.text = clauseString; + descriptor.value = path.toString(); + descriptor.valueComponents = paths; + descriptor.attributes = attrsMap; + descriptor.directives = dirsMap; + + return descriptor; + } + + /** + * Parses delimited string and returns an array containing the tokens. This + * parser obeys quotes, so the delimiter character will be ignored if it is + * inside of a quote. This method assumes that the quote character is not + * included in the set of delimiter characters. + * @param value the delimited string to parse. + * @param delim the characters delimiting the tokens. + * @return an array of string tokens or null if there were no tokens. + **/ + private static String[] parseDelimitedString(String value, String delim) { + if (value == null) { + value = ""; + } + + List list = new ArrayList(); + + int CHAR = 1; + int DELIMITER = 2; + int STARTQUOTE = 4; + int ENDQUOTE = 8; + + StringBuffer sb = new StringBuffer(); + + int expecting = (CHAR | DELIMITER | STARTQUOTE); + + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + + boolean isDelimiter = (delim.indexOf(c) >= 0); + boolean isQuote = (c == QUOTE_CHAR); + + if (isDelimiter && ((expecting & DELIMITER) > 0)) { + list.add(sb.toString().trim()); + sb.delete(0, sb.length()); + expecting = (CHAR | DELIMITER | STARTQUOTE); + } else if (isQuote && ((expecting & STARTQUOTE) > 0)) { + sb.append(c); + expecting = CHAR | ENDQUOTE; + } else if (isQuote && ((expecting & ENDQUOTE) > 0)) { + sb.append(c); + expecting = (CHAR | STARTQUOTE | DELIMITER); + } else if ((expecting & CHAR) > 0) { + sb.append(c); + } else { + throw new IllegalArgumentException("Invalid delimited string: " + value); + } + } + + if (sb.length() > 0) { + list.add(sb.toString().trim()); + } + + return (String[])list.toArray(new String[list.size()]); + } + + public static class Descriptor { + private String text; + private String value; + private String[] valueComponents; + private Map attributes; + private Map directives; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String[] getValueComponents() { + return valueComponents; + } + + public void setValueComponents(String[] valueComponents) { + this.valueComponents = valueComponents; + } + + public Map getAttributes() { + return attributes; + } + + public Map getDirectives() { + return directives; + } + + public String toString() { + return text; + } + + } + +} 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 081693b02b..ec95aba7e1 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 @@ -24,7 +24,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -44,6 +46,7 @@ public final class ServiceDiscovery implements ServiceDiscoverer { private ServiceDiscovery() { super(); } + /** * Get an instance of Service discovery, one instance is created per * ClassLoader that this class is loaded from @@ -112,18 +115,52 @@ public final class ServiceDiscovery implements ServiceDiscoverer { * be returned. */ public ServiceDeclaration getServiceDeclaration(final String name) throws IOException { - // ServiceDeclaration service = getServiceDiscoverer().getFirstServiceDeclaration(name); - // return service; Collection declarations = getServiceDeclarations(name, true); if (!declarations.isEmpty()) { - List declarationList = new ArrayList(declarations); - Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); - return declarationList.get(0); + // List declarationList = new ArrayList(declarations); + // Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); + return declarations.iterator().next(); } else { return null; } } + /** + * Get service declarations that are filtered by the service type. In an OSGi runtime, there + * might be different versions of the services + * @param serviceType + * @return + * @throws IOException + */ + public Collection getServiceDeclarations(Class serviceType, boolean byRanking) + throws IOException { + Collection sds = getServiceDeclarations(serviceType.getName(), byRanking); + for (Iterator i = sds.iterator(); i.hasNext();) { + ServiceDeclaration sd = i.next(); + if (!sd.isAssignableTo(serviceType)) { + logger.log(Level.WARNING, "Service provider {0} is not a type of {1}", new Object[] { + sd, + serviceType + .getName()}); + i.remove(); + } + } + return sds; + } + + public Collection getServiceDeclarations(Class serviceType) throws IOException { + return getServiceDeclarations(serviceType, false); + } + + public ServiceDeclaration getServiceDeclaration(Class serviceType) throws IOException { + Collection sds = getServiceDeclarations(serviceType, true); + if (sds.isEmpty()) { + return null; + } else { + return sds.iterator().next(); + } + } + /** * Compare service declarations by ranking */ diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceDiscoveryTestCase.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceDiscoveryTestCase.java new file mode 100644 index 0000000000..7d0413ef17 --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceDiscoveryTestCase.java @@ -0,0 +1,68 @@ +/* + * 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.tuscany.sca.extensibility; + +import java.util.Collection; +import java.util.Iterator; + +import org.apache.tuscany.sca.extensibility.test.TestInterface; +import org.junit.Assert; +import org.junit.Test; + +/** + * + */ +public class ServiceDiscoveryTestCase { + private static final String NAME = "org.apache.tuscany.sca.extensibility.test.TestInterface"; + + @Test + public void testRanking() throws Exception { + ServiceDeclaration sd = ServiceDiscovery.getInstance().getServiceDeclaration(NAME); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.Test2Impl", sd.getClassName()); + + Collection sds = ServiceDiscovery.getInstance().getServiceDeclarations(NAME); + Assert.assertEquals(3, sds.size()); + + sds = ServiceDiscovery.getInstance().getServiceDeclarations(NAME, true); + Assert.assertEquals(3, sds.size()); + Iterator it = sds.iterator(); + ServiceDeclaration sd1 = it.next(); + ServiceDeclaration sd2 = it.next(); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.Test2Impl", sd1.getClassName()); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.TestImpl", sd2.getClassName()); + } + + @Test + public void testServiceType() throws Exception { + ServiceDeclaration sd = ServiceDiscovery.getInstance().getServiceDeclaration(TestInterface.class); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.Test2Impl", sd.getClassName()); + + Collection sds = ServiceDiscovery.getInstance().getServiceDeclarations(TestInterface.class); + Assert.assertEquals(2, sds.size()); + + sds = ServiceDiscovery.getInstance().getServiceDeclarations(TestInterface.class, true); + Assert.assertEquals(2, sds.size()); + Iterator it = sds.iterator(); + ServiceDeclaration sd1 = it.next(); + ServiceDeclaration sd2 = it.next(); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.Test2Impl", sd1.getClassName()); + Assert.assertEquals("org.apache.tuscany.sca.extensibility.test.TestImpl", sd2.getClassName()); + } +} diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/DummyImpl.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/DummyImpl.java new file mode 100644 index 0000000000..f1ed50c5f2 --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/DummyImpl.java @@ -0,0 +1,31 @@ +/* + * 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.tuscany.sca.extensibility.test; + +/** + * + */ +public class DummyImpl { + + public void test(String str) { + System.out.println("Test: " + str); + } + +} diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java new file mode 100644 index 0000000000..49bc0d022e --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java @@ -0,0 +1,34 @@ +/* + * 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.tuscany.sca.extensibility.test; + +/** + * + */ +public class Test2Impl implements TestInterface { + + /* (non-Javadoc) + * @see org.apache.tuscany.sca.extensibility.test.TestInterface#test(java.lang.String) + */ + public void test(String str) { + System.out.println("Test 2: " + str); + } + +} diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java new file mode 100644 index 0000000000..c925bf07c0 --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java @@ -0,0 +1,34 @@ +/* + * 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.tuscany.sca.extensibility.test; + +/** + * + */ +public class TestImpl implements TestInterface { + + /* (non-Javadoc) + * @see org.apache.tuscany.sca.extensibility.test.TestInterface#test(java.lang.String) + */ + public void test(String str) { + System.out.println("Test: " + str); + } + +} diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java new file mode 100644 index 0000000000..a1897d86c0 --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java @@ -0,0 +1,27 @@ +/* + * 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.tuscany.sca.extensibility.test; + +/** + * + */ +public interface TestInterface { + void test(String str); +} diff --git a/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface b/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface new file mode 100644 index 0000000000..3d5f9d1857 --- /dev/null +++ b/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface @@ -0,0 +1,19 @@ +# 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. +org.apache.tuscany.sca.extensibility.test.TestImpl;ranking=10 +org.apache.tuscany.sca.extensibility.test.Test2Impl;ranking=20 +org.apache.tuscany.sca.extensibility.test.DummyImpl \ No newline at end of file -- cgit v1.2.3