You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2012/05/22 01:12:58 UTC

svn commit: r1341258 - /aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java

Author: gnodet
Date: Mon May 21 23:12:57 2012
New Revision: 1341258

URL: http://svn.apache.org/viewvc?rev=1341258&view=rev
Log:
Improve concurrency in the namespace registry

Conflicts:

	blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java

Modified:
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java?rev=1341258&r1=1341257&r2=1341258&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java Mon May 21 23:12:57 2012
@@ -18,6 +18,9 @@
  */
 package org.apache.aries.blueprint.namespace;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
 import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
 import java.net.URI;
@@ -30,25 +33,20 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.HashSet;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.transform.Source;
-import javax.xml.XMLConstants;
-
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSResourceResolver;
 
 import org.apache.aries.blueprint.NamespaceHandler;
 import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
@@ -61,20 +59,20 @@ import org.osgi.util.tracker.ServiceTrac
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
 import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
 
 /**
  * Default implementation of the NamespaceHandlerRegistry.
- * 
+ *
  * This registry will track NamespaceHandler objects in the OSGi registry and make
  * them available, calling listeners when handlers are registered or unregistered.
  *
  * @version $Rev$, $Date$
  */
 public class NamespaceHandlerRegistryImpl implements NamespaceHandlerRegistry, ServiceTrackerCustomizer {
-    
+
     public static final URI BLUEPRINT_NAMESPACE = URI.create("http://www.osgi.org/xmlns/blueprint/v1.0.0");
 
     public static final String NAMESPACE = "osgi.service.blueprint.namespace";
@@ -87,6 +85,7 @@ public class NamespaceHandlerRegistryImp
     private final Map<Map<URI, NamespaceHandler>, Reference<Schema>> schemas = new LRUMap<Map<URI, NamespaceHandler>, Reference<Schema>>(10);
     private SchemaFactory schemaFactory;
     private List<NamespaceHandlerSetImpl> sets;
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
 
     public NamespaceHandlerRegistryImpl(BundleContext bundleContext) {
         this.bundleContext = bundleContext;
@@ -208,7 +207,7 @@ public class NamespaceHandlerRegistryImp
             throw new IllegalArgumentException("NamespaceHandler service has an associated " + NAMESPACE + " property defined which can not be converted to an array of URI");
         }
     }
-    
+
     public synchronized NamespaceHandlerSet getNamespaceHandlers(Set<URI> uris, Bundle bundle) {
         NamespaceHandlerSetImpl s = new NamespaceHandlerSetImpl(uris, bundle);
         sets.add(s);
@@ -218,33 +217,38 @@ public class NamespaceHandlerRegistryImp
     public void destroy() {
         tracker.close();
     }
-    public synchronized Schema getSchema(Map<URI, NamespaceHandler> handlers)
-        throws IOException, SAXException {
+    public Schema getSchema(Map<URI, NamespaceHandler> handlers)
+            throws IOException, SAXException {
         return getSchema(handlers, null, new Properties());
     }
-    private synchronized Schema getSchema(Map<URI, NamespaceHandler> handlers, 
-                                          final Bundle bundle,
-                                          final Properties schemaMap) throws IOException, SAXException {
-        Schema schema = null;
+
+    private Schema getSchema(Map<URI, NamespaceHandler> handlers,
+                             final Bundle bundle,
+                             final Properties schemaMap) throws IOException, SAXException {
         // Find a schema that can handle all the requested namespaces
         // If it contains additional namespaces, it should not be a problem since
         // they won't be used at all
         if (schemaMap == null || schemaMap.isEmpty()) {
-            for (Map<URI, NamespaceHandler> key : schemas.keySet()) {
-                boolean found = true;
-                for (URI uri : handlers.keySet()) {
-                    if (!handlers.get(uri).equals(key.get(uri))) {
-                        found = false;
-                        break;
+            try {
+                lock.readLock().lock();
+                for (Map<URI, NamespaceHandler> key : schemas.keySet()) {
+                    boolean found = true;
+                    for (URI uri : handlers.keySet()) {
+                        if (!handlers.get(uri).equals(key.get(uri))) {
+                            found = false;
+                            break;
+                        }
+                    }
+                    if (found) {
+                        return schemas.get(key).get();
                     }
                 }
-                if (found) {
-                    schema = schemas.get(key).get();
-                    break;
-                }
+            } finally {
+                lock.readLock().unlock();
             }
         }
-        if (schema == null) {
+        try {
+            lock.writeLock().lock();
             final List<StreamSource> schemaSources = new ArrayList<StreamSource>();
             try {
                 schemaSources.add(new StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/blueprint.xsd")));
@@ -268,8 +272,8 @@ public class NamespaceHandlerRegistryImp
                 }
                 SchemaFactory factory = getSchemaFactory();
                 factory.setResourceResolver(new LSResourceResolver() {
-                    public LSInput resolveResource(String type, 
-                                                   final String namespaceURI, 
+                    public LSInput resolveResource(String type,
+                                                   final String namespaceURI,
                                                    final String publicId,
                                                    String systemId, String baseURI) {
                         String loc = null;
@@ -286,8 +290,8 @@ public class NamespaceHandlerRegistryImp
                             URL url = bundle.getResource(loc);
                             if (url != null) {
                                 try {
-                                    StreamSource source 
-                                        = new StreamSource(url.openStream(), url.toExternalForm());
+                                    StreamSource source
+                                            = new StreamSource(url.openStream(), url.toExternalForm());
                                     schemaSources.add(source);
                                     return new SourceLSInput(source, publicId, url);
                                 } catch (IOException e) {
@@ -311,11 +315,11 @@ public class NamespaceHandlerRegistryImp
                                         // ignore and use the given systemId
                                     }
                                 }
-                                
-                                
+
+
                                 try {
-                                    final StreamSource source 
-                                        = new StreamSource(url.openStream(), url.toExternalForm());
+                                    final StreamSource source
+                                            = new StreamSource(url.openStream(), url.toExternalForm());
                                     schemaSources.add(source);
                                     return new SourceLSInput(source, publicId, url);
                                 } catch (IOException e) {
@@ -325,9 +329,9 @@ public class NamespaceHandlerRegistryImp
                         }
                         return null;
                     }
-                    
+
                 });
-                schema = factory.newSchema(schemaSources.toArray(new Source[schemaSources.size()]));
+                Schema schema = factory.newSchema(schemaSources.toArray(new Source[schemaSources.size()]));
                 // Remove schemas that are fully included
                 for (Iterator<Map<URI, NamespaceHandler>> iterator = schemas.keySet().iterator(); iterator.hasNext();) {
                     Map<URI, NamespaceHandler> key = iterator.next();
@@ -348,6 +352,7 @@ public class NamespaceHandlerRegistryImp
                     //only cache non-custom schemas
                     schemas.put(handlers, new SoftReference<Schema>(schema));
                 }
+                return schema;
             } finally {
                 for (StreamSource s : schemaSources) {
                     try {
@@ -357,10 +362,11 @@ public class NamespaceHandlerRegistryImp
                     }
                 }
             }
+        } finally {
+            lock.writeLock().unlock();
         }
-        return schema;
     }
-    
+
     private class SourceLSInput implements LSInput {
         StreamSource source;
         URL systemId;