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 2009/10/07 12:24:47 UTC
svn commit: r822645 - in /incubator/aries/trunk/blueprint: ./
blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/
blueprint-core/ blueprint-core/src/main/java/org/apache/aries/blueprint/
blueprint-core/src/main/java/org/apache/aries/bl...
Author: gnodet
Date: Wed Oct 7 10:24:46 2009
New Revision: 822645
URL: http://svn.apache.org/viewvc?rev=822645&view=rev
Log:
ARIES-5: Support for multiple namespace handlers for the same schema and use a compatible one wrt class loaders
Modified:
incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
incubator/aries/trunk/blueprint/blueprint-core/pom.xml
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/NamespaceHandler.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/NamespaceHandlerRegistry.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java
incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java
incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java
incubator/aries/trunk/blueprint/pom.xml
Modified: incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java Wed Oct 7 10:24:46 2009
@@ -20,8 +20,11 @@
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
@@ -138,6 +141,15 @@
return getClass().getResource("blueprint-cm.xsd");
}
+ public Set<Class> getManagedClasses() {
+ return new HashSet<Class>(Arrays.asList(
+ CmPropertyPlaceholder.class,
+ CmManagedServiceFactory.class,
+ CmManagedProperties.class,
+ CmProperties.class
+ ));
+ }
+
public Metadata parse(Element element, ParserContext context) {
LOGGER.debug("Parsing element {{}}{}", element.getNamespaceURI(), element.getLocalName());
ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
Modified: incubator/aries/trunk/blueprint/blueprint-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/pom.xml?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/pom.xml (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/pom.xml Wed Oct 7 10:24:46 2009
@@ -37,10 +37,9 @@
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>aries-blueprint-api</artifactId>
</dependency>
- <!-- We should use the org.osgi:org.osgi.core:1.5 jar, but it has not been released yet -->
<dependency>
- <groupId>org.eclipse</groupId>
- <artifactId>osgi</artifactId>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/NamespaceHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/NamespaceHandler.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/NamespaceHandler.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/NamespaceHandler.java Wed Oct 7 10:24:46 2009
@@ -17,6 +17,7 @@
package org.apache.aries.blueprint;
import java.net.URL;
+import java.util.Set;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -27,6 +28,8 @@
public interface NamespaceHandler {
URL getSchemaLocation(String namespace);
+
+ Set<Class> getManagedClasses();
Metadata parse(Element element, ParserContext context);
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java Wed Oct 7 10:24:46 2009
@@ -513,7 +513,7 @@
// call init method
if (initMethod != null) {
try {
- invoke(initMethod, obj, null);
+ invoke(initMethod, obj, (Object[]) null);
} catch (Throwable t) {
throw new ComponentDefinitionException("Unable to intialize bean " + getName(), getRealCause(t));
}
@@ -529,7 +529,7 @@
try {
Method method = getDestroyMethod(obj);
if (method != null) {
- invoke(method, obj, null);
+ invoke(method, obj, (Object[]) null);
}
} catch (Exception e) {
LOGGER.info("Error invoking destroy method", getRealCause(e));
@@ -544,7 +544,7 @@
Method method = getDestroyMethod(instance);
if (method != null) {
try {
- invoke(method, instance, null);
+ invoke(method, instance, (Object[]) null);
} catch (Throwable e) {
LOGGER.info("Error destroying bean " + getName(), getRealCause(e));
}
@@ -584,7 +584,7 @@
Method getter = getPropertyDescriptor(clazz, names[i]).getGetter();
if (getter != null) {
try {
- instance = invoke(getter, instance, null);
+ instance = invoke(getter, instance, (Object[]) null);
} catch (Exception e) {
throw new ComponentDefinitionException("Error getting property: " + names[i] + " on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName(), getRealCause(e));
}
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java Wed Oct 7 10:24:46 2009
@@ -121,6 +121,7 @@
private final ScheduledExecutorService executors;
private Set<URI> namespaces;
private State state = State.Unknown;
+ private NamespaceHandlerRegistry.NamespaceHandlerSet handlerSet;
private boolean destroyed;
private Parser parser;
private BlueprintRepository repository;
@@ -231,19 +232,17 @@
checkDirectives();
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.CREATING, getBundleContext().getBundle(), getExtenderBundle()));
parser = new Parser();
- parser.setValidation(xmlValidation);
parser.parse(getResources());
namespaces = parser.getNamespaces();
- if (namespaces.size() > 0) {
- handlers.addListener(this);
- }
+ handlerSet = handlers.getNamespaceHandlers(namespaces, getBundleContext().getBundle());
+ handlerSet.addListener(this);
state = State.WaitForNamespaceHandlers;
break;
case WaitForNamespaceHandlers:
{
List<String> missing = new ArrayList<String>();
for (URI ns : namespaces) {
- if (handlers.getNamespaceHandler(ns) == null) {
+ if (handlerSet.getNamespaceHandler(ns) == null) {
missing.add("(&(" + Constants.OBJECTCLASS + "=" + NamespaceHandler.class.getName() + ")(" + NamespaceHandlerRegistryImpl.NAMESPACE + "=" + ns + "))");
}
}
@@ -255,7 +254,10 @@
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundle", bundleContext.getBundle()));
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundleContext", bundleContext));
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintConverter", converter));
- parser.populate(handlers, componentDefinitionRegistry);
+ if (xmlValidation) {
+ parser.validate(handlerSet.getSchema());
+ }
+ parser.populate(handlerSet, componentDefinitionRegistry);
state = State.Populated;
break;
}
@@ -777,7 +779,10 @@
if (registration != null) {
registration.unregister();
}
- handlers.removeListener(this);
+ if (handlerSet != null) {
+ handlerSet.removeListener(this);
+ handlerSet.destroy();
+ }
unregisterServices();
untrackServiceReferences();
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/NamespaceHandlerRegistry.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/NamespaceHandlerRegistry.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/NamespaceHandlerRegistry.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/NamespaceHandlerRegistry.java Wed Oct 7 10:24:46 2009
@@ -25,6 +25,8 @@
import javax.xml.validation.Schema;
import org.apache.aries.blueprint.NamespaceHandler;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
import org.xml.sax.SAXException;
/**
@@ -38,42 +40,65 @@
* Retrieve the <code>NamespaceHandler</code> for the specified URI
*
* @param uri the namespace identifying the namespace handler
- * @return the registered <code>NamespaceHandler</code> or <code>null</code> if none has been registered for the given namespace
- */
- NamespaceHandler getNamespaceHandler(URI uri);
-
- /**
- * Add a new Listener to be called when namespace handlers are registerd or unregistered
+ * @param bundle the blueprint bundle to be checked for class space consistency
*
- * @param listener the listener to register
+ * @return a set of registered <code>NamespaceHandler</code>s compatible with the class space of the given bundle
*/
- void addListener(Listener listener);
+ NamespaceHandlerSet getNamespaceHandlers(Set<URI> uri, Bundle bundle);
/**
- * Remove a previously registered Listener
- *
- * @param listener the listener to unregister
+ * Destroy this registry
*/
- void removeListener(Listener listener);
+ void destroy();
/**
- * Obtain a schema to validate the XML for the given list of namespaces
- *
- * @param namespaces
- * @return
+ * Interface used to managed a set of namespace handlers
*/
- Schema getSchema(Set<URI> namespaces) throws SAXException, IOException;
+ public interface NamespaceHandlerSet {
- /**
- * Destroy this registry
- */
- void destroy();
+ Set<URI> getNamespaces();
+
+ boolean isComplete();
+
+ /**
+ * Retrieve the NamespaceHandler to use for the given namespace
+ *
+ * @return the NamespaceHandler to use or <code>null</code> if none is available at this time
+ */
+ NamespaceHandler getNamespaceHandler(URI namespace);
+
+ /**
+ * Obtain a schema to validate the XML for the given list of namespaces
+ *
+ * @return the schema to use to validate the XML
+ */
+ Schema getSchema() throws SAXException, IOException;
+
+ /**
+ * Add a new Listener to be called when namespace handlers are registerd or unregistered
+ *
+ * @param listener the listener to register
+ */
+ void addListener(Listener listener);
+
+ /**
+ * Remove a previously registered Listener
+ *
+ * @param listener the listener to unregister
+ */
+ void removeListener(Listener listener);
+
+ /**
+ * Destroy this handler set
+ */
+ void destroy();
+ }
/**
* Interface used to listen to registered or unregistered namespace handlers.
*
- * @see NamespaceHandlerRegistry#addListener(org.apache.aries.blueprint.container.NamespaceHandlerRegistry.Listener)
- * @see NamespaceHandlerRegistry#removeListener(org.apache.aries.blueprint.container.NamespaceHandlerRegistry.Listener)
+ * @see NamespaceHandlerSet#addListener(org.apache.aries.blueprint.container.NamespaceHandlerRegistry.Listener)
+ * @see NamespaceHandlerSet#removeListener(org.apache.aries.blueprint.container.NamespaceHandlerRegistry.Listener)
*/
public interface Listener {
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java Wed Oct 7 10:24:46 2009
@@ -183,7 +183,7 @@
private List<Document> documents;
private ComponentDefinitionRegistry registry;
- private NamespaceHandlerRegistry namespaceHandlerRegistry;
+ private NamespaceHandlerRegistry.NamespaceHandlerSet handlers;
private String idPrefix = "component-";
private Set<String> ids = new HashSet<String>();
private int idCounter;
@@ -191,8 +191,6 @@
private String defaultAvailability;
private String defaultActivation;
private Set<URI> namespaces;
- private boolean validation;
- private boolean validated;
public Parser() {
}
@@ -201,10 +199,6 @@
this.idPrefix = idPrefix;
}
- public void setValidation(boolean validation) {
- this.validation = validation;
- }
-
public void parse(List<URL> urls) throws Exception {
List<Document> documents = new ArrayList<Document>();
// Create document builder factory
@@ -250,28 +244,21 @@
}
}
- public void populate(NamespaceHandlerRegistry handlers,
+ public void populate(NamespaceHandlerRegistry.NamespaceHandlerSet handlers,
ComponentDefinitionRegistry registry) {
- this.namespaceHandlerRegistry = handlers;
+ this.handlers = handlers;
this.registry = registry;
if (this.documents == null) {
throw new IllegalStateException("Documents should be parsed before populating the registry");
}
- // Validate xmls
- if (!this.validated && validation) {
- validate();
- this.validated = true;
- }
// Parse components
for (Document doc : this.documents) {
loadComponents(doc);
}
}
- private void validate() {
- // Use a LinkedHashSet to ensure that the blueprint schema is loaded first
+ public void validate(Schema schema) {
try {
- Schema schema = this.namespaceHandlerRegistry.getSchema(getNamespaces());
Validator validator = schema.newValidator();
for (Document doc : this.documents) {
validator.validate(new DOMSource(doc));
@@ -1163,11 +1150,11 @@
}
private NamespaceHandler getNamespaceHandler(Node node) {
- if (namespaceHandlerRegistry == null) {
+ if (handlers == null) {
throw new ComponentDefinitionException("Unsupported node (namespace handler registry is not set): " + node);
}
URI ns = URI.create(node.getNamespaceURI());
- NamespaceHandler handler = this.namespaceHandlerRegistry.getNamespaceHandler(ns);
+ NamespaceHandler handler = this.handlers.getNamespaceHandler(ns);
if (handler == null) {
throw new ComponentDefinitionException("Unsupported node namespace: " + node.getNamespaceURI());
}
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java Wed Oct 7 10:24:46 2009
@@ -20,7 +20,10 @@
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
@@ -97,6 +100,12 @@
return getClass().getResource("blueprint-ext.xsd");
}
+ public Set<Class> getManagedClasses() {
+ return new HashSet<Class>(Arrays.asList(
+ PropertyPlaceholder.class
+ ));
+ }
+
public Metadata parse(Element element, ParserContext context) {
LOGGER.debug("Parsing element {{}}{}", element.getNamespaceURI(), element.getLocalName());
if (nodeNameEquals(element, PROPERTY_PLACEHOLDER_ELEMENT)) {
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/NamespaceHandlerRegistryImpl.java Wed Oct 7 10:24:46 2009
@@ -18,24 +18,24 @@
*/
package org.apache.aries.blueprint.namespace;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
import java.net.URI;
import java.net.URL;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.AbstractMap;
-import java.util.LinkedList;
-import java.util.AbstractSet;
-import java.util.Iterator;
import java.util.HashSet;
import java.io.IOException;
-import java.lang.ref.SoftReference;
-import java.lang.ref.Reference;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
@@ -45,6 +45,7 @@
import org.apache.aries.blueprint.NamespaceHandler;
import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
@@ -70,18 +71,18 @@
private static final Logger LOGGER = LoggerFactory.getLogger(NamespaceHandlerRegistryImpl.class);
private final BundleContext bundleContext;
- private final Map<URI, NamespaceHandler> handlers;
+ private final Map<URI, Set<NamespaceHandler>> handlers;
private final ServiceTracker tracker;
- private final Map<Listener, Boolean> listeners;
- private final Map<Set<URI>, Reference<Schema>> schemas = new LRUMap<Set<URI>, Reference<Schema>>(10);
+ private final Map<Map<URI, NamespaceHandler>, Reference<Schema>> schemas = new LRUMap<Map<URI, NamespaceHandler>, Reference<Schema>>(10);
private SchemaFactory schemaFactory;
+ private List<NamespaceHandlerSetImpl> sets;
public NamespaceHandlerRegistryImpl(BundleContext bundleContext) {
this.bundleContext = bundleContext;
- handlers = new HashMap<URI, NamespaceHandler>();
+ handlers = new HashMap<URI, Set<NamespaceHandler>>();
+ sets = new ArrayList<NamespaceHandlerSetImpl>();
tracker = new ServiceTracker(bundleContext, NamespaceHandler.class.getName(), this);
tracker.open();
- listeners = new HashMap<Listener, Boolean>();
}
public Object addingService(ServiceReference reference) {
@@ -119,11 +120,15 @@
public synchronized void registerHandler(NamespaceHandler handler, Map properties) {
List<URI> namespaces = getNamespaces(properties);
for (URI uri : namespaces) {
- if (handlers.containsKey(uri)) {
- LOGGER.warn("Ignoring NamespaceHandler for namespace {}, as another handler has already been registered for the same namespace", uri);
- } else {
- handlers.put(uri, handler);
- callListeners(uri, true);
+ Set<NamespaceHandler> h = handlers.get(uri);
+ if (h == null) {
+ h = new HashSet<NamespaceHandler>();
+ handlers.put(uri, h);
+ }
+ if (h.add(handler)) {
+ for (NamespaceHandlerSetImpl s : sets) {
+ s.registerHandler(uri, handler);
+ }
}
}
}
@@ -131,27 +136,15 @@
public synchronized void unregisterHandler(NamespaceHandler handler, Map properties) {
List<URI> namespaces = getNamespaces(properties);
for (URI uri : namespaces) {
- if (handlers.get(uri) != handler) {
+ Set<NamespaceHandler> h = handlers.get(uri);
+ if (h == null || !h.remove(handler)) {
continue;
}
- handlers.remove(uri);
- callListeners(uri, false);
- }
- removeSchemasFor(namespaces);
- }
-
- private void callListeners(URI uri, boolean registered) {
- for (Listener listener : listeners.keySet()) {
- try {
- if (registered) {
- listener.namespaceHandlerRegistered(uri);
- } else {
- listener.namespaceHandlerUnregistered(uri);
- }
- } catch (Throwable t) {
- LOGGER.debug("Unexpected exception when notifying a NamespaceHandler listener", t);
+ for (NamespaceHandlerSetImpl s : sets) {
+ s.unregisterHandler(uri, handler);
}
}
+ removeSchemasFor(handler);
}
private static List<URI> getNamespaces(Map properties) {
@@ -200,29 +193,23 @@
}
}
- public synchronized NamespaceHandler getNamespaceHandler(URI uri) {
- return handlers.get(uri);
+ public synchronized NamespaceHandlerSet getNamespaceHandlers(Set<URI> uris, Bundle bundle) {
+ NamespaceHandlerSetImpl s = new NamespaceHandlerSetImpl(uris, bundle);
+ sets.add(s);
+ return s;
}
public void destroy() {
tracker.close();
}
- public synchronized void addListener(Listener listener) {
- listeners.put(listener, Boolean.TRUE);
- }
-
- public synchronized void removeListener(Listener listener) {
- listeners.remove(listener);
- }
-
- public synchronized Schema getSchema(Set<URI> namespaces) throws IOException, SAXException {
+ public synchronized Schema getSchema(Map<URI, NamespaceHandler> handlers) throws IOException, SAXException {
Schema schema = null;
// 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
- for (Set<URI> key : schemas.keySet()) {
- if (key.containsAll(namespaces)) {
+ for (Map<URI, NamespaceHandler> key : schemas.keySet()) {
+ if (key.equals(handlers)) {
schema = schemas.get(key).get();
break;
}
@@ -233,24 +220,16 @@
schemaSources.add(new StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/blueprint.xsd")));
// Create a schema for all namespaces known at this point
// It will speed things as it can be reused for all other blueprint containers
- namespaces = new HashSet<URI>(handlers.keySet());
- namespaces.add(BLUEPRINT_NAMESPACE);
- for (URI ns : namespaces) {
- if (!BLUEPRINT_NAMESPACE.equals(ns)) {
- NamespaceHandler handler = getNamespaceHandler(ns);
- if (handler == null) {
- throw new IllegalArgumentException("No namespace handler has been registered for " + ns);
- }
- URL url = handler.getSchemaLocation(ns.toString());
- if (url == null) {
- LOGGER.warn("No URL is defined for schema " + ns + ". This schema will not be validated");
- } else {
- schemaSources.add(new StreamSource(url.openStream()));
- }
+ for (URI ns : handlers.keySet()) {
+ URL url = handlers.get(ns).getSchemaLocation(ns.toString());
+ if (url == null) {
+ LOGGER.warn("No URL is defined for schema " + ns + ". This schema will not be validated");
+ } else {
+ schemaSources.add(new StreamSource(url.openStream()));
}
}
schema = getSchemaFactory().newSchema(schemaSources.toArray(new Source[schemaSources.size()]));
- schemas.put(namespaces, new SoftReference<Schema>(schema));
+ schemas.put(handlers, new SoftReference<Schema>(schema));
} finally {
for (StreamSource s : schemaSources) {
try {
@@ -264,27 +243,202 @@
return schema;
}
- protected synchronized void removeSchemasFor(List<URI> namespaces) {
- List<Set<URI>> keys = new ArrayList<Set<URI>>();
- for (URI ns : namespaces) {
- for (Set<URI> key : schemas.keySet()) {
- if (key.contains(ns)) {
- keys.add(key);
- }
+ protected synchronized void removeSchemasFor(NamespaceHandler handler) {
+ List<Map<URI, NamespaceHandler>> keys = new ArrayList<Map<URI, NamespaceHandler>>();
+ for (Map<URI, NamespaceHandler> key : schemas.keySet()) {
+ if (key.values().contains(handler)) {
+ keys.add(key);
}
}
- for (Set<URI> key : keys) {
+ for (Map<URI, NamespaceHandler> key : keys) {
schemas.remove(key);
}
}
private SchemaFactory getSchemaFactory() {
+ SchemaFactory schemaFactory = null;
if (schemaFactory == null) {
schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
}
return schemaFactory;
}
+ protected class NamespaceHandlerSetImpl implements NamespaceHandlerSet {
+
+ private final Map<Listener, Boolean> listeners;
+ private final Bundle bundle;
+ private final Set<URI> namespaces;
+ private final Map<URI, NamespaceHandler> handlers;
+ private Schema schema;
+
+ public NamespaceHandlerSetImpl(Set<URI> namespaces, Bundle bundle) {
+ this.listeners = new HashMap<Listener, Boolean>();
+ this.namespaces = namespaces;
+ this.bundle = bundle;
+ handlers = new HashMap<URI, NamespaceHandler>();
+ for (URI ns : namespaces) {
+ findCompatibleNamespaceHandler(ns);
+ }
+ }
+
+ public boolean isComplete() {
+ return handlers.size() == namespaces.size();
+ }
+
+ public Set<URI> getNamespaces() {
+ return namespaces;
+ }
+
+ public NamespaceHandler getNamespaceHandler(URI namespace) {
+ return handlers.get(namespace);
+ }
+
+ public Schema getSchema() throws SAXException, IOException {
+ if (!isComplete()) {
+ throw new IllegalStateException("NamespaceHandlerSet is not complete");
+ }
+ if (schema == null) {
+ schema = NamespaceHandlerRegistryImpl.this.getSchema(handlers);
+ }
+ return schema;
+ }
+
+ public synchronized void addListener(Listener listener) {
+ listeners.put(listener, Boolean.TRUE);
+ }
+
+ public synchronized void removeListener(Listener listener) {
+ listeners.remove(listener);
+ }
+
+ public void destroy() {
+ NamespaceHandlerRegistryImpl.this.sets.remove(this);
+ }
+
+ public void registerHandler(URI uri, NamespaceHandler handler) {
+ if (namespaces.contains(uri) && handlers.get(uri) == null) {
+ if (findCompatibleNamespaceHandler(uri) != null) {
+ for (Listener listener : listeners.keySet()) {
+ try {
+ listener.namespaceHandlerRegistered(uri);
+ } catch (Throwable t) {
+ LOGGER.debug("Unexpected exception when notifying a NamespaceHandler listener", t);
+ }
+ }
+ }
+ }
+ }
+
+ public void unregisterHandler(URI uri, NamespaceHandler handler) {
+ if (handlers.get(uri) == handler) {
+ handlers.remove(uri);
+ for (Listener listener : listeners.keySet()) {
+ try {
+ listener.namespaceHandlerUnregistered(uri);
+ } catch (Throwable t) {
+ LOGGER.debug("Unexpected exception when notifying a NamespaceHandler listener", t);
+ }
+ }
+ }
+ }
+
+ private NamespaceHandler findCompatibleNamespaceHandler(URI ns) {
+ Set<NamespaceHandler> candidates = NamespaceHandlerRegistryImpl.this.handlers.get(ns);
+ if (candidates != null) {
+ for (NamespaceHandler h : candidates) {
+ Set<Class> classes = h.getManagedClasses();
+ boolean compat = true;
+ if (classes != null) {
+ Set<Class> allClasses = new HashSet<Class>();
+ for (Class cl : classes) {
+ for (Class c = cl; c != null; c = c.getSuperclass()) {
+ allClasses.add(c);
+ for (Class i : c.getInterfaces()) {
+ allClasses.add(i);
+ }
+ }
+ }
+ for (Class cl : allClasses) {
+ Class clb;
+ try {
+ clb = bundle.loadClass(cl.getName());
+ if (clb != cl) {
+ compat = false;
+ break;
+ }
+ } catch (ClassNotFoundException e) {
+ // Ignore
+ }
+ }
+ }
+ if (compat) {
+ handlers.put(ns, h);
+ return h;
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ protected static Map<URI, NamespaceHandler> findHandlers(Map<URI, Set<NamespaceHandler>> allHandlers,
+ Set<URI> namespaces,
+ Bundle bundle) {
+ Map<URI, NamespaceHandler> handlers = new HashMap<URI, NamespaceHandler>();
+ Map<URI, Set<NamespaceHandler>> candidates = new HashMap<URI, Set<NamespaceHandler>>();
+ // Populate initial candidates
+ for (URI ns : namespaces) {
+ Set<NamespaceHandler> h = new HashSet<NamespaceHandler>();
+ if (allHandlers.get(ns) != null) {
+ h.addAll(allHandlers.get(ns));
+ }
+ candidates.put(ns, h);
+ }
+ // Exclude directly incompatible handlers
+ for (URI ns : namespaces) {
+ for (Iterator<NamespaceHandler> it = candidates.get(ns).iterator(); it.hasNext();) {
+ NamespaceHandler h = it.next();
+ Set<Class> classes = h.getManagedClasses();
+ boolean compat = true;
+ if (classes != null) {
+ Set<Class> allClasses = new HashSet<Class>();
+ for (Class cl : classes) {
+ for (Class c = cl; c != null; c = c.getSuperclass()) {
+ allClasses.add(c);
+ for (Class i : c.getInterfaces()) {
+ allClasses.add(i);
+ }
+ }
+ }
+ for (Class cl : allClasses) {
+ Class clb;
+ try {
+ clb = bundle.loadClass(cl.getName());
+ } catch (Throwable t) {
+ clb = null;
+ }
+ if (clb != cl) {
+ compat = false;
+ break;
+ }
+ }
+ }
+ if (!compat) {
+ it.remove();
+ }
+ }
+ }
+ // TODO: do we need to check if there are incompatibilities between namespaces?
+ // Pick the first ones
+ for (URI ns : namespaces) {
+ Set<NamespaceHandler> h = candidates.get(ns);
+ if (!h.isEmpty()) {
+ handlers.put(ns, h.iterator().next());
+ }
+ }
+ return handlers;
+ }
+
public static class LRUMap<K,V> extends AbstractMap<K,V> {
private final int bound;
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/AbstractBlueprintTest.java Wed Oct 7 10:24:46 2009
@@ -29,31 +29,36 @@
import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
import org.apache.aries.blueprint.container.Parser;
import org.apache.aries.blueprint.namespace.ComponentDefinitionRegistryImpl;
+import org.osgi.framework.Bundle;
import org.xml.sax.SAXException;
public abstract class AbstractBlueprintTest extends TestCase {
protected ComponentDefinitionRegistryImpl parse(String name) throws Exception {
- NamespaceHandlerRegistry handlers = new NamespaceHandlerRegistry() {
- public NamespaceHandler getNamespaceHandler(URI uri) {
+ NamespaceHandlerRegistry.NamespaceHandlerSet handlers = new NamespaceHandlerRegistry.NamespaceHandlerSet() {
+ public Set<URI> getNamespaces() {
return null;
}
- public void addCallback(Runnable runnable) {
+ public NamespaceHandler getNamespaceHandler(URI namespace) {
+ return null;
}
- public void destroy() {
+ public void removeListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+ public Schema getSchema() throws SAXException, IOException {
+ return null;
}
- public void addListener(Listener listener) {
+ public boolean isComplete() {
+ return false;
}
- public void removeListener(Listener listener) {
+ public void addListener(NamespaceHandlerRegistry.Listener listener) {
}
- public Schema getSchema(Set<URI> namespaces) throws SAXException, IOException {
- return null;
+ public void destroy() {
}
};
return parse(name, handlers);
}
- protected ComponentDefinitionRegistryImpl parse(String name, NamespaceHandlerRegistry handlers) throws Exception {
+ protected ComponentDefinitionRegistryImpl parse(String name, NamespaceHandlerRegistry.NamespaceHandlerSet handlers) throws Exception {
ComponentDefinitionRegistryImpl registry = new ComponentDefinitionRegistryImpl();
Parser parser = new Parser();
parser.parse(Collections.singletonList(getClass().getResource(name)));
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ParserTest.java Wed Oct 7 10:24:46 2009
@@ -20,6 +20,9 @@
import java.net.URI;
import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.io.IOException;
@@ -32,6 +35,7 @@
import org.apache.aries.blueprint.container.NamespaceHandlerRegistry;
import org.apache.aries.blueprint.reflect.BeanMetadataImpl;
+import org.osgi.framework.Bundle;
import org.osgi.service.blueprint.reflect.BeanArgument;
import org.osgi.service.blueprint.reflect.BeanMetadata;
import org.osgi.service.blueprint.reflect.BeanProperty;
@@ -150,7 +154,7 @@
public void testCustomNodes() throws Exception {
- ComponentDefinitionRegistry registry = parse("/test-custom-nodes.xml", new TestNamespaceHandlerRegistry());
+ ComponentDefinitionRegistry registry = parse("/test-custom-nodes.xml", new TestNamespaceHandlerSet());
ComponentMetadata metadata;
@@ -180,33 +184,52 @@
assertEquals("org.apache.aries.Cache", comp3.getClassName());
}
- private static class TestNamespaceHandlerRegistry implements NamespaceHandlerRegistry {
-
- public void destroy() {
+ private static class TestNamespaceHandlerSet implements NamespaceHandlerRegistry.NamespaceHandlerSet {
+
+ private TestNamespaceHandlerSet() {
}
-
- public NamespaceHandler getNamespaceHandler(URI uri) {
+
+ public Set<URI> getNamespaces() {
+ return Collections.singleton(URI.create("http://cache.org"));
+ }
+
+ public boolean isComplete() {
+ return true;
+ }
+
+ public NamespaceHandler getNamespaceHandler(URI namespace) {
URI u = URI.create("http://cache.org");
- if (u.equals(uri)) {
+ if (u.equals(namespace)) {
return new TestNamespaceHandler();
} else {
return null;
- }
+ }
}
- public void addListener(Listener listener) {
+ public Schema getSchema() throws SAXException, IOException {
+ return null;
}
- public void removeListener(Listener listener) {
+ public void addListener(NamespaceHandlerRegistry.Listener listener) {
}
- public Schema getSchema(Set<URI> namespaces) throws SAXException, IOException {
- return null;
+ public void removeListener(NamespaceHandlerRegistry.Listener listener) {
+ }
+
+ public void destroy() {
}
}
-
+
private static class TestNamespaceHandler implements NamespaceHandler {
+ public URL getSchemaLocation(String namespace) {
+ return getClass().getResource("/cache.xsd");
+ }
+
+ public Set<Class> getManagedClasses() {
+ return new HashSet<Class>();
+ }
+
public ComponentMetadata decorate(Node node,
ComponentMetadata component,
ParserContext context) {
@@ -227,10 +250,6 @@
}
}
- public URL getSchemaLocation(String namespace) {
- return getClass().getResource("/cache.xsd");
- }
-
public Metadata parse(Element element, ParserContext context) {
String comp = (context.getEnclosingComponent() == null) ? null : context.getEnclosingComponent().getId();
//System.out.println("parse: " + element.getLocalName() + " " + comp);
Modified: incubator/aries/trunk/blueprint/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/pom.xml?rev=822645&r1=822644&r2=822645&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/pom.xml (original)
+++ incubator/aries/trunk/blueprint/pom.xml Wed Oct 7 10:24:46 2009
@@ -89,6 +89,17 @@
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>1.4.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.foundation</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>1.2.0</version>
<exclusions>
@@ -199,7 +210,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.0.0</version>
+ <version>2.0.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>