You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2009/04/10 00:11:30 UTC

svn commit: r763827 - in /geronimo/sandbox/gawor/rfc124: ./ extender/ extender/src/main/java/org/apache/geronimo/osgi/ extender/src/main/java/org/apache/geronimo/osgi/context/ extender/src/main/java/org/apache/geronimo/osgi/convert/ extender/src/test/ ...

Author: gawor
Date: Thu Apr  9 22:11:29 2009
New Revision: 763827

URL: http://svn.apache.org/viewvc?rev=763827&view=rev
Log:
stab at ConversionService and some event publishing

Added:
    geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/
    geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java   (with props)
    geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/
    geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java   (with props)
    geronimo/sandbox/gawor/rfc124/extender/src/test/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/
    geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java   (with props)
Modified:
    geronimo/sandbox/gawor/rfc124/extender/pom.xml
    geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/Activator.java
    geronimo/sandbox/gawor/rfc124/pom.xml

Modified: geronimo/sandbox/gawor/rfc124/extender/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/extender/pom.xml?rev=763827&r1=763826&r2=763827&view=diff
==============================================================================
--- geronimo/sandbox/gawor/rfc124/extender/pom.xml (original)
+++ geronimo/sandbox/gawor/rfc124/extender/pom.xml Thu Apr  9 22:11:29 2009
@@ -88,6 +88,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.xml.bind</groupId>
             <artifactId>jaxb-api</artifactId>
             <version>2.1</version>
@@ -105,5 +110,10 @@
             <version>${version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/Activator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/Activator.java?rev=763827&r1=763826&r2=763827&view=diff
==============================================================================
--- geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/Activator.java (original)
+++ geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/Activator.java Thu Apr  9 22:11:29 2009
@@ -20,7 +20,10 @@
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
@@ -31,6 +34,7 @@
 import org.apache.geronimo.blueprint.ConstructorArg;
 import org.apache.geronimo.blueprint.TpropertyType;
 import org.apache.geronimo.blueprint.Value;
+import org.apache.geronimo.osgi.context.ModuleContextImpl;
 import org.apache.xbean.recipe.DefaultRepository;
 import org.apache.xbean.recipe.ObjectGraph;
 import org.apache.xbean.recipe.ObjectRecipe;
@@ -42,13 +46,26 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.blueprint.context.ModuleContextEventConstants;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.util.tracker.ServiceTracker;
 
 public class Activator implements BundleActivator, BundleListener {
 
+    private StopBundleListener stopBundleListener = new StopBundleListener();
+    private ServiceTracker eventAdminServieTracker;
+    private Map<Bundle, ModuleContextImpl> contextMap = new HashMap<Bundle, ModuleContextImpl>();
+    
     public void start(BundleContext context) {
         System.out.println("Starting to listen for bundle events.");
+        context.addBundleListener(stopBundleListener);
         context.addBundleListener(this);
 
+        this.eventAdminServieTracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
+        this.eventAdminServieTracker.open();
+        
         Bundle[] bundles = context.getBundles();
         for (Bundle b : bundles) {
             if (b.getState() == Bundle.ACTIVE) {
@@ -57,18 +74,57 @@
         }
     }
 
+    
     public void stop(BundleContext context) {
+        context.removeBundleListener(stopBundleListener);
         context.removeBundleListener(this);
+        this.eventAdminServieTracker.close();
         System.out.println("Stopped listening for bundle events.");
     }
 
     public void bundleChanged(BundleEvent event) {
         System.out.println("bundle changed:" + event.getBundle().getSymbolicName() + "  "+ event.getType());
         if (event.getType() == BundleEvent.STARTED) {
-            checkBundle(event.getBundle());
+            checkBundle(event.getBundle());        
         }
     }
 
+    private EventAdmin getEventAdmin() {
+        return (EventAdmin)this.eventAdminServieTracker.getService();
+    }
+    
+    private void sendEvent(ModuleContextImpl moduleContext, String topic) {
+        EventAdmin eventAdmin = getEventAdmin();
+        if (eventAdmin == null) {
+            return;
+        }
+        
+        Bundle bundle = moduleContext.getBundleContext().getBundle();
+        
+        Dictionary props = new Hashtable();        
+        props.put("bundle.symbolicName", bundle.getSymbolicName());
+        props.put("bundle.id", bundle.getBundleId());
+        props.put("bundle", bundle);
+        props.put("bundle.version", "NA");
+        props.put("timestamp", System.currentTimeMillis());
+        props.put(ModuleContextEventConstants.EXTENDER_BUNDLE, "NA");
+        props.put(ModuleContextEventConstants.EXTENDER_ID, "NA");
+        props.put(ModuleContextEventConstants.EXTENDER_SYMBLOICNAME, "NA");
+        
+        Event event = new Event(topic, props);
+        eventAdmin.postEvent(event);
+        System.out.println("Event sent: " + topic);
+    }
+    
+    private void destroyContext(Bundle bundle) {
+        ModuleContextImpl moduleContext = contextMap.remove(bundle);
+        if (moduleContext != null) {
+            sendEvent(moduleContext, ModuleContextEventConstants.TOPIC_DESTROYING);
+            moduleContext.destroy();
+            sendEvent(moduleContext, ModuleContextEventConstants.TOPIC_DESTROYED);
+        }
+    }
+    
     private void checkBundle(Bundle b) {
         System.out.println("Checking: " + b.getSymbolicName());
         
@@ -83,6 +139,8 @@
                     ee.printStackTrace();
                 }
             }
+            ModuleContextImpl moduleContext = new ModuleContextImpl(b.getBundleContext());
+            contextMap.put(b, moduleContext);
         }
         
         Dictionary d = b.getHeaders();
@@ -164,4 +222,12 @@
         }
     }
     
+    private class StopBundleListener implements SynchronousBundleListener {
+        public void bundleChanged(BundleEvent event) {
+            if (event.getType() == BundleEvent.STOPPING) {
+                destroyContext(event.getBundle());
+            }
+        }        
+    }
+    
 }
\ No newline at end of file

Added: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java?rev=763827&view=auto
==============================================================================
--- geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java (added)
+++ geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java Thu Apr  9 22:11:29 2009
@@ -0,0 +1,67 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.context;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.context.NoSuchComponentException;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+
+public class ModuleContextImpl implements ModuleContext {
+
+    private BundleContext bundleContext;
+
+    public ModuleContextImpl(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+        System.out.println("Module context created: " + this.bundleContext);
+    }
+    
+    public BundleContext getBundleContext() {
+        return this.bundleContext;
+    }
+
+    public Object getComponent(String name) throws NoSuchComponentException {
+        return null;
+    }
+
+    public ComponentMetadata getComponentMetadata(String name) throws NoSuchComponentException {
+        return null;
+    }
+
+    public Set getComponentNames() {
+        return null;
+    }
+
+    public Collection getExportedServicesMetadata() {
+        return null;
+    }
+
+    public Collection getLocalComponentsMetadata() {
+        return null;
+    }
+
+    public Collection getReferencedServicesMetadata() {
+        return null;
+    }
+        
+    public void destroy() {
+        System.out.println("Module context destroyed: " + this.bundleContext);
+    }
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/context/ModuleContextImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java?rev=763827&view=auto
==============================================================================
--- geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java (added)
+++ geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java Thu Apr  9 22:11:29 2009
@@ -0,0 +1,141 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.convert;
+
+import java.io.ByteArrayInputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.osgi.service.blueprint.convert.ConversionService;
+import org.osgi.service.blueprint.convert.Converter;
+
+public class ConversionServiceImpl implements ConversionService {
+
+    private Map<Class, List<Converter>> convertersMap = new HashMap<Class, List<Converter>>();
+    
+    public void registerConverter(Converter converter) {
+        Class type = converter.getTargetClass();
+        List<Converter> converters = convertersMap.get(type);
+        if (converters == null) {
+            converters = new ArrayList<Converter>();
+            convertersMap.put(type, converters);
+        }
+        converters.add(converter);
+    }
+    
+    public Object convert(Object fromValue, Class toType) throws Exception {        
+        Converter converter = lookupConverter(toType);
+        if (converter == null) {
+            return convertDefault(fromValue, toType);
+        } else {
+            return converter.convert(fromValue);
+        }        
+    }
+    
+    private Converter lookupConverter(Class toType) {
+        // do explicit lookup
+        List<Converter> converters = convertersMap.get(toType);
+        if (converters != null && !converters.isEmpty()) {
+            return converters.get(0);
+        }
+
+        // try to find converter that matches the type
+        for (Map.Entry<Class, List<Converter>> entry : convertersMap.entrySet()) {
+            Class converterClass = entry.getKey();
+            if (toType.isAssignableFrom(converterClass)) {
+                return entry.getValue().get(0);
+            }
+        }
+
+        return null;
+    }
+    
+    private Object convertDefault(Object fromValue, Class toType) throws Exception {
+        String value = (String)fromValue;
+        if (Locale.class == toType) {
+            String[] tokens = value.split("_");
+            if (tokens.length == 1) { 
+                return new Locale(tokens[0]);
+            } else if (tokens.length == 2) {
+                return new Locale(tokens[0], tokens[1]);
+            } else if (tokens.length == 3) {
+                return new Locale(tokens[0], tokens[1], tokens[2]);
+            } else {
+                throw new Exception("Invalid locale string:" + value);
+            }
+        } else if (Pattern.class == toType) {
+            return Pattern.compile(value);
+        } else if (Properties.class == toType) {
+            Properties props = new Properties();
+            ByteArrayInputStream in = new ByteArrayInputStream(value.getBytes("UTF8"));
+            props.load(in);
+            return props;
+        } else if (Boolean.class == toType || boolean.class == toType) {
+            if ("yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value)) {
+                return Boolean.TRUE;
+            } else if ("no".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value) || "off".equalsIgnoreCase(value)) {
+                return Boolean.FALSE;
+            } else {
+                throw new RuntimeException("Invalid boolean value: " + value);
+            }
+        } else if (Integer.class == toType || int.class == toType) {
+            return Integer.valueOf(value);
+        } else if (Short.class == toType || short.class == toType) {
+            return Short.valueOf(value);
+        } else if (Long.class == toType || long.class == toType) {
+            return Long.valueOf(value);
+        } else if (Float.class == toType || float.class == toType) {
+            return Float.valueOf(value);
+        } else if (Double.class == toType || double.class == toType) {
+            return Double.valueOf(value);
+        } else if (Character.class == toType || char.class == toType) {
+            if (value.length() == 1) {
+                return Character.valueOf(value.charAt(0));
+            } else {
+                throw new Exception("Invalid value for character type: " + value);
+            }
+        } else if (Byte.class == toType || byte.class == toType) {
+            return Byte.valueOf(value);
+        } else {
+            return createObject(value, toType);
+        }
+    }
+    
+    private Object createObject(String value, Class type) throws Exception {
+        Constructor constructor = null;
+        try {
+            constructor = type.getConstructor(String.class);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException("Unable to convert to " + type);
+        }
+        try {
+            return constructor.newInstance(value);
+        } catch (InvocationTargetException e) {
+            throw new Exception("Unable to convert ", e.getTargetException());
+        } catch (Exception e) {
+            throw new Exception("Unable to convert ", e);
+        }
+    }
+        
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/main/java/org/apache/geronimo/osgi/convert/ConversionServiceImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java?rev=763827&view=auto
==============================================================================
--- geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java (added)
+++ geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java Thu Apr  9 22:11:29 2009
@@ -0,0 +1,186 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.convert;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Locale;
+import java.util.Properties;
+
+import org.osgi.service.blueprint.convert.ConversionService;
+import org.osgi.service.blueprint.convert.Converter;
+
+import junit.framework.TestCase;
+
+public class ConversionServiceTest extends TestCase {
+
+   
+    public void testDefault() throws Exception {
+        ConversionService service = new ConversionServiceImpl();
+        
+        Object result;
+        
+        // test primitive type conversion
+        
+        result = service.convert("1", Integer.class);
+        assertTrue(result instanceof Integer);
+        assertEquals(1, ((Integer)result).intValue());
+        
+        result = service.convert("1", int.class);
+        assertTrue(result instanceof Integer);
+        assertEquals(1, ((Integer)result).intValue());
+        
+        result = service.convert("2", Short.class);
+        assertTrue(result instanceof Short);
+        assertEquals(2, ((Short)result).shortValue());
+        
+        result = service.convert("2", short.class);
+        assertTrue(result instanceof Short);
+        assertEquals(2, ((Short)result).shortValue());
+        
+        result = service.convert("3", Long.class);
+        assertTrue(result instanceof Long);
+        assertEquals(3, ((Long)result).longValue());
+        
+        result = service.convert("3", long.class);
+        assertTrue(result instanceof Long);
+        assertEquals(3, ((Long)result).longValue());
+        
+        // test boolean type conversion
+        
+        result = service.convert("yes", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.TRUE, result);
+        
+        result = service.convert("on", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.TRUE, result);
+        
+        result = service.convert("true", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.TRUE, result);
+        
+        result = service.convert("no", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.FALSE, result);
+        
+        result = service.convert("off", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.FALSE, result);
+        
+        result = service.convert("FALSE", Boolean.class);
+        assertTrue(result instanceof Boolean);
+        assertEquals(Boolean.FALSE, result);
+        
+        // test properties type conversion
+        
+        result = service.convert("foo1 = bar1\nfoo2 = bar2", Properties.class);
+        assertTrue(result instanceof Properties);
+        Properties props = (Properties)result;
+        assertEquals("bar1", props.get("foo1"));
+        assertEquals("bar2", props.get("foo2"));
+        
+        // test locale type conversion
+        
+        result = service.convert("en", Locale.class);
+        assertTrue(result instanceof Locale);
+        assertEquals(new Locale("en"), result);
+        
+        result = service.convert("de_DE", Locale.class);
+        assertTrue(result instanceof Locale);
+        assertEquals(new Locale("de", "DE"), result);
+        
+        result = service.convert("_GB", Locale.class);
+        assertTrue(result instanceof Locale);
+        assertEquals(new Locale("", "GB"), result);
+        
+        result = service.convert("en_US_WIN", Locale.class);
+        assertTrue(result instanceof Locale);
+        assertEquals(new Locale("en", "US", "WIN"), result);
+        
+        result = service.convert("de__POSIX", Locale.class);
+        assertTrue(result instanceof Locale);
+        assertEquals(new Locale("de", "", "POSIX"), result);
+                
+        // converted using the String constructor
+        
+        result = service.convert("http://foo", URI.class);
+        assertTrue(result instanceof URI);
+        assertEquals("http://foo", ((URI)result).toString());
+        
+        result = service.convert("myfile", File.class);
+        assertTrue(result instanceof File);
+        assertEquals("myfile", ((File)result).getName());
+        
+    }
+        
+    public void testCustom() throws Exception {
+        ConversionServiceImpl service = new ConversionServiceImpl();
+        service.registerConverter(new RegionConverter());
+        service.registerConverter(new EuRegionConverter());
+        
+        // lookup on a specific registered converter type
+        Object result;
+        result = service.convert(null, Region.class);
+        assertTrue(result instanceof Region);
+        assertFalse(result instanceof EuRegion);
+                
+        result = service.convert(null, EuRegion.class);
+        assertTrue(result instanceof EuRegion);
+        
+        // find first converter that matches the type
+        service = new ConversionServiceImpl();
+        service.registerConverter(new AsianRegionConverter());
+        service.registerConverter(new EuRegionConverter());
+        
+        result = service.convert(null, Region.class);
+        assertTrue(result instanceof AsianRegion || result instanceof EuRegion);
+    }
+    
+    private interface Region {} 
+    
+    private interface EuRegion extends Region {}
+    
+    private interface AsianRegion extends Region {}
+    
+    private static class RegionConverter implements Converter {
+        public Object convert(Object source) throws Exception {
+            return new Region() {} ;
+        }
+        public Class getTargetClass() {
+            return Region.class;
+        }       
+    }
+    
+    private static class EuRegionConverter implements Converter {
+        public Object convert(Object source) throws Exception {
+            return new EuRegion() {} ;
+        }
+        public Class getTargetClass() {
+            return EuRegion.class;
+        }       
+    }
+    
+    private static class AsianRegionConverter implements Converter {
+        public Object convert(Object source) throws Exception {
+            return new AsianRegion() {} ;
+        }
+        public Class getTargetClass() {
+            return AsianRegion.class;
+        }       
+    }
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/gawor/rfc124/extender/src/test/java/org/apache/geronimo/osgi/convert/ConversionServiceTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/sandbox/gawor/rfc124/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gawor/rfc124/pom.xml?rev=763827&r1=763826&r2=763827&view=diff
==============================================================================
--- geronimo/sandbox/gawor/rfc124/pom.xml (original)
+++ geronimo/sandbox/gawor/rfc124/pom.xml Thu Apr  9 22:11:29 2009
@@ -35,6 +35,16 @@
                 <artifactId>org.osgi.core</artifactId>
                 <version>1.2.0</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>org.osgi.compendium</artifactId>
+                <version>1.2.0</version>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>3.8.2</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>