You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2011/11/11 23:15:10 UTC

svn commit: r1201073 - in /camel/trunk: camel-core/ camel-core/src/main/java/org/apache/camel/component/validator/ camel-core/src/main/java/org/apache/camel/processor/validation/ camel-core/src/test/java/org/apache/camel/component/validator/ camel-core...

Author: cmueller
Date: Fri Nov 11 22:15:09 2011
New Revision: 1201073

URL: http://svn.apache.org/viewvc?rev=1201073&view=rev
Log:
CAMEL-4666: support catalog entity resolver in validator-component

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorWithResourceResolverRouteTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/validation/CatalogLSResourceResolver.java
    camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/catalog.cat
    camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report-base.xsd
    camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report.xsd
Modified:
    camel/trunk/camel-core/pom.xml
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/validation/ValidatingProcessor.java
    camel/trunk/parent/pom.xml

Modified: camel/trunk/camel-core/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/pom.xml?rev=1201073&r1=1201072&r2=1201073&view=diff
==============================================================================
--- camel/trunk/camel-core/pom.xml (original)
+++ camel/trunk/camel-core/pom.xml Fri Nov 11 22:15:09 2011
@@ -96,6 +96,14 @@
       <artifactId>easymock</artifactId>
       <scope>test</scope>
     </dependency>
+    
+    <!-- validator -->
+	<dependency>
+		<groupId>xml-resolver</groupId>
+		<artifactId>xml-resolver</artifactId>
+		<version>${xml-resolver-version}</version>
+		<scope>test</scope>
+	</dependency>
   </dependencies>
 
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java?rev=1201073&r1=1201072&r2=1201073&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java Fri Nov 11 22:15:09 2011
@@ -18,8 +18,11 @@ package org.apache.camel.component.valid
 
 import java.io.InputStream;
 import java.util.Map;
+
 import javax.xml.transform.stream.StreamSource;
 
+import org.w3c.dom.ls.LSResourceResolver;
+
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.impl.ProcessorEndpoint;
@@ -46,7 +49,8 @@ public class ValidatorComponent extends 
         LOG.debug("{} using schema resource: {}", this, resourceUri);
         configureValidator(validator, uri, remaining, parameters);
 
-        // force loading of schema at create time otherwise concurrent processing could
+        // force loading of schema at create time otherwise concurrent
+        // processing could
         // cause thread safe issues for the javax.xml.validation.SchemaFactory
         validator.loadSchema();
 
@@ -54,6 +58,11 @@ public class ValidatorComponent extends 
     }
 
     protected void configureValidator(ValidatingProcessor validator, String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        LSResourceResolver resourceResolver = resolveAndRemoveReferenceParameter(parameters, "resourceResolver", LSResourceResolver.class);
+        if (resourceResolver != null) {
+            validator.setResourceResolver(resourceResolver);
+        }
+
         setProperties(validator, parameters);
     }
-}
+}
\ No newline at end of file

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/validation/ValidatingProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/validation/ValidatingProcessor.java?rev=1201073&r1=1201072&r2=1201073&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/validation/ValidatingProcessor.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/validation/ValidatingProcessor.java Fri Nov 11 22:15:09 2011
@@ -32,6 +32,8 @@ import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
 import javax.xml.validation.Validator;
 
+import org.w3c.dom.ls.LSResourceResolver;
+
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
@@ -42,7 +44,7 @@ import org.apache.camel.Processor;
  * A processor which validates the XML version of the inbound message body
  * against some schema either in XSD or RelaxNG
  * 
- * @version 
+ * @version
  */
 public class ValidatingProcessor implements Processor {
     // for lazy creation of the Schema
@@ -55,6 +57,7 @@ public class ValidatingProcessor impleme
     private ValidatorErrorHandler errorHandler = new DefaultValidationErrorHandler();
     private boolean useDom;
     private boolean useSharedSchema = true;
+    private LSResourceResolver resourceResolver;
 
     public void process(Exchange exchange) throws Exception {
         Schema schema;
@@ -80,7 +83,8 @@ public class ValidatingProcessor impleme
         }
 
         // create a new errorHandler and set it on the validator
-        // must be a local instance to avoid problems with concurrency (to be thread safe)
+        // must be a local instance to avoid problems with concurrency (to be
+        // thread safe)
         ValidatorErrorHandler handler = errorHandler.getClass().newInstance();
         validator.setErrorHandler(handler);
 
@@ -88,10 +92,9 @@ public class ValidatingProcessor impleme
             validator.validate(source, result);
         } catch (SAXParseException e) {
             // can be thrown for non well formed XML
-            throw new SchemaValidationException(exchange, schema, 
-                                                Collections.singletonList(e), 
-                                                Collections.<SAXParseException>emptyList(), 
-                                                Collections.<SAXParseException>emptyList());
+            throw new SchemaValidationException(exchange, schema, Collections.singletonList(e),
+                    Collections.<SAXParseException> emptyList(),
+                    Collections.<SAXParseException> emptyList());
         }
 
         handler.handleErrors(exchange, schema, result);
@@ -175,10 +178,11 @@ public class ValidatingProcessor impleme
     }
 
     /**
-     * Sets whether DOMSource and DOMResult should be used, or
-     * SaxSource and SaxResult.
-     *
-     * @param useDom true to use DOM otherwise Sax is used
+     * Sets whether DOMSource and DOMResult should be used, or SaxSource and
+     * SaxResult.
+     * 
+     * @param useDom
+     *            true to use DOM otherwise Sax is used
      */
     public void setUseDom(boolean useDom) {
         this.useDom = useDom;
@@ -192,11 +196,21 @@ public class ValidatingProcessor impleme
         this.useSharedSchema = useSharedSchema;
     }
 
+    public LSResourceResolver getResourceResolver() {
+        return resourceResolver;
+    }
+
+    public void setResourceResolver(LSResourceResolver resourceResolver) {
+        this.resourceResolver = resourceResolver;
+    }
+
     // Implementation methods
     // -----------------------------------------------------------------------
 
     protected SchemaFactory createSchemaFactory() {
-        return SchemaFactory.newInstance(schemaLanguage);
+        SchemaFactory factory = SchemaFactory.newInstance(schemaLanguage);
+        factory.setResourceResolver(getResourceResolver());
+        return factory;
     }
 
     protected Source createSchemaSource() throws IOException {
@@ -216,5 +230,4 @@ public class ValidatingProcessor impleme
         }
         return factory.newSchema(getSchemaSource());
     }
-
-}
+}
\ No newline at end of file

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorWithResourceResolverRouteTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorWithResourceResolverRouteTest.java?rev=1201073&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorWithResourceResolverRouteTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorWithResourceResolverRouteTest.java Fri Nov 11 22:15:09 2011
@@ -0,0 +1,98 @@
+/**
+ * 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.camel.component.validator;
+
+import java.net.URL;
+
+import org.w3c.dom.ls.LSResourceResolver;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.impl.PropertyPlaceholderDelegateRegistry;
+import org.apache.camel.processor.validation.CatalogLSResourceResolver;
+import org.apache.camel.util.ResourceHelper;
+import org.apache.xml.resolver.CatalogManager;
+import org.apache.xml.resolver.tools.CatalogResolver;
+
+public class ValidatorWithResourceResolverRouteTest extends ContextTestSupport {
+
+    protected MockEndpoint validEndpoint;
+    protected MockEndpoint finallyEndpoint;
+    protected MockEndpoint invalidEndpoint;
+
+    public void testValidMessage() throws Exception {
+        validEndpoint.expectedMessageCount(1);
+        finallyEndpoint.expectedMessageCount(1);
+        invalidEndpoint.expectedMessageCount(0);
+        template.sendBody(
+                "direct:start",
+                "<report xmlns='http://foo.com/report' xmlns:rb='http://foo.com/report-base'><author><rb:name>Knuth</rb:name></author><content><rb:chapter><rb:subject></rb:subject>"
+                + "<rb:abstract></rb:abstract><rb:body></rb:body></rb:chapter></content></report>");
+
+        MockEndpoint.assertIsSatisfied(validEndpoint, invalidEndpoint, finallyEndpoint);
+    }
+
+    public void testInvalidMessage() throws Exception {
+        validEndpoint.expectedMessageCount(0);
+        invalidEndpoint.expectedMessageCount(1);
+        finallyEndpoint.expectedMessageCount(1);
+
+        template.sendBody(
+                "direct:start",
+                "<report xmlns='http://foo.com/report' xmlns:rb='http://foo.com/report-base'><author><rb:name>Knuth</rb:name></author></report>");
+
+        MockEndpoint.assertIsSatisfied(validEndpoint, invalidEndpoint, finallyEndpoint);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        validEndpoint = resolveMandatoryEndpoint("mock:valid", MockEndpoint.class);
+        invalidEndpoint = resolveMandatoryEndpoint("mock:invalid", MockEndpoint.class);
+        finallyEndpoint = resolveMandatoryEndpoint("mock:finally", MockEndpoint.class);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        // we have to do it here, because we need the context created first
+        CatalogManager.getStaticManager().setIgnoreMissingProperties(true);
+        CatalogResolver catalogResolver = new CatalogResolver(true);
+        URL catalogUrl = ResourceHelper.resolveMandatoryResourceAsUrl(context.getClassResolver(), "org/apache/camel/component/validator/catalog.cat");
+        catalogResolver.getCatalog().parseCatalog(catalogUrl);
+        LSResourceResolver resourceResolver = new CatalogLSResourceResolver(catalogResolver);
+        JndiRegistry registry = (JndiRegistry) ((PropertyPlaceholderDelegateRegistry) context.getRegistry()).getRegistry();
+        registry.bind("resourceResolver", resourceResolver);
+
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .doTry()
+                        .to("validator:org/apache/camel/component/validator/report.xsd?resourceResolver=#resourceResolver")
+                        .to("mock:valid").doCatch(ValidationException.class)
+                        .to("mock:invalid")
+                    .doFinally()
+                        .to("mock:finally")
+                    .end();
+            }
+        };
+    }
+}
\ No newline at end of file

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/validation/CatalogLSResourceResolver.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/validation/CatalogLSResourceResolver.java?rev=1201073&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/validation/CatalogLSResourceResolver.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/validation/CatalogLSResourceResolver.java Fri Nov 11 22:15:09 2011
@@ -0,0 +1,161 @@
+/**
+ * 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.camel.processor.validation;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.InputSource;
+
+import org.apache.xml.resolver.tools.CatalogResolver;
+
+public class CatalogLSResourceResolver implements LSResourceResolver {
+
+    CatalogResolver catalogResolver;
+
+    public CatalogLSResourceResolver() {
+    }
+
+    public CatalogLSResourceResolver(CatalogResolver catalogResolver) {
+        super();
+        this.catalogResolver = catalogResolver;
+    }
+
+    public CatalogResolver getCatalogResolver() {
+        return catalogResolver;
+    }
+
+    public void setCatalogResolver(CatalogResolver catalogResolver) {
+        this.catalogResolver = catalogResolver;
+    }
+
+    @Override
+    public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
+        return new LSInputSource(namespaceURI, publicId, systemId, baseURI);
+    }
+
+    class LSInputSource implements LSInput {
+        private InputSource inputSource;
+        private String publicId;
+        private String systemId;
+        private String baseURI;
+
+        public LSInputSource(String namespaceURI, String publicId, String systemId, String baseURI) {
+            if (publicId == null) {
+                publicId = namespaceURI;
+            }
+            
+            this.publicId = publicId;
+            this.systemId = systemId;
+            this.baseURI = baseURI;
+            
+            if (catalogResolver == null) {
+                throw new IllegalStateException("catalogResolver must be provided");
+            }
+            
+            this.inputSource = catalogResolver.resolveEntity(publicId, systemId);
+        }
+
+        public Reader getCharacterStream() {
+            return null;
+        }
+
+        public void setCharacterStream(Reader characterStream) {
+            // noop
+        }
+
+        public InputStream getByteStream() {
+            return inputSource != null ? inputSource.getByteStream() : null;
+        }
+
+        public void setByteStream(InputStream byteStream) {
+            if (inputSource != null) {
+                inputSource.setByteStream(byteStream);
+            }
+        }
+
+        public String getStringData() {
+            return null;
+        }
+
+        public void setStringData(String stringData) {
+            // noop
+        }
+
+        public String getSystemId() {
+            if (inputSource != null) {
+                return inputSource.getSystemId();
+            }
+
+            return systemId;
+        }
+
+        public void setSystemId(String systemId) {
+            if (inputSource != null) {
+                inputSource.setSystemId(systemId);
+            }
+        }
+
+        public String getPublicId() {
+            if (inputSource != null) {
+                return inputSource.getPublicId();
+            }
+
+            return publicId;
+        }
+
+        public void setPublicId(String publicId) {
+            if (inputSource != null) {
+                inputSource.setPublicId(publicId);
+            } else {
+                this.publicId = publicId;
+            }
+        }
+
+        public String getBaseURI() {
+            return baseURI;
+        }
+
+        public void setBaseURI(String baseURI) {
+            // noop
+        }
+
+        public String getEncoding() {
+            if (inputSource != null) {
+                return inputSource.getEncoding();
+            }
+
+            return null;
+        }
+
+        public void setEncoding(String encoding) {
+            if (inputSource != null) {
+                inputSource.setEncoding(encoding);
+            }
+        }
+
+        public boolean getCertifiedText() {
+            return true;
+        }
+
+        public void setCertifiedText(boolean certifiedText) {
+            // noop
+        }
+    }
+}
\ No newline at end of file

Added: camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/catalog.cat
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/catalog.cat?rev=1201073&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/catalog.cat (added)
+++ camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/catalog.cat Fri Nov 11 22:15:09 2011
@@ -0,0 +1,2 @@
+PUBLIC "http://foo.com/report" "report.xsd"
+PUBLIC "http://foo.com/report-base" "report-base.xsd"

Added: camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report-base.xsd
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report-base.xsd?rev=1201073&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report-base.xsd (added)
+++ camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report-base.xsd Fri Nov 11 22:15:09 2011
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    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.
+-->
+<xs:schema elementFormDefault="qualified" version="1.0"
+           targetNamespace="http://foo.com/report-base"
+           xmlns:tns="http://foo.com/report-base"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+
+  <xs:element name="content" type="tns:content" />
+  
+  <xs:complexType name="content">
+  	<xs:sequence>
+  		<xs:element name="chapter" type="tns:chapter" maxOccurs="unbounded" />
+  	</xs:sequence>
+  </xs:complexType>
+	  
+  <xs:complexType name="chapter">
+    <xs:sequence>
+      <xs:element name="subject" type="xs:string"/>
+      <xs:element name="abstract" type="xs:string"/>
+      <xs:element name="body" type="xs:string"/>
+    </xs:sequence>
+  </xs:complexType>
+
+  <xs:complexType name="person">
+    <xs:sequence>
+      <xs:element name="name" type="xs:string"/>
+      <xs:element name="email" type="xs:string" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>
\ No newline at end of file

Added: camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report.xsd
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report.xsd?rev=1201073&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report.xsd (added)
+++ camel/trunk/camel-core/src/test/resources/org/apache/camel/component/validator/report.xsd Fri Nov 11 22:15:09 2011
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    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.
+-->
+<xs:schema elementFormDefault="qualified" version="1.0"
+           targetNamespace="http://foo.com/report"
+           xmlns:tns="http://foo.com/report"
+           xmlns:rb="http://foo.com/report-base"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+  <xs:import namespace="http://foo.com/report-base" schemaLocation="http://foo.com/report-base.xsd" /> 
+
+  <xs:element name="report">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="author" type="rb:person" maxOccurs="unbounded" />                
+		<xs:element name="content" type="rb:content" />
+        <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file

Modified: camel/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=1201073&r1=1201072&r2=1201073&view=diff
==============================================================================
--- camel/trunk/parent/pom.xml (original)
+++ camel/trunk/parent/pom.xml Fri Nov 11 22:15:09 2011
@@ -157,6 +157,7 @@
     <velocity-version>1.7</velocity-version>
     <woodstox-version>4.1.1</woodstox-version>
     <xbean-spring-version>3.5</xbean-spring-version>
+    <xml-resolver-version>1.2</xml-resolver-version>
     <xstream-version>1.4.1</xstream-version>
     <xmlsec-version>1.4.5</xmlsec-version>
     <xerces-version>2.9.1</xerces-version>