antonio 2004/06/26 01:41:18
Modified: . status.xml
src/java/org/apache/cocoon/generation
JXTemplateGenerator.java
Log:
[PATCH] Caching JXTemplateGenerator
Submitted by: Leszek Gawron
Revision Changes Path
1.372 +4 -1 cocoon-2.1/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/status.xml,v
retrieving revision 1.371
retrieving revision 1.372
diff -u -r1.371 -r1.372
--- status.xml 23 Jun 2004 19:14:34 -0000 1.371
+++ status.xml 26 Jun 2004 08:41:18 -0000 1.372
@@ -204,6 +204,9 @@
<changes>
<release version="@version@" date="@date@">
+ <action dev="AG" type="fix" fixes-bug="29752" due-to="Leszek Gawron">
+ Apply patch: Caching JXTemplateGenerator.
+ </action>
<action dev="VG" type="update">
ResourceReader can now take configuration elements, parameters
are deprecated.
1.47 +70 -14
cocoon-2.1/src/java/org/apache/cocoon/generation/JXTemplateGenerator.java
Index: JXTemplateGenerator.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/generation/JXTemplateGenerator.java,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- JXTemplateGenerator.java 26 Jun 2004 07:31:18 -0000 1.46
+++ JXTemplateGenerator.java 26 Jun 2004 08:41:18 -0000 1.47
@@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.Serializable;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -43,6 +44,7 @@
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.components.flow.FlowHelper;
import org.apache.cocoon.components.flow.WebContinuation;
import
org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptFlowHelper;
@@ -115,7 +117,7 @@
*
* @version CVS $Id$
*/
-public class JXTemplateGenerator extends ServiceableGenerator {
+public class JXTemplateGenerator extends ServiceableGenerator implements
CacheableProcessingComponent {
private static final JXPathContextFactory
jxpathContextFactory = JXPathContextFactory.newInstance();
@@ -711,7 +713,8 @@
final static String PARAMETER = "parameter";
final static String FORMAT_NUMBER = "formatNumber";
final static String FORMAT_DATE = "formatDate";
-
+ final static String CACHE_KEY = "cache-key";
+ final static String VALIDITY = "cache-validity";
/**
* Compile a single Jexl expr (contained in ${}) or XPath expression
@@ -1116,9 +1119,11 @@
static class StartDocument extends Event {
StartDocument(Locator location) {
super(location);
+ templateProperties = new HashMap();
}
SourceValidity compileTime;
EndDocument endDocument; // null if document fragment
+ Map templateProperties;
}
static class EndDocument extends Event {
@@ -2182,8 +2187,18 @@
public void startElement(String namespaceURI, String localName,
String qname, Attributes attrs) throws
SAXException {
Event newEvent = null;
+ AttributesImpl elementAttributes = new AttributesImpl( attrs );
+ int attributeCount = elementAttributes.getLength();
+ for (int i = 0; i < attributeCount; i++) {
+ String attributeURI = elementAttributes.getURI(i);
+ if (StringUtils.equals(attributeURI, NS)) {
+
getStartEvent().templateProperties.put(elementAttributes.getLocalName(i),
+
compileExpr(elementAttributes.getValue(i), null, locator));
+ elementAttributes.removeAttribute(i--);
+ }
+ }
StartElement startElement = new StartElement(locator,
namespaceURI,
- localName, qname,
attrs);
+ localName, qname,
elementAttributes);
if (NS.equals(namespaceURI)) {
if (localName.equals(FOR_EACH)) {
String items = attrs.getValue("items");
@@ -2596,8 +2611,10 @@
"Error during resolving of '" + src + "'.", se);
}
final String uri = inputSource.getURI();
+ boolean regenerate = false;
+ StartDocument startEvent = null;
synchronized (cache) {
- StartDocument startEvent = (StartDocument)cache.get(uri);
+ startEvent = (StartDocument)cache.get(uri);
if (startEvent != null) {
int valid = SourceValidity.UNKNOWN;
if (startEvent.compileTime != null) {
@@ -2609,7 +2626,19 @@
}
if (valid != SourceValidity.VALID) {
cache.remove(uri);
+ regenerate = true;
}
+ } else {
+ regenerate = true;
+ }
+ }
+ if (regenerate) {
+ Parser parser = new Parser();
+ SourceUtil.parse(this.manager, this.inputSource, parser);
+ startEvent = parser.getStartEvent();
+ startEvent.compileTime = this.inputSource.getValidity();
+ synchronized (cache) {
+ cache.put(uri, startEvent);
}
}
}
@@ -2726,15 +2755,6 @@
synchronized (cache) {
startEvent = (StartDocument)cache.get(cacheKey);
}
- if (startEvent == null) {
- Parser parser = new Parser();
- SourceUtil.parse(this.manager, this.inputSource, parser);
- startEvent = parser.getStartEvent();
- startEvent.compileTime = this.inputSource.getValidity();
- synchronized (cache) {
- cache.put(cacheKey, startEvent);
- }
- }
performGeneration(this.xmlConsumer, globalJexlContext, jxpathContext,
null, startEvent, null);
}
@@ -3693,4 +3713,40 @@
ev = ev.next;
}
}
+ /* (non-Javadoc)
+ * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
+ */
+ public Serializable getKey() {
+ JXTExpression cacheKeyExpr =
(JXTExpression)getCurrentTemplateProperty(CACHE_KEY);
+ try {
+ return (Serializable) getValue(cacheKeyExpr,
globalJexlContext, jxpathContext);
+ } catch (Exception e) {
+ getLogger().error("error evaluating cache key", e);
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
+ */
+ public SourceValidity getValidity() {
+ JXTExpression validityExpr =
(JXTExpression)getCurrentTemplateProperty(VALIDITY);
+ try {
+ return (SourceValidity) getValue(validityExpr,
globalJexlContext, jxpathContext);
+ } catch (Exception e) {
+ getLogger().error( "error evaluating cache key", e );
+ return null;
+ }
+ }
+
+ private Object getCurrentTemplateProperty(String propertyName) {
+ final String uri = inputSource.getURI();
+ StartDocument startEvent;
+ synchronized (cache) {
+ startEvent = (StartDocument)cache.get(uri);
+ }
+ if (startEvent == null)
+ return null;
+ return startEvent.templateProperties.get(propertyName);
+ }
}