cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject svn commit: r1138969 - in /cocoon/cocoon3/trunk/cocoon-sax/src/main: java/org/apache/cocoon/sax/component/ java/org/apache/cocoon/sax/util/ resources/
Date Thu, 23 Jun 2011 16:26:37 GMT
Author: ilgrosso
Date: Thu Jun 23 16:26:36 2011
New Revision: 1138969

URL: http://svn.apache.org/viewvc?rev=1138969&view=rev
Log:
Enhancing resource cache for XSLT and SchemaProcessor transformers

Added:
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/ValidityValue.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/resources/
Modified:
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/InMemoryLRUResourceCache.java

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java?rev=1138969&r1=1138968&r2=1138969&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
(original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
Thu Jun 23 16:26:36 2011
@@ -18,6 +18,8 @@
  */
 package org.apache.cocoon.sax.component;
 
+import java.io.File;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Map;
 
@@ -32,19 +34,23 @@ import org.apache.cocoon.sax.AbstractSAX
 import org.apache.cocoon.sax.SAXConsumer;
 import org.apache.cocoon.sax.util.InMemoryLRUResourceCache;
 import org.apache.cocoon.sax.util.SAXConsumerAdapter;
+import org.apache.cocoon.sax.util.ValidityValue;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.xml.sax.SAXException;
 
 public final class SchemaProcessorTransformer extends AbstractSAXTransformer {
 
-    private static final InMemoryLRUResourceCache<Schema> SCHEMA_LRU_CACHE = new InMemoryLRUResourceCache<Schema>();
-
-    private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+    private static final Log LOG = LogFactory.getLog(
+            SchemaProcessorTransformer.class);
 
     private static final String SOURCE = "source";
 
-    private final Log logger = LogFactory.getLog(this.getClass());
+    private static final InMemoryLRUResourceCache<Schema> SCHEMA_LRU_CACHE =
+            new InMemoryLRUResourceCache<Schema>();
+
+    private static final SchemaFactory SCHEMA_FACTORY =
+            SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
 
     private Schema schema;
 
@@ -72,7 +78,8 @@ public final class SchemaProcessorTransf
     @Override
     protected void setSAXConsumer(SAXConsumer xmlConsumer) {
         ValidatorHandler validatorHandler = this.schema.newValidatorHandler();
-        validatorHandler.setErrorHandler(new SchemaErrorHandler(this.logger, this.source.toExternalForm()));
+        validatorHandler.setErrorHandler(new SchemaErrorHandler(this.LOG,
+                this.source.toExternalForm()));
         validatorHandler.setContentHandler(xmlConsumer);
 
         SAXConsumerAdapter saxConsumerAdapter = new SAXConsumerAdapter();
@@ -82,20 +89,45 @@ public final class SchemaProcessorTransf
 
     private void init(URL source) {
         if (source == null) {
-            throw new IllegalArgumentException("The parameter 'source' mustn't be null.");
+            throw new IllegalArgumentException("The parameter 'source' "
+                    + "mustn't be null.");
+        }
+
+        this.source = source;
+
+        final File schemaFile;
+        try {
+            schemaFile = "file".equals(this.source.getProtocol())
+                    ? new File(this.source.toURI()) : null;
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Invalid source specified: " + source, e);
         }
 
+        this.schema = null;
         if (SCHEMA_LRU_CACHE.containsKey(source)) {
-            this.schema = SCHEMA_LRU_CACHE.get(source);
-        } else {
+            ValidityValue<Schema> cacheEntry = SCHEMA_LRU_CACHE.get(source);
+            if (schemaFile == null
+                    || cacheEntry.getLastModified() >= schemaFile.lastModified()) {
+
+                this.schema = cacheEntry.getValue();
+            }
+        }
+        if (this.schema == null) {
             try {
-                this.schema = SCHEMA_FACTORY.newSchema(source);
-                SCHEMA_LRU_CACHE.put(source, this.schema);
+                this.schema = schemaFile != null
+                        ? SCHEMA_FACTORY.newSchema(schemaFile)
+                        : SCHEMA_FACTORY.newSchema(source);
+
+                ValidityValue<Schema> cacheEntry = (schemaFile != null)
+                        ? new ValidityValue<Schema>(this.schema,
+                        schemaFile.lastModified())
+                        : new ValidityValue<Schema>(this.schema);
+                SCHEMA_LRU_CACHE.put(source, cacheEntry);
             } catch (SAXException e) {
-                throw new SetupException("Could not initialize xschema source", e);
+                throw new SetupException(
+                        "Could not initialize xschema source", e);
             }
         }
-
-        this.source = source;
     }
 }

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java?rev=1138969&r1=1138968&r2=1138969&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
(original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
Thu Jun 23 16:26:36 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.cocoon.sax.component;
 
+import java.io.File;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
@@ -38,6 +40,7 @@ import org.apache.cocoon.sax.AbstractSAX
 import org.apache.cocoon.sax.SAXConsumer;
 import org.apache.cocoon.sax.util.InMemoryLRUResourceCache;
 import org.apache.cocoon.sax.util.SAXConsumerAdapter;
+import org.apache.cocoon.sax.util.ValidityValue;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -46,22 +49,25 @@ public class XSLTTransformer extends Abs
     /**
      * The memory based LRU cache for already loaded XSLTs.
      */
-    private static final InMemoryLRUResourceCache<Templates> XSLT_CACHE = new InMemoryLRUResourceCache<Templates>();
+    private static final InMemoryLRUResourceCache<Templates> XSLT_CACHE =
+            new InMemoryLRUResourceCache<Templates>();
 
     /**
      * A generic transformer factory to parse XSLTs.
      */
-    private static final SAXTransformerFactory TRAX_FACTORY = createNewSAXTransformerFactory();
+    private static final SAXTransformerFactory TRAX_FACTORY =
+            createNewSAXTransformerFactory();
 
     /**
      * The XSLT parameters name pattern.
      */
-    private static final Pattern XSLT_PARAMETER_NAME_PATTERN = Pattern.compile("[a-zA-Z_][\\w\\-\\.]*");
+    private static final Pattern XSLT_PARAMETER_NAME_PATTERN =
+            Pattern.compile("[a-zA-Z_][\\w\\-\\.]*");
 
     /**
      * This class log.
      */
-    private final Log log = LogFactory.getLog(XSLTTransformer.class);
+    private final Log LOG = LogFactory.getLog(XSLTTransformer.class);
 
     /**
      * The XSLT parameters reference.
@@ -95,52 +101,74 @@ public class XSLTTransformer extends Abs
     }
 
     /**
-     * Creates a new transformer reading the XSLT from the URL source and setting the Transformer
-     * Factory attributes.
+     * Creates a new transformer reading the XSLT from the URL source and 
+     * setting the TransformerFactory attributes.
      *
-     * This constructor is useful when users want to perform XSLT transformation using <a
-     * href="http://xml.apache.org/xalan-j/xsltc_usage.html">xsltc</a>.
+     * This constructor is useful when users want to perform XSLT transformation
+     * using <a href="http://xml.apache.org/xalan-j/xsltc_usage.html">xsltc</a>.
      *
      * @param source the XSLT URL source
      * @param attributes the Transformer Factory attributes
      */
-    public XSLTTransformer(final URL source, final Map<String, Object> attributes)
{
+    public XSLTTransformer(final URL source,
+            final Map<String, Object> attributes) {
+
         super();
         this.loadXSLT(source, attributes);
     }
 
     /**
-     * Method useful to create a new transformer reading the XSLT from the URL source and
setting
-     * the Transformer Factory attributes.
+     * Method useful to create a new transformer reading the XSLT from the URL 
+     * source and setting the Transformer Factory attributes.
      *
-     * This method is useful when users want to perform XSLT transformation using <a
-     * href="http://xml.apache.org/xalan-j/xsltc_usage.html">xsltc</a>.
+     * This method is useful when users want to perform XSLT transformation 
+     * using <a href="http://xml.apache.org/xalan-j/xsltc_usage.html">xsltc</a>.
      *
      * @param source the XSLT URL source
      * @param attributes the Transformer Factory attributes
      */
-    private void loadXSLT(final URL source, final Map<String, Object> attributes) {
+    private void loadXSLT(final URL source,
+            final Map<String, Object> attributes) {
+
         if (source == null) {
-            throw new IllegalArgumentException("The parameter 'source' mustn't be null.");
+            throw new IllegalArgumentException("The parameter 'source' "
+                    + "mustn't be null.");
         }
 
         this.source = source;
 
+        final File xsltFile;
+        try {
+            xsltFile = "file".equals(this.source.getProtocol())
+                    ? new File(this.source.toURI()) : null;
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Invalid source specified: " + source, e);
+        }
+
+        this.templates = null;
         // check the XSLT is in the cache first
         if (XSLT_CACHE.containsKey(source)) {
             // get the XSLT directly from the cache
-            this.templates = XSLT_CACHE.get(this.source);
-        } else {
+            ValidityValue<Templates> cacheEntry = XSLT_CACHE.get(this.source);
+            if (xsltFile == null
+                    || cacheEntry.getLastModified() >= xsltFile.lastModified()) {
+
+                this.templates = cacheEntry.getValue();
+            }
+        }
+        if (this.templates == null) {
             // XSLT has to be parsed
-            Source urlSource = new StreamSource(this.source.toExternalForm());
+            Source urlSource = xsltFile != null
+                    ? new StreamSource(xsltFile)
+                    : new StreamSource(this.source.toExternalForm());
 
             SAXTransformerFactory transformerFactory;
             if (attributes != null && !attributes.isEmpty()) {
                 transformerFactory = createNewSAXTransformerFactory();
                 for (Entry<String, Object> attribute : attributes.entrySet()) {
-                    String name = attribute.getKey();
-                    Object value = attribute.getValue();
-                    transformerFactory.setAttribute(name, value);
+                    transformerFactory.setAttribute(
+                            attribute.getKey(), attribute.getValue());
                 }
             } else {
                 transformerFactory = TRAX_FACTORY;
@@ -149,7 +177,11 @@ public class XSLTTransformer extends Abs
             try {
                 this.templates = transformerFactory.newTemplates(urlSource);
                 // store the XSLT into the cache for future reuse
-                XSLT_CACHE.put(this.source, this.templates);
+                ValidityValue<Templates> cacheEntry = (xsltFile != null)
+                        ? new ValidityValue<Templates>(this.templates,
+                        xsltFile.lastModified())
+                        : new ValidityValue<Templates>(this.templates);
+                XSLT_CACHE.put(this.source, cacheEntry);
             } catch (TransformerConfigurationException e) {
                 throw new SetupException("Impossible to read XSLT from '"
                         + this.source.toExternalForm()
@@ -176,11 +208,14 @@ public class XSLTTransformer extends Abs
      */
     @Override
     @SuppressWarnings("unchecked")
-    public void setConfiguration(final Map<String, ? extends Object> configuration)
{
+    public void setConfiguration(
+            final Map<String, ? extends Object> configuration) {
+
         try {
             this.source = (URL) configuration.get("source");
         } catch (ClassCastException cce) {
-            throw new SetupException("The configuration value of 'source' can't be cast to
java.net.URL.", cce);
+            throw new SetupException("The configuration value of 'source' "
+                    + "can't be cast to java.net.URL.", cce);
         }
 
         if (this.source != null) {
@@ -191,9 +226,10 @@ public class XSLTTransformer extends Abs
                 this.loadXSLT(this.source, null);
             }
         } else {
-            if (this.log.isDebugEnabled()) {
-                this.log.debug("Impossible to load XSLT parameters from '" + this.source
-                        + "' source, make sure it is NOT null and is a valid URL");
+            if (this.LOG.isDebugEnabled()) {
+                this.LOG.debug("Impossible to load XSLT parameters from '"
+                        + this.source + "' source, make sure it is NOT null "
+                        + "and is a valid URL");
             }
         }
 
@@ -207,9 +243,11 @@ public class XSLTTransformer extends Abs
     protected void setSAXConsumer(final SAXConsumer consumer) {
         TransformerHandler transformerHandler;
         try {
-            transformerHandler = TRAX_FACTORY.newTransformerHandler(this.templates);
+            transformerHandler = TRAX_FACTORY.newTransformerHandler(
+                    this.templates);
         } catch (Exception ex) {
-            throw new SetupException("Could not initialize transformer handler.", ex);
+            throw new SetupException(
+                    "Could not initialize transformer handler.", ex);
         }
 
         if (this.parameters != null) {
@@ -231,7 +269,8 @@ public class XSLTTransformer extends Abs
         result.setLexicalHandler(consumer);
         transformerHandler.setResult(result);
 
-        TraxErrorListener traxErrorListener = new TraxErrorListener(this.log, this.source.toExternalForm());
+        TraxErrorListener traxErrorListener = new TraxErrorListener(this.LOG,
+                this.source.toExternalForm());
         transformerHandler.getTransformer().setErrorListener(traxErrorListener);
 
         SAXConsumerAdapter saxConsumerAdapter = new SAXConsumerAdapter();

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/InMemoryLRUResourceCache.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/InMemoryLRUResourceCache.java?rev=1138969&r1=1138968&r2=1138969&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/InMemoryLRUResourceCache.java
(original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/InMemoryLRUResourceCache.java
Thu Jun 23 16:26:36 2011
@@ -24,11 +24,6 @@ import java.util.Map;
 public final class InMemoryLRUResourceCache<V> implements Serializable {
 
     /**
-     * This class serial version UID.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
      * The fixed cache size.
      */
     private static final int CACHE_SIZE = 255;
@@ -41,25 +36,26 @@ public final class InMemoryLRUResourceCa
     /**
      * The fixed cache capacity.
      */
-    private static final int CACHE_CAPACITY = (int) Math.ceil(CACHE_SIZE / LOAD_FACTOR) +
1;
+    private static final int CACHE_CAPACITY =
+            (int) Math.ceil(CACHE_SIZE / LOAD_FACTOR) + 1;
 
     /**
      * The map that implements the LRU cache.
      */
-    private final Map<URL, V> data = new LinkedHashMap<URL, V>(CACHE_CAPACITY,
LOAD_FACTOR) {
-        /**
-         * This class serialVersionUID.
-         */
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<URL, V> eldest) {
-            return size() > CACHE_SIZE;
-        }
-    };
+    private final Map<URL, ValidityValue<V>> data =
+            new LinkedHashMap<URL, ValidityValue<V>>(
+            CACHE_CAPACITY, LOAD_FACTOR) {
+
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                protected boolean removeEldestEntry(
+                        final Map.Entry<URL, ValidityValue<V>> eldest) {
+
+                    return size() > CACHE_SIZE;
+                }
+            };
 
     /**
      * Returns true if this cache contains a mapping for the specified key.
@@ -68,7 +64,7 @@ public final class InMemoryLRUResourceCa
      * @return true if this map contains a mapping for the specified key, false
      *         otherwise.
      */
-    public boolean containsKey(URL key) {
+    public boolean containsKey(final URL key) {
         checkKey(key);
         return this.data.containsKey(key);
     }
@@ -83,7 +79,7 @@ public final class InMemoryLRUResourceCa
      * @return the value to which the specified key is cached, null if this
      *         cache contains no mapping for the key.
      */
-    public V get(URL key) {
+    public ValidityValue<V> get(final URL key) {
         checkKey(key);
         return this.data.get(key);
     }
@@ -96,7 +92,7 @@ public final class InMemoryLRUResourceCa
      * @param key key with which the specified value is to be associated.
      * @param value value to be associated with the specified key.
      */
-    public void put(URL key, V value) {
+    public void put(final URL key, final ValidityValue<V> value) {
         checkKey(key);
         this.data.put(key, value);
     }
@@ -106,10 +102,9 @@ public final class InMemoryLRUResourceCa
      *
      * @param key the key object.
      */
-    private static void checkKey(URL key) {
+    private static void checkKey(final URL key) {
         if (key == null) {
             throw new IllegalArgumentException("null keys not supported");
         }
     }
-
 }

Added: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/ValidityValue.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/ValidityValue.java?rev=1138969&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/ValidityValue.java
(added)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/ValidityValue.java
Thu Jun 23 16:26:36 2011
@@ -0,0 +1,39 @@
+/*
+ * Licensed 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.cocoon.sax.util;
+
+public class ValidityValue<V> {
+
+    final private V value;
+
+    final private long lastModified;
+
+    public ValidityValue(final V value) {
+        this.value = value;
+        this.lastModified = 0;
+    }
+
+    public ValidityValue(final V value, long lastModified) {
+        this.value = value;
+        this.lastModified = lastModified;
+    }
+
+    public V getValue() {
+        return value;
+    }
+
+    public long getLastModified() {
+        return lastModified;
+    }
+}



Mime
View raw message