Author: gnodet
Date: Tue Apr 12 22:10:44 2016
New Revision: 1738872
URL: http://svn.apache.org/viewvc?rev=1738872&view=rev
Log:
[ARIES-1503] Smarter fix for cxf
CXF jaxws namespace handler imports the standard cxf namespaces, but its
namespace handler always return a url to the jaxws xsd, which is not used at
all.
In order to work around those cases, we do allow the dynamic addition of
namespaces while building the schema. If a schema can’t be found, we raise a
MissingNamespaceException which is handled by the BlueprintContainerImpl and
keep the container in the WaitForNamespaceHandlers state.
Added:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/MissingNamespaceException.java
Modified:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
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/container/BlueprintContainerImpl.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=1738872&r1=1738871&r2=1738872&view=diff
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
(original)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
Tue Apr 12 22:10:44 2016
@@ -54,6 +54,7 @@ import org.apache.aries.blueprint.Proces
import org.apache.aries.blueprint.di.ExecutionContext;
import org.apache.aries.blueprint.di.Recipe;
import org.apache.aries.blueprint.di.Repository;
+import org.apache.aries.blueprint.namespace.MissingNamespaceException;
import org.apache.aries.blueprint.namespace.NamespaceHandlerRegistryImpl;
import org.apache.aries.blueprint.parser.ComponentDefinitionRegistryImpl;
import org.apache.aries.blueprint.parser.NamespaceHandlerSet;
@@ -337,15 +338,21 @@ public class BlueprintContainerImpl
}
}
}
- if (xmlValidation == null ||
"true".equals(xmlValidation)) {
-
parser.validate(handlerSet.getSchema(parser.getSchemaLocations()));
- } else if ("structure".equals(xmlValidation)) {
-
parser.validate(handlerSet.getSchema(parser.getSchemaLocations()), new
ValidationHandler());
- } else if ("psvi".equals(xmlValidation)) {
-
parser.validatePsvi(handlerSet.getSchema(parser.getSchemaLocations()));
+ try {
+ if (xmlValidation == null ||
"true".equals(xmlValidation)) {
+
parser.validate(handlerSet.getSchema(parser.getSchemaLocations()));
+ } else if ("structure".equals(xmlValidation)) {
+
parser.validate(handlerSet.getSchema(parser.getSchemaLocations()), new
ValidationHandler());
+ } else if ("psvi".equals(xmlValidation)) {
+
parser.validatePsvi(handlerSet.getSchema(parser.getSchemaLocations()));
+ }
+ parser.populate(handlerSet,
componentDefinitionRegistry);
+ state = State.Populated;
+ } catch (MissingNamespaceException e) {
+ // If we found a missing namespace when parsing
the schema,
+ // we remain in the current state
+ namespaces.add(e.getNamespace());
}
- parser.populate(handlerSet,
componentDefinitionRegistry);
- state = State.Populated;
break;
}
case Populated:
Added:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/MissingNamespaceException.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/MissingNamespaceException.java?rev=1738872&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/MissingNamespaceException.java
(added)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/MissingNamespaceException.java
Tue Apr 12 22:10:44 2016
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.blueprint.namespace;
+
+import java.net.URI;
+
+public class MissingNamespaceException extends RuntimeException {
+
+ private final URI namespace;
+
+ public MissingNamespaceException(URI namespace) {
+ this.namespace = namespace;
+ }
+
+ public URI getNamespace() {
+ return namespace;
+ }
+}
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=1738872&r1=1738871&r2=1738872&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
Tue Apr 12 22:10:44 2016
@@ -249,25 +249,6 @@ public class NamespaceHandlerRegistryImp
tracker.close();
}
- private Schema getSchema(Map<URI, NamespaceHandler> handlers,
- final Bundle bundle,
- final Properties schemaMap,
- Map<String, String> locations) throws
IOException, SAXException {
- if (schemaMap != null && !schemaMap.isEmpty()) {
- return createSchema(handlers, bundle, schemaMap, locations);
- }
- // 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
- Schema schema = getExistingSchema(handlers);
- if (schema == null) {
- // Create schema
- schema = createSchema(handlers, bundle, schemaMap, locations);
- cacheSchema(handlers, schema);
- }
- return schema;
- }
-
private Schema getExistingSchema(Map<URI, NamespaceHandler> handlers) {
synchronized (schemas) {
for (Map<URI, NamespaceHandler> key : schemas.keySet()) {
@@ -322,51 +303,6 @@ public class NamespaceHandlerRegistryImp
}
}
- private Schema createSchema(Map<URI, NamespaceHandler> handlers,
- Bundle bundle,
- Properties schemaMap,
- Map<String, String> locations) throws
IOException, SAXException {
- final List<StreamSource> schemaSources = new ArrayList<StreamSource>();
- final Map<String, URI> urlToNamespace = new HashMap<String, URI>();
- try {
- schemaSources.add(new
StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/blueprint.xsd")));
- schemaSources.add(new
StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/ext/impl/xml.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
- for (URI ns : handlers.keySet()) {
- URL url = handlers.get(ns).getSchemaLocation(ns.toString());
- if (url == null && locations != null) {
- String loc = locations.get(ns.toString());
- if (loc != null) {
- url = handlers.get(ns).getSchemaLocation(loc);
- }
- }
- if (url == null) {
- LOGGER.warn("No URL is defined for schema " + ns + ". This
schema will not be validated");
- } else {
- urlToNamespace.put(url.toExternalForm(), ns);
- schemaSources.add(new StreamSource(url.openStream(),
url.toExternalForm()));
- }
- }
- for (Object ns : schemaMap.values()) {
- URL url = bundle.getResource(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(),
url.toExternalForm()));
- }
- }
- synchronized (schemaFactory) {
- schemaFactory.setResourceResolver(new
BundleResourceResolver(handlers, schemaMap, bundle, schemaSources,
urlToNamespace));
- return schemaFactory.newSchema(schemaSources.toArray(new
Source[schemaSources.size()]));
- }
- } finally {
- for (StreamSource s : schemaSources) {
- closeQuietly(s.getInputStream());
- }
- }
- }
-
private static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
@@ -377,95 +313,6 @@ public class NamespaceHandlerRegistryImp
}
}
- private static class BundleResourceResolver implements LSResourceResolver {
- private final Map<URI, NamespaceHandler> handlers;
- private final Properties schemaMap;
- private final Bundle bundle;
- private final List<StreamSource> schemaSources;
- private final Map<String, URI> urlToNamespace;
-
- public BundleResourceResolver(Map<URI, NamespaceHandler> handlers,
Properties schemaMap, Bundle bundle, List<StreamSource> schemaSources,
Map<String, URI> urlToNamespace) {
- this.handlers = handlers;
- this.schemaMap = schemaMap;
- this.bundle = bundle;
- this.schemaSources = schemaSources;
- this.urlToNamespace = urlToNamespace;
- }
-
- public LSInput resolveResource(String type,
- final String namespaceURI,
- final String publicId,
- String systemId,
- String baseURI) {
- URI nsUri = namespaceURI != null ? URI.create(namespaceURI) : null;
- // Use provided schema map to find the resource
- String loc = null;
- if (namespaceURI != null) {
- loc = schemaMap.getProperty(namespaceURI);
- }
- if (loc == null && publicId != null) {
- loc = schemaMap.getProperty(publicId);
- }
- if (loc == null && systemId != null) {
- loc = schemaMap.getProperty(systemId);
- }
- if (loc != null) {
- URL url = bundle.getResource(loc);
- if (url != null) {
- return createLSInput(url, nsUri);
- }
- }
- // Support include-relative-path case
- if (baseURI != null && systemId != null &&
!systemId.matches("^[a-z][-+.0-9a-z]*:.*")) {
- URL url;
- try {
- url = new URL(new URL(baseURI), systemId);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return createLSInput(url, nsUri);
- }
- if (namespaceURI != null) {
- String id = systemId != null ? systemId : namespaceURI;
- // This is a namespace with a known handler
- if (handlers.containsKey(nsUri)) {
- NamespaceHandler h = handlers.get(nsUri);
- if (h != null) {
- URL url = h.getSchemaLocation(id);
- if (url != null) {
- return createLSInput(url, nsUri);
- }
- }
- }
- // This is a resource loaded from a schema
- if (baseURI != null && urlToNamespace.containsKey(baseURI)) {
- NamespaceHandler h =
handlers.get(urlToNamespace.get(baseURI));
- if (h != null) {
- URL url = h.getSchemaLocation(id);
- if (url != null) {
- return createLSInput(url, nsUri);
- }
- }
- }
- }
- return null;
- }
-
- private LSInput createLSInput(URL url, URI nsUri) {
- try {
- String systemId = url.toExternalForm();
- final StreamSource source = new StreamSource(url.openStream(),
systemId);
- schemaSources.add(source);
- if (nsUri != null) {
- urlToNamespace.put(systemId, nsUri);
- }
- return new SourceLSInput(source);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
private static class SourceLSInput implements LSInput {
private final StreamSource source;
@@ -590,11 +437,136 @@ public class NamespaceHandlerRegistryImp
throw new IllegalStateException("NamespaceHandlerSet is not
complete");
}
if (schema == null) {
- schema = NamespaceHandlerRegistryImpl.this.getSchema(handlers,
bundle, schemaMap, locations);
+ schema = doGetSchema(locations);
+ }
+ return schema;
+ }
+
+ private Schema doGetSchema(Map<String, String> locations) throws
IOException, SAXException {
+ if (schemaMap != null && !schemaMap.isEmpty()) {
+ return createSchema(locations);
+ }
+ // 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
+ Schema schema = getExistingSchema(handlers);
+ if (schema == null) {
+ // Create schema
+ schema = createSchema(locations);
+ cacheSchema(handlers, schema);
}
return schema;
}
+ private Schema createSchema(Map<String, String> locations) throws
IOException, SAXException {
+ final List<StreamSource> schemaSources = new
ArrayList<StreamSource>();
+ try {
+ schemaSources.add(new
StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/blueprint.xsd")));
+ schemaSources.add(new
StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/ext/impl/xml.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
+ for (URI ns : handlers.keySet()) {
+ URL url =
handlers.get(ns).getSchemaLocation(ns.toString());
+ if (url == null && locations != null) {
+ String loc = locations.get(ns.toString());
+ if (loc != null) {
+ url = handlers.get(ns).getSchemaLocation(loc);
+ }
+ }
+ 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(),
url.toExternalForm()));
+ }
+ }
+ for (Object ns : schemaMap.values()) {
+ URL url = bundle.getResource(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(),
url.toExternalForm()));
+ }
+ }
+ LSResourceResolver resolver = new LSResourceResolver() {
+ public LSInput resolveResource(String type,
+ final String namespaceURI,
+ final String publicId,
+ String systemId,
+ String baseURI) {
+ URI nsUri = namespaceURI != null ?
URI.create(namespaceURI) : null;
+ // Use provided schema map to find the resource
+ String loc = null;
+ if (namespaceURI != null) {
+ loc = schemaMap.getProperty(namespaceURI);
+ }
+ if (loc == null && publicId != null) {
+ loc = schemaMap.getProperty(publicId);
+ }
+ if (loc == null && systemId != null) {
+ loc = schemaMap.getProperty(systemId);
+ }
+ if (loc != null) {
+ URL url = bundle.getResource(loc);
+ if (url != null) {
+ return createLSInput(url);
+ }
+ }
+ // Support include-relative-path case
+ if (baseURI != null && systemId != null &&
!systemId.matches("^[a-z][-+.0-9a-z]*:.*")) {
+ URL url;
+ try {
+ url = new URL(new URL(baseURI), systemId);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return createLSInput(url);
+ }
+ if (namespaceURI != null) {
+ String id = systemId != null ? systemId :
namespaceURI;
+ // This is a namespace with a known handler
+ NamespaceHandler h = getNamespaceHandler(nsUri);
+ if (h == null) {
+ // Find a compatible namespace
+ LOGGER.warn("Dynamically adding namespace
handler {} to bundle {}/{}",
+ nsUri, bundle.getSymbolicName(),
bundle.getVersion());
+ h = findCompatibleNamespaceHandler(nsUri);
+ }
+ // Load from the handler
+ if (h != null) {
+ URL url = h.getSchemaLocation(id);
+ if (url != null) {
+ return createLSInput(url);
+ }
+ } else {
+ throw new MissingNamespaceException(nsUri);
+ }
+ }
+ return null;
+ }
+
+ private LSInput createLSInput(URL url) {
+ try {
+ String systemId = url.toExternalForm();
+ final StreamSource source = new
StreamSource(url.openStream(), systemId);
+ schemaSources.add(source);
+ return new SourceLSInput(source);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ synchronized (schemaFactory) {
+ schemaFactory.setResourceResolver(resolver);
+ return schemaFactory.newSchema(schemaSources.toArray(new
Source[schemaSources.size()]));
+ }
+ } finally {
+ for (StreamSource s : schemaSources) {
+ closeQuietly(s.getInputStream());
+ }
+ }
+ }
+
+
public void addListener(Listener listener) {
listeners.add(listener);
}
@@ -668,6 +640,7 @@ public class NamespaceHandlerRegistryImp
}
}
if (compat) {
+ namespaces.add(ns);
handlers.put(ns, h);
return h;
}