Hi,
IMHO cacheing/monitoring implemented in XSLComponent
overlaps with the native X:Forge monitoring system.
X:Forge monitoring system philosophy is: Components
doesn' t have to care about changes, when they are invoked
they just produce xml and, if they are monitorizable,
return a monitor which checks if the resources used in the
*current request* change. If monitored resources for a
specific request aren' t changed, associated components
will not be called at all.
In the new XSLComponent version, there is also the possibilty
to monitor the whole xml file used by x:forge. In my opinion
this should be done by the generator/producer/"who loads the file"
in a cocoon/servlet like system.
Transformer cache in XSLComponent, doesn' t consider that a
single Component instance can be used to apply different stylesheets:
<code>
if (hasChanged(mFiles[0])) {
try {
// Initialize a new Transformer
log.debug("Initializing a new transformer.");
StreamSource stylesheet = new StreamSource(mFiles[0]);
mTransformer = mTransformerFactory.newTransformer(stylesheet);
mTransformer.setParameter("lastModified",new
Long(mFiles[0].lastModified()));
}
catch (TransformerConfigurationException tce) {
throw new XForgeException("Something wrong with the transformer:
" + tce.toString());
}
}
else { log.debug("Using cached transformer."); }
[...]
// do the transformation
try {
mTransformer.transform(src,dest);
}
catch (TransformerException te) {
throw new XForgeException("Problem transforming " + xml + " with
" + xsl + ": " + te.toString());
}
</code>
<bug>
<xsltest1>
<xsl:apply>
<xf:parameter name="xml">
<xsldate>
<date:xmlnow/>
</xsldate>
</xf:parameter>
<xf:parameter name="xsl">test/test.xsl</xf:parameter>
</xsl:apply>
</xsltest1>
<xsltest2>
<xsl:apply>
<xf:parameter name="xml">
<xsldate>
<date:xmlnow/>
</xsldate>
</xf:parameter>
<xf:parameter name="xsl">test/test2.xsl</xf:parameter>
</xsl:apply>
</xsltest2>
<xsltest3>
<xsl:apply>
<xf:parameter name="xml">
<xsldate>
<date:xmlnow/>
</xsldate>
</xf:parameter>
<xf:parameter name="xsl">test/test.xsl</xf:parameter>
</xsl:apply>
</xsltest3>
</bug>
The third trasformation will apply test2.xsl instead of test.xsl.
As u can see to make it work correctly, more code has to be
written in the xslcomponent, weighting down it a lot. Consider
also that if we follow this philosophy, each component will reinvent
the wheel each time needs to cache something.
The advantage of the X:Forge monitoring system philosphy is
to make component logic easier and cleaner.
The disadvantage is to re-run a component also if changed
another component used in that request. To avoid this we
should watch at the problem in a more general way; for
example (1) thinking about cacheing each component sax result.
For example:
<test>
<comp1:dosomething>
<xf:param name="param1">
<comp2:dosomething/>
</xf:param>
</comp1:dosomething>
<comp3:dosomething>
<xf:param name="param1">
<comp4:dosomething/>
</xf:param>
</comp1:dosomething>
</test>
If comp2 changes, we must invalidate all it' s ancestors results,
but we can reuse the ouput of comp3.
This is just an idea ...
But probably u need even something more: You want to cache
one of the params passed to the component (in this case the
Transfomation object created parsing the xsl) .... This is more
difficult ...
Hhhhmmm .... Do u really need it ( considered (1) ) ? :)
Ciao,
---
Alberto.
|