cziegeler 2003/10/28 11:53:57
Modified: src/java/org/apache/cocoon/transformation
TraxTransformer.java
src/webapp sitemap.xmap
src/blocks/deli/java/org/apache/cocoon/transformation
DeliTransformer.java
src/java/org/apache/cocoon/components
ExtendedComponentSelector.java
Log:
Improvements to the TraxTransformer:
- Recycle bug (endDocument was called even when cached).
- Performance improved during parameter handling
- Performance improvement with new configuration
- Better debug statements
Revision Changes Path
1.8 +101 -37
cocoon-2.1/src/java/org/apache/cocoon/transformation/TraxTransformer.java
Index: TraxTransformer.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/transformation/TraxTransformer.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- TraxTransformer.java 24 Oct 2003 12:50:08 -0000 1.7
+++ TraxTransformer.java 28 Oct 2003 19:53:57 -0000 1.8
@@ -56,6 +56,7 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.Map.Entry;
import java.lang.reflect.Method;
import javax.xml.transform.sax.SAXResult;
@@ -97,9 +98,10 @@
* <use-request-parameters>false</use-request-parameters>
*
<use-browser-capabilities-db>false</use-browser-capabilities-db>
* <use-session-info>false</use-session-info>
- * <xslt-processor>xslt</xslt-processor>
+ * <xslt-processor-role>xslt</xslt-processor-role>
*
<transformer-factory>org.apache.xalan.processor.TransformerFactoryImpl</transformer-factory>
* </map:transformer>
+ * <check-includess>true</check-includes>
* </pre>
*
* The <use-request-parameter> configuration forces the transformer to
make all
@@ -135,6 +137,15 @@
* compatibility reasons. Please configure the xslt processor in the
cocoon.xconf properly
* and use the xslt-processor-role configuration mentioned above.
*
+ * The <check-includes> configuration specifies if the included
stylesheets are
+ * also checked for changes during chaching. If this is set to true
(default), the
+ * included stylesheets are also checked for changes; if this is set to
false, only
+ * the main stylesheet is checked. Setting this to false improves the
performance,
+ * and should be used whenever no includs are in the stylesheet. However, if
+ * you have includes, you have to be careful when changing included
stylesheets
+ * as the changes might not take effect immediately. You should touch the
main
+ * stylesheet as well.
+ *
* <p>
* <b>In a map:sitemap/map:pipelines/map:pipeline:</b><br>
* <pre>
@@ -178,11 +189,14 @@
private boolean useSessionInfo = false;
private boolean _useSessionInfo = false;
+ /** Do we check included stylesheets for changes? */
+ private boolean checkIncludes = true;
+
/** The trax TransformerHandler */
protected TransformerHandler transformerHandler;
/** The validity of the Transformer */
- SourceValidity transformerValidity;
+ protected SourceValidity transformerValidity;
/** The Source */
private Source inputSource;
@@ -200,6 +214,9 @@
/** Xalan's DTMManager.getIncremental() method. See recycle() method to
see what we need this for. */
private Method xalanDtmManagerGetIncrementalMethod;
+ /** Exception that might occur during setConsumer */
+ private SAXException exceptionDuringSetConsumer;
+
/**
* Configure this transformer.
*/
@@ -228,12 +245,16 @@
if (!xsltProcessorRole.startsWith(XSLTProcessor.ROLE)) {
xsltProcessorRole = XSLTProcessor.ROLE + '/' + xsltProcessorRole;
}
+
+ child = conf.getChild("check-includes");
+ this.checkIncludes = child.getValueAsBoolean(this.checkIncludes);
+
if (getLogger().isDebugEnabled()) {
getLogger().debug("Use parameters is " + this.useParameters);
getLogger().debug("Use cookies is " + this.useCookies);
getLogger().debug("Use session info is " + this.useSessionInfo);
getLogger().debug("Use TrAX Processor " + xsltProcessorRole);
-
+ getLogger().debug("Check for included stylesheets is " +
this.checkIncludes);
if (traxFactory != null) {
getLogger().debug("Use TrAX Transformer Factory " +
traxFactory);
} else {
@@ -292,20 +313,30 @@
_useParameters = par.getParameterAsBoolean("use-request-parameters",
this.useParameters);
_useCookies = par.getParameterAsBoolean("use-cookies",
this.useCookies);
_useSessionInfo = par.getParameterAsBoolean("use-session-info",
this.useSessionInfo);
-
+ final boolean _checkIncludes =
par.getParameterAsBoolean("check-includes", this.checkIncludes);
+
if (getLogger().isDebugEnabled()) {
getLogger().debug("Using stylesheet: '" +
this.inputSource.getURI() + "' in " + this);
+ getLogger().debug("Use parameters is " + this._useParameters);
+ getLogger().debug("Use cookies is " + this._useCookies);
+ getLogger().debug("Use session info is " + this._useSessionInfo);
+ getLogger().debug("Check for included stylesheets is " +
_checkIncludes);
}
- /** Get a Transformer Handler */
+ // Get a Transformer Handler if we check for includes
+ // If we don't check the handler is get during setConsumer()
try {
- XSLTProcessor.TransformerHandlerAndValidity handlerAndValidity =
-
this.xsltProcessor.getTransformerHandlerAndValidity(inputSource, null);
- this.transformerHandler =
handlerAndValidity.getTransfomerHandler();
- this.transformerValidity =
handlerAndValidity.getTransfomerValidity();
+ if ( _checkIncludes ) {
+ XSLTProcessor.TransformerHandlerAndValidity
handlerAndValidity =
+
this.xsltProcessor.getTransformerHandlerAndValidity(this.inputSource, null);
+ this.transformerHandler =
handlerAndValidity.getTransfomerHandler();
+ this.transformerValidity =
handlerAndValidity.getTransfomerValidity();
+ } else {
+ this.transformerValidity = this.inputSource.getValidity();
+ }
} catch (XSLTProcessorException se) {
- throw new ProcessingException("Unable to get transformer handler
for " + src, se);
- }
+ throw new ProcessingException("Unable to get transformer handler
for " + this.inputSource.getURI(), se);
+ }
}
/**
@@ -340,12 +371,12 @@
* component is currently not cacheable.
*/
public SourceValidity getValidity() {
- /*
- * VG: Key is generated using parameter/value pairs,
- * so this information does not need to be verified again
- * (if parameter added/removed or value changed, key should
- * change also), only stylesheet's validity is included.
- */
+ //
+ // VG: Key is generated using parameter/value pairs,
+ // so this information does not need to be verified again
+ // (if parameter added/removed or value changed, key should
+ // change also), only stylesheet's validity is included.
+ //
return this.transformerValidity;
}
@@ -354,27 +385,41 @@
*/
public void setConsumer(XMLConsumer consumer) {
- Map map = getLogicSheetParameters();
+ if ( this.transformerHandler == null ) {
+ try {
+ this.transformerHandler =
this.xsltProcessor.getTransformerHandler(this.inputSource);
+ } catch (XSLTProcessorException se) {
+ // the exception will be thrown during startDocument()
+ this.exceptionDuringSetConsumer =
+ new SAXException("Unable to get transformer handler for "
+ this.inputSource.getURI(), se);
+ return;
+ }
+ }
+ final Map map = getLogicSheetParameters();
if (map != null) {
- Iterator iterator = map.keySet().iterator();
- while(iterator.hasNext()) {
- String name = (String)iterator.next();
-
transformerHandler.getTransformer().setParameter(name,map.get(name));
+ final javax.xml.transform.Transformer transformer =
this.transformerHandler.getTransformer();
+ final Iterator iterator = map.entrySet().iterator();
+ while (iterator.hasNext()) {
+ final Map.Entry entry = (Entry) iterator.next();
+ transformer.setParameter((String)entry.getKey(),
entry.getValue());
}
}
- super.setContentHandler(transformerHandler);
- super.setLexicalHandler(transformerHandler);
+ super.setContentHandler(this.transformerHandler);
+ super.setLexicalHandler(this.transformerHandler);
- if (transformerHandler instanceof LogEnabled) {
- ((LogEnabled)transformerHandler).enableLogging(getLogger());
+ if (this.transformerHandler instanceof LogEnabled) {
+
((LogEnabled)this.transformerHandler).enableLogging(getLogger());
}
// According to TrAX specs, all TransformerHandlers are
LexicalHandlers
- SAXResult result = new SAXResult(consumer);
+ final SAXResult result = new SAXResult(consumer);
result.setLexicalHandler(consumer);
- transformerHandler.setResult(result);
+ this.transformerHandler.setResult(result);
}
+ /**
+ * Get the parameters for the logicsheet
+ */
protected Map getLogicSheetParameters() {
if (this.logicSheetParameters != null) {
return this.logicSheetParameters;
@@ -417,10 +462,10 @@
}
if (this._useSessionInfo) {
- Request request = ObjectModelHelper.getRequest(objectModel);
+ final Request request =
ObjectModelHelper.getRequest(objectModel);
if (map == null) map = new HashMap(5);
- Session session = request.getSession(false);
+ final Session session = request.getSession(false);
if (session != null) {
map.put("session-available","true");
map.put("session-is-new",session.isNew()?"true":"false");
@@ -451,9 +496,12 @@
}
this.logicSheetParameters = map;
- return map;
+ return this.logicSheetParameters;
}
+ /**
+ * Test if the name is a valid parameter name for XSLT
+ */
static boolean isValidXSLTParameterName(String name) {
if (name.length() == 0) {
return false;
@@ -498,7 +546,7 @@
}
this.resolver = null;
this.par = null;
- if (this.finishedDocument == false && transformerHandler != null) {
+ if (!this.finishedDocument && transformerHandler != null) {
// This situation will only occur if an exception occured during
pipeline execution.
// If Xalan is used in incremental mode, it is important that
endDocument is called, otherwise
// the thread on which it runs the transformation will keep
waiting.
@@ -506,18 +554,20 @@
// serializer will write output to the outputstream after what's
already there (the error page),
// see also bug 13186.
if (xalanDtmManagerGetIncrementalMethod != null
- &&
transformerHandler.getClass().getName().equals("org.apache.xalan.transformer.TransformerHandlerImpl"))
{
+ &&
transformerHandler.getClass().getName().equals("org.apache.xalan.transformer.TransformerHandlerImpl"))
{
try {
- boolean incremental =
((Boolean)xalanDtmManagerGetIncrementalMethod.invoke(null,
null)).booleanValue();
- if (incremental)
+ final boolean incremental =
((Boolean)xalanDtmManagerGetIncrementalMethod.invoke(null,
null)).booleanValue();
+ if (incremental) {
super.endDocument();
+ }
} catch (Exception ignore) {}
}
}
- this.finishedDocument = false;
+ this.finishedDocument = true;
this.logicSheetParameters = null;
this.transformerHandler = null;
this.transformerValidity = null;
+ this.exceptionDuringSetConsumer = null;
super.recycle();
}
@@ -529,4 +579,18 @@
super.endDocument();
this.finishedDocument = true;
}
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#startDocument()
+ */
+ public void startDocument() throws SAXException {
+ // did an exception occur during setConsumer?
+ // if so, throw it here
+ if ( this.exceptionDuringSetConsumer != null ) {
+ throw this.exceptionDuringSetConsumer;
+ }
+ this.finishedDocument = false;
+ super.startDocument();
+ }
+
}
1.36 +4 -9 cocoon-2.1/src/webapp/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/webapp/sitemap.xmap,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- sitemap.xmap 28 Oct 2003 14:17:34 -0000 1.35
+++ sitemap.xmap 28 Oct 2003 19:53:57 -0000 1.36
@@ -82,6 +82,7 @@
<use-session-parameters>false</use-session-parameters>
<use-cookie-parameters>false</use-cookie-parameters>
<xslt-processor-role>xalan</xslt-processor-role>
+ <check-includes>true</check-includes>
</map:transformer>
<!-- NOTE: This is the same as the default processor but with a
different name (for compatibility) -->
@@ -90,6 +91,7 @@
<use-session-parameters>false</use-session-parameters>
<use-cookie-parameters>false</use-cookie-parameters>
<xslt-processor-role>xalan</xslt-processor-role>
+ <check-includes>true</check-includes>
</map:transformer>
<!-- NOTE: You can also try XSLTC as the default processor. If you use
Xalan extensions, use the "xalan" transformer. -->
@@ -98,6 +100,7 @@
<use-session-parameters>false</use-session-parameters>
<use-cookie-parameters>false</use-cookie-parameters>
<xslt-processor-role>xsltc</xslt-processor-role>
+ <check-includes>true</check-includes>
</map:transformer>
<map:transformer logger="sitemap.transformer.xinclude" name="xinclude"
pool-grow="2" pool-max="16" pool-min="2"
src="org.apache.cocoon.transformation.XIncludeTransformer"/>
@@ -337,18 +340,10 @@
| individual map:pipeline elements (using map:parameter syntax).
+-->
<!-- parameter name="outputBufferSize" value="8192"/ -->
- <!--+
- | If you want to use an alternate cache implementation you can
specify
- | the cache-role parameter to indicate the component key of the
cache
- | implementation you want to use. The EventAware implementation
in the
- | example below requires that the eventcache block is present.
- + -->
- <!-- parameter name="cache-role"
value="org.apache.cocoon.caching.Cache/EventAware"/ -->
</map:pipe>
<map:pipe name="caching-point"
src="org.apache.cocoon.components.pipeline.impl.CachingPointProcessingPipeline">
<autoCachingPoint>On</autoCachingPoint>
<!-- parameter name="outputBufferSize" value="8192"/ -->
- <!-- parameter name="cache-role"
value="org.apache.cocoon.caching.Cache/EventAware"/ -->
</map:pipe>
<map:pipe name="noncaching"
src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
<!-- parameter name="outputBufferSize" value="8192"/ -->
1.2 +14 -8
cocoon-2.1/src/blocks/deli/java/org/apache/cocoon/transformation/DeliTransformer.java
Index: DeliTransformer.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/deli/java/org/apache/cocoon/transformation/DeliTransformer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DeliTransformer.java 9 Mar 2003 00:03:45 -0000 1.1
+++ DeliTransformer.java 28 Oct 2003 19:53:57 -0000 1.2
@@ -76,7 +76,7 @@
public class DeliTransformer extends TraxTransformer {
/** The DELI service instance */
- private Deli deli = null;
+ private Deli deli;
/**
* Set the current <code>ComponentManager</code> instance used by this
@@ -88,6 +88,9 @@
this.deli = (Deli) this.manager.lookup(Deli.ROLE);
}
+ /**
+ * Get the parameters for the logicsheet
+ */
protected Map getLogicSheetParameters() {
Map map = super.getLogicSheetParameters();
@@ -102,10 +105,11 @@
map.put("deli-capabilities", deliCapabilities);
String accept = request.getParameter("accept");
- if (accept == null)
+ if (accept == null) {
accept = request.getHeader("accept");
-
- /* add the accept param */
+ }
+
+ // add the accept param
map.put("accept", accept);
} catch (Exception e) {
getLogger().error("Error setting DELI info", e);
@@ -113,15 +117,17 @@
}
this.logicSheetParameters = map;
- return map;
+ return this.logicSheetParameters;
}
/**
* Disposable
*/
public void dispose() {
- this.manager.release(this.deli);
- this.deli = null;
+ if ( this.manager != null ) {
+ this.manager.release(this.deli);
+ this.deli = null;
+ }
super.dispose();
}
}
1.5 +2 -1
cocoon-2.1/src/java/org/apache/cocoon/components/ExtendedComponentSelector.java
Index: ExtendedComponentSelector.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/ExtendedComponentSelector.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ExtendedComponentSelector.java 12 Aug 2003 15:48:02 -0000 1.4
+++ ExtendedComponentSelector.java 28 Oct 2003 19:53:57 -0000 1.5
@@ -371,6 +371,7 @@
this.parentLocator.release( this.parentSelector );
this.parentLocator = null;
this.parentSelector = null;
+ this.parentComponents = null;
}
}