You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by pr...@apache.org on 2001/01/23 18:34:58 UTC
cvs commit: xml-cocoon/src/org/apache/cocoon/generation FileGenerator.java
prussell 01/01/23 09:34:58
Modified: src/org/apache/cocoon/generation Tag: xml-cocoon2
FileGenerator.java
Log:
Applied patch to FileGenerator from Carsten Ziegeler to make it use
Stefano's XMLCompiler to speed up generation.
Revision Changes Path
No revision
No revision
1.1.2.13 +152 -17 xml-cocoon/src/org/apache/cocoon/generation/Attic/FileGenerator.java
Index: FileGenerator.java
===================================================================
RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/generation/Attic/FileGenerator.java,v
retrieving revision 1.1.2.12
retrieving revision 1.1.2.13
diff -u -r1.1.2.12 -r1.1.2.13
--- FileGenerator.java 2000/12/08 20:39:34 1.1.2.12
+++ FileGenerator.java 2001/01/23 17:34:53 1.1.2.13
@@ -9,42 +9,177 @@
import org.apache.avalon.Poolable;
import java.io.IOException;
+import java.io.File;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Map;
import org.apache.cocoon.components.parser.Parser;
+import org.apache.cocoon.components.store.Store;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Roles;
+import org.apache.cocoon.xml.XMLCompiler;
+import org.apache.cocoon.xml.XMLInterpreter;
+import org.apache.cocoon.xml.XMLMulticaster;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.apache.avalon.ComponentManager;
import org.apache.avalon.ComponentNotFoundException;
import org.apache.avalon.ComponentNotAccessibleException;
+import org.apache.avalon.Configurable;
+import org.apache.avalon.Configuration;
+import org.apache.avalon.ConfigurationException;
+import org.apache.avalon.Parameters;
/**
*
+ *
+ * The <code>FileGenerator</code> is a class that reads XML from a source
+ * and generates SAX Events.
+ *
+ * The generator can use a store to store the compiled xml. The compiled
+ * xml reduces the processing time as no second parsing for that xml is required.
+ * The compiled xml is only generated for local files and can be configured in
+ * the sitemap. The generator can get a default behaviour and each sitemap
+ * pipeline can override this behaviour.
+ * <p>
+ * <code>
+ * <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"><br>
+ * <use-store map:value="false"/><br>
+ * </map:generator>
+ * <:map:generate type="file"><br>
+ * <parameter name="use-store" value="true"/><br>
+ * </map:generate><br>
+ * </code>
+ * </p>
+ *
* @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
* (Apache Software Foundation, Exoffice Technologies)
- * @version CVS $Revision: 1.1.2.12 $ $Date: 2000/12/08 20:39:34 $
+ * @author <a href="mailto:cziegeler@sundn.de">Carsten Ziegeler</a>
+ * @version CVS $Revision: 1.1.2.13 $ $Date: 2001/01/23 17:34:53 $
*/
-public class FileGenerator extends ComposerGenerator implements Poolable {
+public class FileGenerator extends ComposerGenerator implements Poolable, Configurable {
+
+ /** The store service instance */
+ private Store store = null;
+ /** Is the store turned on? (default is off) */
+ private boolean useStore;
+
+ /** The default configuration for useStore */
+ private boolean defaultUseStore;
+
/**
+ * Set the current <code>ComponentManager</code> instance used by this
+ * <code>Composer</code>.
+ */
+ public void compose(ComponentManager manager) {
+ super.compose(manager);
+ try {
+ log.debug("Looking up " + Roles.STORE);
+ this.store = (Store) manager.lookup(Roles.STORE);
+ } catch (Exception e) {
+ log.error("Could not find component", e);
+ }
+ }
+
+ /**
+ * Configure this transformer.
+ */
+ public void configure(Configuration conf)
+ throws ConfigurationException {
+ if (conf != null) {
+ Configuration child = conf.getChild("use-store");
+ this.defaultUseStore = child.getValueAsBoolean(false);
+ }
+ }
+
+ /**
+ * Set the use-store parameter
+ */
+ public void setup(EntityResolver resolver, Map objectModel, String src, Parameters par) {
+ super.setup(resolver, objectModel, src, par);
+ this.useStore = par.getParameterAsBoolean("use-store", this.defaultUseStore);
+ }
+
+ /**
* Generate XML data.
*/
public void generate()
throws IOException, SAXException, ProcessingException {
try {
- log.debug("Looking up " + Roles.PARSER);
- Parser parser=(Parser)this.manager.lookup(Roles.PARSER);
+ // Only local files are checked for modification
+ // External files are never stored
+ // Using the entity resolver we get the filename of the current file:
+ // The systemID if such a resource starts with file:/.
+ InputSource src = super.resolver.resolveEntity(null, super.source);
+ String systemID = src.getSystemId();
+ byte[] cxml = null;
- parser.setContentHandler(this.contentHandler);
- parser.setLexicalHandler(this.lexicalHandler);
- parser.parse(super.resolver.resolveEntity(null,this.source));
- } catch (IOException e) {
- log.error("FileGenerator.generate()", e);
- throw(e);
- } catch (SAXException e) {
- log.error("FileGenerator.generate()", e);
- throw(e);
- } catch (Exception e){
- log.error("Could not get parser", e);
- throw new ProcessingException(e.getMessage());
- }
+ if (this.useStore == true)
+ {
+ // Is this a local file
+ if (systemID.startsWith("file:/") == true) {
+ // Stored is an array of the compiled xml and the caching time
+ if (store.containsKey(systemID) == true) {
+ Object[] cxmlAndTime = (Object[])store.get(systemID);
+ File xmlFile = new File(systemID.substring(6));
+ long storedTime = ((Long)cxmlAndTime[1]).longValue();
+ if (storedTime >= xmlFile.lastModified()) {
+ cxml = (byte[])cxmlAndTime[0];
+ }
+ }
+ }
+ }
+
+ if(cxml == null)
+ {
+ // use the xmlcompiler for local files if storing is on
+ if (this.useStore == true && systemID.startsWith("file:/") == true)
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ XMLCompiler compiler = new XMLCompiler();
+ compiler.setOutputStream(baos);
+ XMLMulticaster multicaster = new XMLMulticaster(compiler, null,
+ this.contentHandler, this.lexicalHandler);
+
+ log.debug("Looking up " + Roles.PARSER);
+ Parser parser=(Parser)this.manager.lookup(Roles.PARSER);
+
+ parser.setContentHandler(multicaster);
+ parser.setLexicalHandler(multicaster);
+ parser.parse(src);
+
+ // Stored is an array of the cxml and the current time
+ Object[] cxmlAndTime = new Object[2];
+ cxmlAndTime[0] = baos.toByteArray();
+ cxmlAndTime[1] = new Long(System.currentTimeMillis());
+ store.hold(systemID, cxmlAndTime);
+ } else {
+ log.debug("Looking up " + Roles.PARSER);
+ Parser parser=(Parser)this.manager.lookup(Roles.PARSER);
+
+ parser.setContentHandler(this.contentHandler);
+ parser.setLexicalHandler(this.lexicalHandler);
+ parser.parse(src);
+ }
+ } else {
+ // use the stored cxml
+ ByteArrayInputStream bais = new ByteArrayInputStream(cxml);
+ XMLInterpreter interpreter = new XMLInterpreter();
+ interpreter.setContentHandler(this.contentHandler);
+ interpreter.setEntityResolver(super.resolver);
+ interpreter.parse(bais);
+ }
+ } catch (IOException e) {
+ log.error("FileGenerator.generate()", e);
+ throw(e);
+ } catch (SAXException e) {
+ log.error("FileGenerator.generate()", e);
+ throw(e);
+ } catch (Exception e){
+ log.error("Could not get parser", e);
+ throw new ProcessingException(e.getMessage());
+ }
}
}