diff --git a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaCollection.java b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaCollection.java
index 50a4f3da..a4d7e1d8 100644
--- a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaCollection.java
+++ b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaCollection.java
@@ -22,6 +22,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.ws.commons.schema.ValidationEventHandler;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
@@ -30,11 +32,16 @@ import org.apache.ws.commons.schema.XmlSchemaImport;
import org.apache.ws.commons.schema.XmlSchemaInclude;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
+import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
+import org.xml.sax.InputSource;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
@@ -52,7 +59,9 @@ import org.springframework.xml.xsd.XsdSchemaCollection;
* @see Commons XML Schema
* @since 1.5.0
*/
-public class CommonsXsdSchemaCollection implements XsdSchemaCollection, InitializingBean {
+public class CommonsXsdSchemaCollection implements XsdSchemaCollection, InitializingBean, ResourceLoaderAware {
+
+ private static final Log logger = LogFactory.getLog(CommonsXsdSchemaCollection.class);
private final XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
@@ -64,6 +73,8 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
private ValidationEventHandler validationEventHandler;
+ private ResourceLoader resourceLoader;
+
/**
* Constructs a new, empty instance of the CommonsXsdSchemaCollection.
*
@@ -104,16 +115,23 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
this.validationEventHandler = validationEventHandler;
}
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
public void afterPropertiesSet() throws IOException {
Assert.notEmpty(xsdResources, "'xsds' must not be empty");
+ schemaCollection.setSchemaResolver(new ClasspathUriResolver());
+
Set processedIncludes = new HashSet();
Set processedImports = new HashSet();
for (int i = 0; i < xsdResources.length; i++) {
- Assert.isTrue(xsdResources[i].exists(), xsdResources[i] + " does not exit");
+ Resource xsdResource = xsdResources[i];
+ Assert.isTrue(xsdResource.exists(), xsdResource + " does not exit");
XmlSchema xmlSchema = schemaCollection
- .read(SaxUtils.createInputSource(xsdResources[i]), validationEventHandler);
+ .read(SaxUtils.createInputSource(xsdResource), validationEventHandler);
xmlSchemas.add(xmlSchema);
if (inline) {
@@ -121,6 +139,10 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
findImports(xmlSchema, processedImports, processedIncludes);
}
}
+ if (logger.isInfoEnabled()) {
+ logger.info("Loaded " + StringUtils.arrayToCommaDelimitedString(xsdResources));
+ }
+
}
public XsdSchema[] getXsdSchemas() {
@@ -200,4 +222,34 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
return buffer.toString();
}
+ private class ClasspathUriResolver extends DefaultURIResolver {
+
+ public InputSource resolveEntity(String namespace, String schemaLocation, String baseUri) {
+ if (resourceLoader != null) {
+ Resource resource = resourceLoader.getResource(schemaLocation);
+ if (resource.exists()) {
+ return createInputSource(resource);
+ }
+ else {
+ // let's try and find it on the classpath, see SWS-362
+ String classpathLocation = ResourceLoader.CLASSPATH_URL_PREFIX + "/" + schemaLocation;
+ resource = resourceLoader.getResource(classpathLocation);
+ if (resource.exists()) {
+ return createInputSource(resource);
+ }
+ }
+ }
+ return super.resolveEntity(namespace, schemaLocation, baseUri);
+ }
+
+ private InputSource createInputSource(Resource resource) {
+ try {
+ return SaxUtils.createInputSource(resource);
+ }
+ catch (IOException ex) {
+ throw new CommonsXsdSchemaException("Could not resolve location", ex);
+ }
+ }
+ }
+
}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java
index dcf6797c..ac491570 100644
--- a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java
+++ b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java
@@ -16,8 +16,6 @@
package org.springframework.xml.xsd.commons;
-import org.apache.ws.commons.schema.XmlSchemaException;
-
import org.springframework.xml.xsd.XsdSchemaException;
/**
@@ -32,7 +30,7 @@ public class CommonsXsdSchemaException extends XsdSchemaException {
super(message);
}
- public CommonsXsdSchemaException(String message, XmlSchemaException exception) {
+ public CommonsXsdSchemaException(String message, Throwable exception) {
super(message, exception);
}
}