You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fo...@apache.org on 2016/02/08 14:22:29 UTC
camel git commit: CAMEL-9572: Validator: support custom resource
resolver factory
Repository: camel
Updated Branches:
refs/heads/master 092f16ebc -> 03b5c2943
CAMEL-9572: Validator: support custom resource resolver factory
support for custom resource resolvers which depend on the resource URI
of the endpoint and which works also for dynamic endpoints
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/03b5c294
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/03b5c294
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/03b5c294
Branch: refs/heads/master
Commit: 03b5c29436a80cf8681ddf514dcaa313e2b105b0
Parents: 092f16e
Author: Franz Forsthofer <fr...@sap.com>
Authored: Sat Feb 6 15:58:35 2016 +0100
Committer: Franz Forsthofer <fr...@sap.com>
Committed: Mon Feb 8 14:20:49 2016 +0100
----------------------------------------------------------------------
...DefaultValidatorResourceResolverFactory.java | 34 ++++
.../component/validator/ValidatorComponent.java | 23 +++
.../component/validator/ValidatorEndpoint.java | 26 ++-
.../ValidatorResourceResolverFactory.java | 50 ++++++
.../ValidatorResourceResolverFactoryTest.java | 164 +++++++++++++++++++
5 files changed, 294 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/03b5c294/camel-core/src/main/java/org/apache/camel/component/validator/DefaultValidatorResourceResolverFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/validator/DefaultValidatorResourceResolverFactory.java b/camel-core/src/main/java/org/apache/camel/component/validator/DefaultValidatorResourceResolverFactory.java
new file mode 100644
index 0000000..ac06bd1
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/component/validator/DefaultValidatorResourceResolverFactory.java
@@ -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.camel.component.validator;
+
+import org.w3c.dom.ls.LSResourceResolver;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * Default resource rsolver factory which instantiates the default resource
+ * rsolver ({@link DefaultLSResourceResolver}).
+ */
+public class DefaultValidatorResourceResolverFactory implements ValidatorResourceResolverFactory {
+
+ @Override
+ public LSResourceResolver createResourceResolver(CamelContext camelContext, String rootResourceUri) {
+ return new DefaultLSResourceResolver(camelContext, rootResourceUri);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/03b5c294/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
index 07e038a..6756530 100644
--- a/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
+++ b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorComponent.java
@@ -20,6 +20,7 @@ import java.util.Map;
import org.apache.camel.Endpoint;
import org.apache.camel.impl.UriEndpointComponent;
+import org.apache.camel.spi.Metadata;
/**
* The <a href="http://camel.apache.org/validation.html">Validator Component</a> is for validating XML against a schema
@@ -28,6 +29,9 @@ import org.apache.camel.impl.UriEndpointComponent;
*/
public class ValidatorComponent extends UriEndpointComponent {
+ @Metadata(label = "advanced", description = "To use a custom LSResourceResolver which depends on a dynamic endpoint resource URI")
+ private ValidatorResourceResolverFactory resourceResolverFactory;
+
public ValidatorComponent() {
this(ValidatorEndpoint.class);
}
@@ -36,8 +40,27 @@ public class ValidatorComponent extends UriEndpointComponent {
super(endpointClass);
}
+ public ValidatorResourceResolverFactory getResourceResolverFactory() {
+ return resourceResolverFactory;
+ }
+
+ public void setResourceResolverFactory(ValidatorResourceResolverFactory resourceResolverFactory) {
+ this.resourceResolverFactory = resourceResolverFactory;
+ }
+
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
ValidatorEndpoint endpoint = new ValidatorEndpoint(uri, this, remaining);
+ // lookup custom resolver to use
+ ValidatorResourceResolverFactory resolverFactory = resolveAndRemoveReferenceParameter(parameters, "resourceResolverFactory", ValidatorResourceResolverFactory.class);
+ if (resolverFactory == null) {
+ // not in endpoint then use component specific resource resolver factory
+ resolverFactory = getResourceResolverFactory();
+ }
+ if (resolverFactory == null) {
+ // fallback to use a Camel default resource resolver factory
+ resolverFactory = new DefaultValidatorResourceResolverFactory();
+ }
+ endpoint.setResourceResolverFactory(resolverFactory);
setProperties(endpoint, parameters);
return endpoint;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/03b5c294/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorEndpoint.java
index 6b04a8c..8cd175e 100644
--- a/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorEndpoint.java
@@ -69,8 +69,11 @@ public class ValidatorEndpoint extends DefaultEndpoint {
@UriParam(defaultValue = "true", label = "advanced",
description = "Whether the Schema instance should be shared or not. This option is introduced to work around a JDK 1.6.x bug. Xerces should not have this issue.")
private boolean useSharedSchema = true;
- @UriParam(label = "advanced", description = "To use a custom LSResourceResolver")
+ @UriParam(label = "advanced", description = "To use a custom LSResourceResolver. Do not use together with resourceResolverFactory")
private LSResourceResolver resourceResolver;
+ @UriParam(label = "advanced", description = "To use a custom LSResourceResolver which depends on a dynamic endpoint resource URI. " + //
+ "The default resource resolver factory resturns a resource resolver which can read files from the class path and file system. Do not use together with resourceResolver.")
+ private ValidatorResourceResolverFactory resourceResolverFactory;
@UriParam(defaultValue = "true", description = "Whether to fail if no body exists.")
private boolean failOnNullBody = true;
@UriParam(defaultValue = "true", description = "Whether to fail if no header exists when validating against a header.")
@@ -110,8 +113,13 @@ public class ValidatorEndpoint extends DefaultEndpoint {
if (!schemaReaderConfigured) {
if (resourceResolver != null) {
schemaReader.setResourceResolver(resourceResolver);
+ } else if (resourceResolverFactory != null) {
+ // set the created resource resolver to the resourceResolver variable, so that it can
+ // be accessed by the endpoint
+ resourceResolver = resourceResolverFactory.createResourceResolver(getCamelContext(), resourceUri);
+ schemaReader.setResourceResolver(resourceResolver);
} else {
- schemaReader.setResourceResolver(new DefaultLSResourceResolver(getCamelContext(), resourceUri));
+ schemaReader.setResourceResolver(new DefaultValidatorResourceResolverFactory().createResourceResolver(getCamelContext(), resourceUri));
}
schemaReader.setSchemaLanguage(getSchemaLanguage());
schemaReader.setSchemaFactory(getSchemaFactory());
@@ -241,12 +249,24 @@ public class ValidatorEndpoint extends DefaultEndpoint {
}
/**
- * To use a custom LSResourceResolver
+ * To use a custom LSResourceResolver. See also {@link #setResourceResolverFactory(ValidatorResourceResolverFactory)}
*/
public void setResourceResolver(LSResourceResolver resourceResolver) {
this.resourceResolver = resourceResolver;
}
+ public ValidatorResourceResolverFactory getResourceResolverFactory() {
+ return resourceResolverFactory;
+ }
+
+ /** For creating a resource resolver which depends on the endpoint resource URI.
+ * Must not be used in combination with method {@link #setResourceResolver(LSResourceResolver).
+ * If not set then {@link DefaultValidatorResourceResolverFactory} is used
+ */
+ public void setResourceResolverFactory(ValidatorResourceResolverFactory resourceResolverFactory) {
+ this.resourceResolverFactory = resourceResolverFactory;
+ }
+
public boolean isFailOnNullBody() {
return failOnNullBody;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/03b5c294/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorResourceResolverFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorResourceResolverFactory.java b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorResourceResolverFactory.java
new file mode 100644
index 0000000..8004e72
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/component/validator/ValidatorResourceResolverFactory.java
@@ -0,0 +1,50 @@
+/**
+ * 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 org.w3c.dom.ls.LSResourceResolver;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * Can be used to create custom resource resolver for the validator endpoint.
+ * This interface is useful, if the custom resource resolver depends on the
+ * resource URI specified in the validator endpoint. The resource URI of the
+ * endpoint can be even dynamic, like in the following example:
+ *
+ * <pre>
+ * {@code <camel:recipientList>}
+ * {@code <camel:simple>}validator:${header.XSD_FILE}?resourceResolverFactory=#resourceResolverFactory{@code</camel:simple>}
+ * {@code </camel:recipientList>}
+ * </pre>
+ *
+ * The dynamic resource URI given in ${header.XSD_FILE} will be past as
+ * rootResourceUri parameter in the method
+ * {@link #createResourceResolver(CamelContext, String)}
+ */
+public interface ValidatorResourceResolverFactory {
+
+ /**
+ * Method is called during the creation of a validator endpoint.
+ *
+ * @param camelContext camel context
+ * @param rootResourceUri resource URI specified in the endpoint URI
+ * @return resource resolver
+ */
+ LSResourceResolver createResourceResolver(CamelContext camelContext, String rootResourceUri);
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/03b5c294/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorResourceResolverFactoryTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorResourceResolverFactoryTest.java b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorResourceResolverFactoryTest.java
new file mode 100644
index 0000000..b55aad7
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorResourceResolverFactoryTest.java
@@ -0,0 +1,164 @@
+/**
+ * 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.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.model.language.ConstantExpression;
+import org.apache.camel.model.language.SimpleExpression;
+import org.junit.Assert;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+
+public class ValidatorResourceResolverFactoryTest extends ContextTestSupport {
+
+ private JndiRegistry registry;
+
+ public void testConfigurationOnEndpoint() throws Exception {
+ // ensure that validator from test method "testConfigurationOnComponent"
+ // is unbind
+ registry.getContext().unbind("validator");
+
+ String directStart = "direct:start";
+ String endpointUri = "validator:org/apache/camel/component/validator/xsds/person.xsd?resourceResolverFactory=#resourceResolverFactory";
+
+ execute(directStart, endpointUri);
+ }
+
+ public void testConfigurationOnComponent() throws Exception {
+ // set resource resolver factory on component
+ ValidatorComponent validatorComponent = new ValidatorComponent();
+ validatorComponent.setResourceResolverFactory(new ResourceResolverFactoryImpl());
+ registry.bind("validator", validatorComponent);
+
+ String directStart = "direct:startComponent";
+ String endpointUri = "validator:org/apache/camel/component/validator/xsds/person.xsd";
+ execute(directStart, endpointUri);
+
+ }
+
+ void execute(String directStart, String endpointUri) throws InterruptedException {
+ MockEndpoint endEndpoint = resolveMandatoryEndpoint("mock:end", MockEndpoint.class);
+ endEndpoint.expectedMessageCount(1);
+
+ final String body = "<p:person user=\"james\" xmlns:p=\"org.person\" xmlns:h=\"org.health.check.person\" xmlns:c=\"org.health.check.common\">\n" //
+ + " <p:firstName>James</p:firstName>\n" //
+ + " <p:lastName>Strachan</p:lastName>\n" //
+ + " <p:city>London</p:city>\n" //
+ + " <h:health>\n"//
+ + " <h:lastCheck>2011-12-23</h:lastCheck>\n" //
+ + " <h:status>OK</h:status>\n" //
+ + " <c:commonElement>" //
+ + " <c:element1/>" //
+ + " <c:element2/>" //
+ + " </c:commonElement>" //
+ + " </h:health>\n" //
+ + "</p:person>";
+
+ template.sendBody(directStart, body);
+
+ // fetch dynamic endpoint
+ ValidatorEndpoint validatorEndpoint = null;
+ for (int i = 0; i < 5; i++) {
+ validatorEndpoint = resolveMandatoryEndpoint(endpointUri, ValidatorEndpoint.class);
+ if (validatorEndpoint != null) {
+ break;
+ }
+ // wait until endpoint is resolved
+ Thread.sleep(50);
+ }
+ MockEndpoint.assertIsSatisfied(endEndpoint);
+ Assert.assertNotNull(validatorEndpoint);
+ CustomResourceResolver resolver = (CustomResourceResolver)validatorEndpoint.getResourceResolver();
+
+ Set<String> uris = resolver.getResolvedResourceUris();
+ checkResourceUri(uris, "../type2.xsd");
+ checkResourceUri(uris, "health/health.xsd");
+ checkResourceUri(uris, "type1.xsd");
+ checkResourceUri(uris, "common/common.xsd");
+ }
+
+ void checkResourceUri(Set<String> uris, String resourceUri) {
+ Assert.assertTrue("Missing resource uri " + resourceUri + " in resolved resource URI set", uris.contains(resourceUri));
+ }
+
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ registry = super.createRegistry();
+ registry.bind("resourceResolverFactory", new ResourceResolverFactoryImpl());
+ return registry;
+
+ }
+
+ @Override
+ protected RouteBuilder[] createRouteBuilders() throws Exception {
+ return new RouteBuilder[] {new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start").setHeader("xsd_file", new ConstantExpression("org/apache/camel/component/validator/xsds/person.xsd"))
+ .recipientList(new SimpleExpression("validator:${header.xsd_file}?resourceResolverFactory=#resourceResolverFactory")).to("mock:end");
+ }
+
+ }, new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+
+ from("direct:startComponent").setHeader("xsd_file", new ConstantExpression("org/apache/camel/component/validator/xsds/person.xsd"))
+ .recipientList(new SimpleExpression("validator:${header.xsd_file}")).to("mock:end");
+
+ }
+ }};
+ }
+
+ static class ResourceResolverFactoryImpl implements ValidatorResourceResolverFactory {
+
+ @Override
+ public LSResourceResolver createResourceResolver(CamelContext camelContext, String rootResourceUri) {
+ return new CustomResourceResolver(camelContext, rootResourceUri);
+ }
+
+ }
+
+ /** Custom resource resolver which collects all resolved resource URIs. */
+ static class CustomResourceResolver extends DefaultLSResourceResolver {
+
+ private final Set<String> resolvedRsourceUris = new HashSet<>();
+
+ CustomResourceResolver(CamelContext camelContext, String resourceUri) {
+ super(camelContext, resourceUri);
+ }
+
+ public Set<String> getResolvedResourceUris() {
+ return resolvedRsourceUris;
+ }
+
+ @Override
+ public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
+ LSInput result = super.resolveResource(type, namespaceURI, publicId, systemId, baseURI);
+ resolvedRsourceUris.add(systemId);
+ return result;
+ }
+
+ }
+
+}