Repository: camel
Updated Branches:
  refs/heads/master 792e4c6d6 -> 77e079a83


CAMEL-9572: Validator: clearSchemaCache method refactored

- it is not a good idea to re-read the schema in the clearSchemaCache
method. Therefore the readSchema method is moved to the SchemaReader.
Now, if the schema was updated and the clearSchemaCache method is called
then the re-reading is tried during the first process call. This change
was especially necessary  to support the case where the schema document
was deleted and the clearSchemaCache was called. In this case. now no
error occurs during the clearSchemaCache call, but the error "no file
found" occurs during the next process call. This is the expected
behavior, in the previous solution the cache would not be cleared at all
and the processing would have went on. 

Change-Id: Ie206872875e2bddaeb036fc4dfb43ec907770787


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/77e079a8
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/77e079a8
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/77e079a8

Branch: refs/heads/master
Commit: 77e079a83861b93d39d556a76019e78cfb9389db
Parents: 792e4c6
Author: Franz Forsthofer <franz.forstho...@sap.com>
Authored: Tue Feb 16 14:00:39 2016 +0100
Committer: Franz Forsthofer <franz.forstho...@sap.com>
Committed: Tue Feb 16 14:00:39 2016 +0100

----------------------------------------------------------------------
 .../component/validator/ValidatorEndpoint.java  | 43 ++++-----------
 .../processor/validation/SchemaReader.java      | 56 ++++++++++++++++++--
 2 files changed, 62 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/77e079a8/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 8cd175e..163364d 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
@@ -16,8 +16,6 @@
  */
 package org.apache.camel.component.validator;
 
-import java.io.IOException;
-import java.io.InputStream;
 import javax.xml.XMLConstants;
 import javax.xml.validation.SchemaFactory;
 
@@ -29,7 +27,6 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
-import org.apache.camel.converter.IOConverter;
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.processor.validation.DefaultValidationErrorHandler;
 import org.apache.camel.processor.validation.SchemaReader;
@@ -39,10 +36,7 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
-import org.apache.camel.util.IOHelper;
-import org.apache.camel.util.ResourceHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
 
 /**
  * Validates the payload of a message using XML Schema and JAXP Validation.
@@ -51,8 +45,6 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(scheme = "validator", title = "Validator", syntax = 
"validator:resourceUri", producerOnly = true, label = "core,validation")
 public class ValidatorEndpoint extends DefaultEndpoint {
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(ValidatorEndpoint.class);
-
     @UriPath(description = "URL to a local resource on the classpath, or a 
reference to lookup a bean in the Registry,"
             + " or a full URL to a remote resource or resource on the file 
system which contains the XSD to validate against.")
     @Metadata(required = "true")
@@ -86,25 +78,23 @@ public class ValidatorEndpoint extends DefaultEndpoint {
      * to be able to clear the cached schema in the schema reader. See method
      * {@link #clearCachedSchema}.
      */
-    private final SchemaReader schemaReader = new SchemaReader();
+    private final SchemaReader schemaReader;
     private volatile boolean schemaReaderConfigured;
 
     public ValidatorEndpoint() {
+        schemaReader = new SchemaReader();
     }
 
     public ValidatorEndpoint(String endpointUri, Component component, String 
resourceUri) {
         super(endpointUri, component);
         this.resourceUri = resourceUri;
+        schemaReader = new SchemaReader(getCamelContext(), resourceUri);
     }
 
     @ManagedOperation(description = "Clears the cached schema, forcing to 
re-load the schema on next request")
-    public void clearCachedSchema() throws Exception {
-        LOG.debug("{} rereading schema resource: {}", this, resourceUri);
-        byte[] bytes = readSchemaResource();
-        schemaReader.setSchemaAsByteArray(bytes);
-
-        schemaReader.setSchema(null); // will cause to reload the schema from
-                                      // the set byte-array on next request
+    public void clearCachedSchema() {
+        
+        schemaReader.setSchema(null); // will cause to reload the schema
     }
 
     @Override
@@ -114,9 +104,9 @@ public class ValidatorEndpoint extends DefaultEndpoint {
             if (resourceResolver != null) {
                 schemaReader.setResourceResolver(resourceResolver);
             } else if (resourceResolverFactory != null) {
+                resourceResolver = 
resourceResolverFactory.createResourceResolver(getCamelContext(), resourceUri);
                 // 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 
DefaultValidatorResourceResolverFactory().createResourceResolver(getCamelContext(),
 resourceUri));
@@ -124,10 +114,6 @@ public class ValidatorEndpoint extends DefaultEndpoint {
             schemaReader.setSchemaLanguage(getSchemaLanguage());
             schemaReader.setSchemaFactory(getSchemaFactory());
             
-            byte[] bytes = readSchemaResource();
-            schemaReader.setSchemaAsByteArray(bytes);
-            LOG.debug("{} using schema resource: {}", this, resourceUri);
-
             // force loading of schema at create time otherwise concurrent
             // processing could cause thread safe issues for the
             // javax.xml.validation.SchemaFactory
@@ -143,18 +129,7 @@ public class ValidatorEndpoint extends DefaultEndpoint {
         return new ValidatorProducer(this, validator);
     }
 
-    protected byte[] readSchemaResource() throws IOException {
-        InputStream is = 
ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), 
resourceUri);
-        byte[] bytes = null;
-        try {
-            bytes = IOConverter.toBytes(is);
-        } finally {
-            // and make sure to close the input stream after the schema has 
been
-            // loaded
-            IOHelper.close(is);
-        }
-        return bytes;
-    }
+
 
     @Override
     public Consumer createConsumer(Processor processor) throws Exception {

http://git-wip-us.apache.org/repos/asf/camel/blob/77e079a8/camel-core/src/main/java/org/apache/camel/processor/validation/SchemaReader.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/processor/validation/SchemaReader.java
 
b/camel-core/src/main/java/org/apache/camel/processor/validation/SchemaReader.java
index 0fdb9e1..12abfdb 100644
--- 
a/camel-core/src/main/java/org/apache/camel/processor/validation/SchemaReader.java
+++ 
b/camel-core/src/main/java/org/apache/camel/processor/validation/SchemaReader.java
@@ -19,6 +19,7 @@ package org.apache.camel.processor.validation;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 
 import javax.xml.XMLConstants;
@@ -30,11 +31,22 @@ import javax.xml.validation.SchemaFactory;
 import org.w3c.dom.ls.LSResourceResolver;
 import org.xml.sax.SAXException;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.converter.IOConverter;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ResourceHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Reads the schema used in the processor {@link ValidatingProcessor}. Contains
  * the method {@link clearCachedSchema()} to force re-reading the schema.
  */
 public class SchemaReader {
+    
+    private static final Logger LOG = 
LoggerFactory.getLogger(SchemaReader.class);
 
     private String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI;
     // must be volatile because is accessed from different threads see 
ValidatorEndpoint.clearCachedSchema
@@ -44,8 +56,24 @@ public class SchemaReader {
     private volatile SchemaFactory schemaFactory;
     private URL schemaUrl;
     private File schemaFile;
-    private volatile byte[] schemaAsByteArray;
+    private byte[] schemaAsByteArray;
+    private final String schemaResourceUri;
     private LSResourceResolver resourceResolver;
+    
+    private final CamelContext camelContext;
+    
+    
+    public SchemaReader() {
+        this(null, null);
+    }
+    
+    /** Specify a camel context and a schema resource URI in order to read the 
schema via the class resolver specified in the Camel context. */
+    public SchemaReader(CamelContext camelContext, String schemaResourceUri) {
+        ObjectHelper.notNull(camelContext, "camelContext");
+        ObjectHelper.notNull(schemaResourceUri, "schemaResourceUri");
+        this.camelContext = camelContext;
+        this.schemaResourceUri = schemaResourceUri;
+    }
 
     public void loadSchema() throws Exception {
         // force loading of schema
@@ -145,7 +173,7 @@ public class SchemaReader {
     }
 
     protected Source createSchemaSource() throws IOException {
-        throw new IllegalArgumentException("You must specify either a schema, 
schemaFile, schemaSource or schemaUrl property");
+        throw new IllegalArgumentException("You must specify either a schema, 
schemaFile, schemaSource, schemaUrl, or schemaUri property");
     }
 
     protected Schema createSchema() throws SAXException, IOException {
@@ -171,11 +199,33 @@ public class SchemaReader {
                 return factory.newSchema(new StreamSource(new 
ByteArrayInputStream(schemaAsByteArray)));
             }
         }
-
+        
+        if (schemaResourceUri != null) {
+            synchronized (this) {
+                bytes = readSchemaResource();
+                return factory.newSchema(new StreamSource(new 
ByteArrayInputStream(bytes)));
+            }          
+        }
+        
         Source source = getSchemaSource();
         synchronized (this) {
             return factory.newSchema(source);
         }
+
+    }
+    
+    protected byte[] readSchemaResource() throws IOException {
+        LOG.debug("reading schema resource: {}", schemaResourceUri);
+        InputStream is = 
ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, 
schemaResourceUri);
+        byte[] bytes = null;
+        try {
+            bytes = IOConverter.toBytes(is);
+        } finally {
+            // and make sure to close the input stream after the schema has 
been
+            // loaded
+            IOHelper.close(is);
+        }
+        return bytes;
     }
 
 }

Reply via email to