You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by il...@apache.org on 2011/06/23 18:26:37 UTC
svn commit: r1138969 - in /cocoon/cocoon3/trunk/cocoon-sax/src/main:
java/org/apache/cocoon/sax/component/ java/org/apache/cocoon/sax/util/
resources/
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;
+ }
+}