harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r953413 - in /harmony/enhanced/java/trunk/classlib/modules/imageio/src: main/java/javax/imageio/ main/java/javax/imageio/spi/ main/java/org/apache/harmony/x/imageio/internal/nls/ test/java/javax/imageio/spi/
Date Thu, 10 Jun 2010 18:00:34 GMT
Author: aaf
Date: Thu Jun 10 18:00:34 2010
New Revision: 953413

URL: http://svn.apache.org/viewvc?rev=953413&view=rev
Log:
Committed Lang's patch for HARMONY-6507: implemented service registry ordering.

Modified:
    harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/ImageIO.java
    harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/spi/ServiceRegistry.java
    harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties
    harmony/enhanced/java/trunk/classlib/modules/imageio/src/test/java/javax/imageio/spi/ServiceRegistryTest.java

Modified: harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/ImageIO.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/ImageIO.java?rev=953413&r1=953412&r2=953413&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/ImageIO.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/ImageIO.java
Thu Jun 10 18:00:34 2010
@@ -30,6 +30,7 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Arrays;
+import java.util.List;
 import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
 import java.net.URL;
@@ -104,7 +105,7 @@ public final class ImageIO {
     }
 
     public static String[] getReaderFormatNames() {
-        ArrayList<String> FormatNames = new ArrayList<String>();
+        List<String> FormatNames = new ArrayList<String>();
 
         Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
true);
         while (it.hasNext()) {
@@ -116,7 +117,7 @@ public final class ImageIO {
     }
 
     public static String[] getReaderMIMETypes() {
-        ArrayList<String> MIMETypes = new ArrayList<String>();
+        List<String> MIMETypes = new ArrayList<String>();
 
         Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
true);
         while (it.hasNext()) {

Modified: harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/spi/ServiceRegistry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/spi/ServiceRegistry.java?rev=953413&r1=953412&r2=953413&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/spi/ServiceRegistry.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/javax/imageio/spi/ServiceRegistry.java
Thu Jun 10 18:00:34 2010
@@ -74,14 +74,14 @@ public class ServiceRegistry {
         throw new NotImplementedException();
     }
 
-    @SuppressWarnings("unchecked")
+//    @SuppressWarnings("unchecked")
     public <T> Iterator<T> getServiceProviders(Class<T> category, Filter
filter, boolean useOrdering) {
-        return new FilteredIterator<T>(filter, (Iterator<T>)categories.getProviders(category,
useOrdering));
+        return new FilteredIterator<T>(filter, (Iterator<T>) categories.getProviders(category,
useOrdering));
     }
 
-    @SuppressWarnings("unchecked")
+//    @SuppressWarnings("unchecked")
     public <T> Iterator<T> getServiceProviders(Class<T> category, boolean
useOrdering) {
-        return (Iterator<T>)categories.getProviders(category, useOrdering);
+        return (Iterator<T>) categories.getProviders(category, useOrdering);
     }
 
     public <T> T getServiceProviderByClass(Class<T> providerClass) throws NotImplementedException
{
@@ -89,14 +89,12 @@ public class ServiceRegistry {
         throw new NotImplementedException();
     }
 
-    public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider)
throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider)
{
+        return categories.setOrdering(category, firstProvider, secondProvider);
     }
 
-    public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider)
throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider)
{
+        return categories.unsetOrdering(category, firstProvider, secondProvider);
     }
 
     public void deregisterAll(Class<?> category) throws NotImplementedException {
@@ -137,6 +135,26 @@ public class ServiceRegistry {
             this.registry = registry;
         }
 
+        <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider)
{
+            ProvidersMap providers = categories.get(category);
+            
+            if (providers == null) {
+                throw new IllegalArgumentException(Messages.getString("imageio.92", category));
+            }
+            
+            return providers.setOrdering(firstProvider, secondProvider);
+        }
+        
+        <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider)
{
+            ProvidersMap providers = categories.get(category);
+            
+            if (providers == null) {
+                throw new IllegalArgumentException(Messages.getString("imageio.92", category));
+            }
+            
+            return providers.unsetOrdering(firstProvider, secondProvider);
+        }
+        
         //-- TODO: useOrdering
         Iterator<?> getProviders(Class<?> category, boolean useOrdering) {
             ProvidersMap providers = categories.get(category);
@@ -182,6 +200,9 @@ public class ServiceRegistry {
         }
 
         private boolean addToNamed(Object provider, Class<?> category) {
+            if (!category.isAssignableFrom(provider.getClass())) {
+                throw new ClassCastException();
+            }
             Object obj = categories.get(category);
 
             if (null == obj) {
@@ -221,12 +242,21 @@ public class ServiceRegistry {
     }
 
     private static class ProvidersMap {
-        //-- TODO: providers ordering support
 
         Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>();
+        Map<Object, ProviderNode> nodeMap = new HashMap<Object, ProviderNode>();
 
         boolean addProvider(Object provider) {
-            return providers.put(provider.getClass(), provider) == null;
+            ProviderNode node =  new ProviderNode(provider);
+            nodeMap.put(provider, node);
+            Object obj = providers.put(provider.getClass(), provider);
+            
+            if (obj !=  null) {
+                nodeMap.remove(obj);
+                return false;
+            }
+            
+            return true;
         }
 
         boolean removeProvider(Object provider,
@@ -249,10 +279,63 @@ public class ServiceRegistry {
             return providers.keySet().iterator();
         }
 
-        //-- TODO ordering
-        Iterator<?> getProviders(boolean userOrdering) {
+        Iterator<?> getProviders(boolean useOrdering) {
+            if (useOrdering) {
+                return new OrderedProviderIterator(nodeMap.values().iterator());        
     
+            }
+            
             return providers.values().iterator();
         }
+        
+        public <T> boolean setOrdering(T firstProvider, T secondProvider) {
+            if (firstProvider == secondProvider) {
+                throw new IllegalArgumentException(Messages.getString("imageio.98"));
+            }
+            
+            if ((firstProvider == null) || (secondProvider == null)) {
+                throw new IllegalArgumentException(Messages.getString("imageio.5E"));
+            }
+           
+            ProviderNode firstNode = nodeMap.get(firstProvider);
+            ProviderNode secondNode = nodeMap.get(secondProvider);
+                    
+            // if the ordering is already set, return false
+            if ((firstNode == null) || (firstNode.contains(secondNode))) {
+                return false;
+            }
+            
+            // put secondProvider into firstProvider's outgoing nodes list
+            firstNode.addOutEdge(secondNode);
+            // increase secondNode's incoming edge by 1
+            secondNode.addInEdge();         
+            
+            return true;
+        }
+        
+        public <T> boolean unsetOrdering(T firstProvider, T secondProvider) {
+            if (firstProvider == secondProvider) {
+                throw new IllegalArgumentException(Messages.getString("imageio.98"));
+            }
+            
+            if ((firstProvider == null) || (secondProvider == null)) {
+                throw new IllegalArgumentException(Messages.getString("imageio.5E"));
+            }
+            
+            ProviderNode firstNode = nodeMap.get(firstProvider);
+            ProviderNode secondNode = nodeMap.get(secondProvider); 
+                    
+            // if the ordering is not set, return false
+            if ((firstNode == null) || (!firstNode.contains(secondNode))) {
+                return false;
+            }
+                    
+            // remove secondProvider from firstProvider's outgoing nodes list
+            firstNode.removeOutEdge(secondNode);
+            // decrease secondNode's incoming edge by 1
+            secondNode.removeInEdge();
+                    
+            return true;            
+        }
     }
 
     private static class FilteredIterator<E> implements Iterator<E> {
@@ -298,4 +381,116 @@ public class ServiceRegistry {
             }
         }
     }
+    
+    private static class ProviderNode {
+        // number of incoming edges
+        private int incomingEdges;  
+        // all outgoing nodes
+        private Set<Object> outgoingNodes; 
+        private Object provider;
+                
+        public ProviderNode(Object provider) {
+            incomingEdges = 0;
+            outgoingNodes = new HashSet<Object>();
+            this.provider = provider;
+        }
+            
+        public Object getProvider() {
+            return provider;
+        }
+        
+        public Iterator<Object> getOutgoingNodes() {
+            return outgoingNodes.iterator();
+        }
+        
+        public boolean addOutEdge(Object secondProvider) {
+            return outgoingNodes.add(secondProvider);
+        }
+        
+        public <T> boolean removeOutEdge(Object provider) {
+            return outgoingNodes.remove(provider);
+        }
+        
+        public void addInEdge() {
+            incomingEdges++;
+        }
+        
+        public void removeInEdge() {
+            incomingEdges--;
+        }
+        
+        public int getIncomingEdges() {
+            return incomingEdges;
+        }
+        
+        public boolean contains(Object provider) {
+            return outgoingNodes.contains(provider);
+        }
+    }
+
+    /**
+     * The iterator implements Kahn topological sorting algorithm.
+     * @see <a href="http://en.wikipedia.org/wiki/Topological_sorting">Wikipedia</a>
+     * for further reference.
+     */
+    private static class OrderedProviderIterator implements Iterator {
+
+        // the stack contains nodes which has no lesser nodes
+        // except those already returned by the iterator
+        private Stack<ProviderNode> firstNodes = new Stack<ProviderNode>();
+
+        // a dynamic counter of incoming nodes
+        // when a node is returned by iterator, the counters for connected
+        // nodes decrement
+        private Map<ProviderNode, Integer> incomingEdges = new HashMap<ProviderNode,
Integer>();
+        
+        public OrderedProviderIterator(Iterator it) {
+            // find all the nodes that with no incoming edges and
+            // add them to firstNodes
+            while (it.hasNext()) {
+                ProviderNode node = (ProviderNode) it.next();
+                incomingEdges.put(node, new Integer(node.getIncomingEdges()));
+                if (node.getIncomingEdges() == 0) {
+                    firstNodes.push(node);
+                }
+            }
+        }
+            
+        public boolean hasNext() {
+            return !firstNodes.empty();
+        }
+
+        public Object next() {
+            if (firstNodes.empty()) {
+               throw new NoSuchElementException();
+            }
+                            
+            // get a node from firstNodes
+            ProviderNode node = firstNodes.pop();
+                            
+            // find all the outgoing nodes
+            Iterator it = node.getOutgoingNodes();
+            while (it.hasNext()) {
+                ProviderNode outNode = (ProviderNode) it.next();
+                
+                // remove the incoming edge from the node.
+                int edges = incomingEdges.get(outNode);
+                edges--;
+                incomingEdges.put(outNode, new Integer(edges));
+                
+                // add to the firstNodes if this node's incoming edge is equal to 0
+                if (edges == 0) {
+                    firstNodes.push(outNode);
+                }
+            }
+            
+            incomingEdges.remove(node);
+                            
+            return node.getProvider();
+        }
+        
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
 }

Modified: harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties?rev=953413&r1=953412&r2=953413&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties
Thu Jun 10 18:00:34 2010
@@ -100,7 +100,7 @@ imageio.52=input == null!
 imageio.53=image cannot be NULL
 imageio.54=output cannot be NULL
 imageio.55=MIMEType cannot be NULL
-imageio.56=Use deregisterServiceprovider instead of Iterator.remove()
+imageio.56=Use deregisterServiceProvider instead of Iterator.remove()
 imageio.57=format names array cannot be NULL or empty
 imageio.58=Plugin class name cannot be NULL
 imageio.59=output types array cannot be NULL or empty
@@ -108,7 +108,7 @@ imageio.5A=vendor name cannot be NULL
 imageio.5B=version name cannot be NULL
 imageio.5C=input types array cannot be NULL or empty
 imageio.5D=categories iterator should not be NULL
-imageio.5E=provider should be != NULL
+imageio.5E=Provider should be != NULL
 imageio.5F=raster should not be NULL
 imageio.60=no thumbnails were set
 imageio.61=newChild == null!
@@ -166,4 +166,5 @@ imageio.94=Output {0} is not supported
 imageio.95=Input is not an instance of java.io.RandomAccessFile
 imageio.96=Writer cannot be null
 imageio.97=Reader cannot be null
+imageio.98=Ordered providers cannot be equal
 

Modified: harmony/enhanced/java/trunk/classlib/modules/imageio/src/test/java/javax/imageio/spi/ServiceRegistryTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/imageio/src/test/java/javax/imageio/spi/ServiceRegistryTest.java?rev=953413&r1=953412&r2=953413&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/imageio/src/test/java/javax/imageio/spi/ServiceRegistryTest.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/imageio/src/test/java/javax/imageio/spi/ServiceRegistryTest.java
Thu Jun 10 18:00:34 2010
@@ -18,16 +18,97 @@
 package javax.imageio.spi;
 
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.Locale;
 
 import junit.framework.TestCase;
 
 import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
 import javax.imageio.spi.ImageReaderSpi;
 import javax.imageio.spi.ImageWriterSpi;
 
 public class ServiceRegistryTest extends TestCase {
     
+    public void testGetServiceProviders() {
+        Class[] CATEGORIES = new Class[] {
+                ImageReaderSpi.class };
+        
+        ServiceRegistry registry = new ServiceRegistry(Arrays.<Class<?>> asList(CATEGORIES).iterator());
+        
+        ImageReaderSpi reader = new SampleImageReaderSpi();
+        ImageReaderSpi reader1 = new Reader1Spi();
+        ImageReaderSpi reader2 = new Reader2Spi();
+        
+        // Add 3 different providers to the registry
+        registry.registerServiceProvider(reader, CATEGORIES[0]);
+        registry.registerServiceProvider(reader1, CATEGORIES[0]);
+        registry.registerServiceProvider(reader2, CATEGORIES[0]);
+        
+        // Add a different type of provider to the category
+        ImageWriterSpi writer = new SampleImageWriterSpi();
+        try {
+            registry.registerServiceProvider(writer, CATEGORIES[0]);
+            fail("ClassCastException expected");
+        }
+        catch (ClassCastException expected) {
+            // Ok
+        }
+        
+        // Set ordering between these providers
+        // reader2 > reader1 >  reader
+        assertTrue("Failed to set ordering: reader2 > reader1",
+            registry.setOrdering(CATEGORIES[0], reader2, reader1));
+        assertTrue("Failed to set ordering: reader1 > reader",
+            registry.setOrdering(CATEGORIES[0], reader1, reader));
+        
+        // Return false if this ordering has already been set
+        assertFalse("Failed to check if the ordering reader1 > reader has been set",
+            registry.setOrdering(CATEGORIES[0], reader1, reader));
+        
+        // If two providers are the same
+        try {
+        	registry.setOrdering(CATEGORIES[0], reader, reader);
+        	fail("IllegalArgumentException expected");
+        }
+        catch (IllegalArgumentException expected) {
+            // Ok
+        }
+        
+        // If either provider is null
+        try {
+        	registry.setOrdering(CATEGORIES[0], null, reader);
+        	fail("IllegalArgumentException expected");
+        }
+        catch (IllegalArgumentException expected) {
+            // Ok
+        }
+        
+        // Get the iterator of sorted providers
+        Iterator it = registry.getServiceProviders(CATEGORIES[0], true);
+        
+        // Verify the order
+        assertEquals("Failed to return reader2", it.next(), reader2);
+        assertEquals("Failed to return reader1", it.next(), reader1);
+        assertEquals("Failed to return reader", it.next(), reader);
+        
+        // The iterator should be able to run more than once
+        it = registry.getServiceProviders(CATEGORIES[0], true);
+        
+        // Verify the order
+        assertEquals("Failed to return reader2", it.next(), reader2);
+        assertEquals("Failed to return reader1", it.next(), reader1);
+        assertEquals("Failed to return reader", it.next(), reader);
+
+        // Unset orderings
+        assertTrue("Failed to unset ordering: reader2 > reader1", registry.unsetOrdering(CATEGORIES[0],
reader2, reader1));
+        assertTrue("Failed to unset ordering: reader1 > reader", registry.unsetOrdering(CATEGORIES[0],
reader1, reader));
+        
+        // Return false if this ordering is not set
+        assertFalse("Failed to check if the ordering is not set", registry.unsetOrdering(CATEGORIES[0],
reader2, reader));
+    }
+
     public void testRegistryServiceProvider() throws Exception {
         Class[] CATEGORIES = new Class[] {
                 ImageWriterSpi.class, ImageReaderSpi.class
@@ -84,3 +165,30 @@ class SampleImageReaderSpi extends Image
     }
 }
 
+class Reader1Spi extends SampleImageReaderSpi {
+}
+
+class Reader2Spi extends SampleImageReaderSpi {
+}
+
+class SampleImageWriterSpi extends ImageWriterSpi {
+    SampleImageWriterSpi() {
+        super("sample vendor", "1.0", new String[] { "sample" },
+            null, null, SampleImageReaderSpi.class.getName(),
+            STANDARD_OUTPUT_TYPE, null, false, null, null,
+            null, null, false, null, null, null, null);
+    }
+
+    public boolean canEncodeImage(ImageTypeSpecifier type) {
+        return false;
+    }
+
+    public ImageWriter createWriterInstance(Object extension) {
+        return null;
+    }
+
+    public String getDescription(Locale locale) {
+        return null;
+    }
+}
+



Mime
View raw message