You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by gi...@locus.apache.org on 2000/10/12 18:44:16 UTC

cvs commit: xml-cocoon/xdocs faq.xml license.xml

giacomo     00/10/12 09:44:15

  Modified:    skins/xml.apache.org/stylesheets Tag: xml-cocoon2
                        book2project.xsl changes2document.xsl
                        context2label.xsl copyover.xsl
                        directory2project.xsl document2image.xsl
                        document2project.xsl scan4resources.xsl
                        todo2document.xsl
               src/org/apache/cocoon Tag: xml-cocoon2 Cocoon.java
                        Constants.java Notifier.java
               src/org/apache/cocoon/components/language/generator Tag:
                        xml-cocoon2 ProgramGeneratorImpl.java
               src/org/apache/cocoon/components/language/markup Tag:
                        xml-cocoon2 AbstractMarkupLanguage.java
                        Logicsheet.java LogicsheetCodeGenerator.java
                        MarkupCodeGenerator.java MarkupLanguage.java
                        NamedLogicsheet.java
               src/org/apache/cocoon/components/language/markup/sitemap
                        Tag: xml-cocoon2 SitemapMarkupLanguage.java
               src/org/apache/cocoon/components/language/markup/sitemap/java
                        Tag: xml-cocoon2 sitemap.xsl
               src/org/apache/cocoon/components/language/markup/xsp Tag:
                        xml-cocoon2 XSPMarkupLanguage.java
               src/org/apache/cocoon/sitemap Tag: xml-cocoon2
                        ComponentHolderFactory.java ErrorNotifier.java
               src/org/apache/cocoon/transformation Tag: xml-cocoon2
                        XIncludeTransformer.java XalanTransformer.java
               src/org/apache/cocoon/util Tag: xml-cocoon2 DOMUtils.java
               src/org/apache/cocoon/xml/xpath Tag: xml-cocoon2
                        XPathAPI.java
               webapp/stylesheets/system Tag: xml-cocoon2 error2html.xsl
                        status2html.xsl
               xdocs    Tag: xml-cocoon2 faq.xml license.xml
  Log:
  Moving to Xalan2J
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/book2project.xsl
  
  Index: book2project.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/book2project.xsl,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- book2project.xsl	2000/03/20 22:01:23	1.1.2.1
  +++ book2project.xsl	2000/10/12 16:43:04	1.1.2.2
  @@ -176,4 +176,4 @@
       </create>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.5.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/changes2document.xsl
  
  Index: changes2document.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/changes2document.xsl,v
  retrieving revision 1.5.2.1
  retrieving revision 1.5.2.2
  diff -u -r1.5.2.1 -r1.5.2.2
  --- changes2document.xsl	2000/03/20 22:01:23	1.5.2.1
  +++ changes2document.xsl	2000/10/12 16:43:05	1.5.2.2
  @@ -51,4 +51,4 @@
     <!-- remove -->
    </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.2.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/context2label.xsl
  
  Index: context2label.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/context2label.xsl,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- context2label.xsl	2000/03/20 22:01:23	1.2.2.1
  +++ context2label.xsl	2000/10/12 16:43:05	1.2.2.2
  @@ -18,4 +18,4 @@
       </xsl:if>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.2.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/copyover.xsl
  
  Index: copyover.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/copyover.xsl,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- copyover.xsl	2000/03/20 22:01:24	1.2.2.1
  +++ copyover.xsl	2000/10/12 16:43:05	1.2.2.2
  @@ -8,4 +8,4 @@
       </xsl:copy>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.3.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/directory2project.xsl
  
  Index: directory2project.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/directory2project.xsl,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- directory2project.xsl	2000/03/20 22:01:24	1.3.2.1
  +++ directory2project.xsl	2000/10/12 16:43:08	1.3.2.2
  @@ -16,4 +16,4 @@
       </xsl:if>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.2.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/document2image.xsl
  
  Index: document2image.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/document2image.xsl,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- document2image.xsl	2000/03/20 22:01:24	1.2.2.1
  +++ document2image.xsl	2000/10/12 16:43:08	1.2.2.2
  @@ -17,4 +17,4 @@
       </image>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.1.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/document2project.xsl
  
  Index: document2project.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/document2project.xsl,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- document2project.xsl	2000/03/20 22:01:25	1.1.2.1
  +++ document2project.xsl	2000/10/12 16:43:08	1.1.2.2
  @@ -16,4 +16,4 @@
       <xsl:apply-templates/>
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.1.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/scan4resources.xsl
  
  Index: scan4resources.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/scan4resources.xsl,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- scan4resources.xsl	2000/03/20 22:01:25	1.1.2.1
  +++ scan4resources.xsl	2000/10/12 16:43:08	1.1.2.2
  @@ -16,4 +16,4 @@
        <!-- ignore -->
     </xsl:template>
   
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  1.1.2.2   +1 -1      xml-cocoon/skins/xml.apache.org/stylesheets/todo2document.xsl
  
  Index: todo2document.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/skins/xml.apache.org/stylesheets/todo2document.xsl,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- todo2document.xsl	2000/03/20 22:01:25	1.1.2.1
  +++ todo2document.xsl	2000/10/12 16:43:08	1.1.2.2
  @@ -28,4 +28,4 @@
     </s2>
    </xsl:template>
    
  -</xsl:stylesheet>
  \ No newline at end of file
  +</xsl:stylesheet>
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.4.2.30  +33 -1     xml-cocoon/src/org/apache/cocoon/Cocoon.java
  
  Index: Cocoon.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/Cocoon.java,v
  retrieving revision 1.4.2.29
  retrieving revision 1.4.2.30
  diff -u -r1.4.2.29 -r1.4.2.30
  --- Cocoon.java	2000/09/28 19:13:59	1.4.2.29
  +++ Cocoon.java	2000/10/12 16:43:11	1.4.2.30
  @@ -41,7 +41,7 @@
    * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
    *         (Apache Software Foundation, Exoffice Technologies)
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  - * @version CVS $Revision: 1.4.2.29 $ $Date: 2000/09/28 19:13:59 $
  + * @version CVS $Revision: 1.4.2.30 $ $Date: 2000/10/12 16:43:11 $
    */
   public class Cocoon
     implements Component, Configurable, ComponentManager, Modifiable, Processor, Constants {
  @@ -77,6 +77,9 @@
        * Create a new <code>Cocoon</code> instance.
        */
       protected Cocoon() throws ConfigurationException {
  +        // Set the system properties needed by Xalan2.
  +        setSystemProperties();
  +
           // Setup the default parser, for parsing configuration.
           // If one need to use a different parser, set the given system property
           String parser = System.getProperty(PARSER_PROPERTY, DEFAULT_PARSER);
  @@ -85,6 +88,13 @@
           } catch (Exception e) {
               throw new ConfigurationException("Error creating parser (" + parser + ")", null);
           }
  +        String processor = System.getProperty(PROCESSOR_PROPERTY, DEFAULT_PROCESSOR);
  +        try {
  +			trax.Processor.setPlatformDefaultProcessor(processor);
  +            this.components.put("processor", ClassUtils.loadClass(parser));
  +        } catch (Exception e) {
  +            throw new ConfigurationException("Error creating processor (" + processor + ")", null);
  +        }
       }
       
       /**
  @@ -228,4 +238,26 @@
           String file = new URL(environment.resolveEntity(null, this.sitemapFileName).getSystemId()).getFile();
           return this.sitemapManager.invoke(environment, "", file, true);
       }
  +
  +  /**
  +   * Sets required system properties .
  +   */	
  +    protected void setSystemProperties()
  +	{
  +	  java.util.Properties props = new java.util.Properties();
  +
  +      // This is needed by Xalan2, it is used by org.xml.sax.helpers.XMLReaderFactory
  +      // to locate the SAX2 driver.
  +	  props.put("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
  +	  
  +      java.util.Properties systemProps = System.getProperties();
  +      Enumeration propEnum = props.propertyNames();
  +      while(propEnum.hasMoreElements())
  +      {
  +        String prop = (String)propEnum.nextElement();
  +        if(!systemProps.containsKey(prop))
  +          systemProps.put(prop, props.getProperty(prop));
  +      }
  +      System.setProperties(systemProps);
  +	}
   }
  
  
  
  1.1.2.9   +4 -1      xml-cocoon/src/org/apache/cocoon/Attic/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/Attic/Constants.java,v
  retrieving revision 1.1.2.8
  retrieving revision 1.1.2.9
  diff -u -r1.1.2.8 -r1.1.2.9
  --- Constants.java	2000/10/06 21:25:27	1.1.2.8
  +++ Constants.java	2000/10/12 16:43:11	1.1.2.9
  @@ -10,7 +10,7 @@
   
   /**
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  - * @version CVS $Revision: 1.1.2.8 $ $Date: 2000/10/06 21:25:27 $
  + * @version CVS $Revision: 1.1.2.9 $ $Date: 2000/10/12 16:43:11 $
    */
   
   public interface Constants {
  @@ -33,6 +33,9 @@
   
       public static final String PARSER_PROPERTY = "org.apache.cocoon.components.parser.Parser";
       public static final String DEFAULT_PARSER  = "org.apache.cocoon.components.parser.XercesParser";
  +    public static final String PROCESSOR_PROPERTY = "trax.processor.xslt";
  +    public static final String DEFAULT_PROCESSOR = "org.apache.xalan.processor.StylesheetProcessor";
  +
   
       public static final String XSP_PREFIX          = "xsp";
       public static final String XSP_URI             = "http://apache.org/xsp";
  
  
  
  1.1.2.6   +17 -17    xml-cocoon/src/org/apache/cocoon/Attic/Notifier.java
  
  Index: Notifier.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/Attic/Notifier.java,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- Notifier.java	2000/09/29 01:02:51	1.1.2.5
  +++ Notifier.java	2000/10/12 16:43:11	1.1.2.6
  @@ -32,7 +32,7 @@
    *
    * @author <a href="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a> Aisa
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  - * @version CVS $Revision: 1.1.2.5 $ $Date: 2000/09/29 01:02:51 $
  + * @version CVS $Revision: 1.1.2.6 $ $Date: 2000/10/12 16:43:11 $
    */
    
   public class Notifier {
  @@ -83,7 +83,7 @@
       public static void notify(Notificable n, ContentHandler ch) throws SAXException {
   
           final String PREFIX = Cocoon.ERROR_NAMESPACE_PREFIX;
  -        final String URI = Cocoon.ERROR_NAMESPACE_PREFIX;
  +        final String URI = Cocoon.ERROR_NAMESPACE_URI;
   
           String buf;
           
  @@ -94,28 +94,28 @@
           // Root element.
           AttributesImpl atts = new AttributesImpl();
   
  -        atts.addAttribute(URI, "type", "type", "CDATA", n.getType());
  -        atts.addAttribute(URI, "sender", "sender", "CDATA", n.getSender());
  -        ch.startElement(URI, "notify", "notify", atts);
  -        ch.startElement(URI, "title", "title", new AttributesImpl());
  +        atts.addAttribute(URI, "type", "error:type", "CDATA", n.getType());
  +        atts.addAttribute(URI, "sender", "error:sender", "CDATA", n.getSender());
  +        ch.startElement(URI, "notify", "error:notify", atts);
  +        ch.startElement(URI, "title", "error:title", new AttributesImpl());
           ch.characters(n.getTitle().toCharArray(), 0, n.getTitle().length());
  -        ch.endElement(URI, "title", "title");
  -        ch.startElement(URI, "source", "source", new AttributesImpl());
  +        ch.endElement(URI, "title", "error:title");
  +        ch.startElement(URI, "source", "error:source", new AttributesImpl());
           ch.characters(n.getSource().toCharArray(), 0, n.getSource().length());
  -        ch.endElement(URI, "source", "source");
  -        ch.startElement(URI, "message", "message", new AttributesImpl());
  +        ch.endElement(URI, "source", "error:source");
  +        ch.startElement(URI, "message", "error:message", new AttributesImpl());
   
           if (n.getMessage() != null) {
               ch.characters(n.getMessage().toCharArray(), 0,
                             n.getMessage().length());
           }
   
  -        ch.endElement(URI, "message", "message");
  -        ch.startElement(URI, "description", "description",
  +        ch.endElement(URI, "message", "error:message");
  +        ch.startElement(URI, "description", "error:description",
                           new AttributesImpl());
           ch.characters(n.getDescription().toCharArray(), 0,
                         n.getDescription().length());
  -        ch.endElement(URI, "description", "description");
  +        ch.endElement(URI, "description", "error:description");
   
           HashMap  extraDescriptions = n.getExtraDescriptions();
           Iterator keyIter           = extraDescriptions.keySet().iterator();
  @@ -125,17 +125,17 @@
   
               atts = new AttributesImpl();
   
  -            atts.addAttribute(URI, "description", "description", "CDATA",
  +            atts.addAttribute(URI, "description", "error:description", "CDATA",
                                 key);
  -            ch.startElement(URI, "extra", "extra", atts);
  +            ch.startElement(URI, "extra", "error:extra", atts);
               ch.characters(extraDescriptions.get(key).toString().toCharArray(),
                             0, (extraDescriptions.get(key).toString())
                                 .length());
  -            ch.endElement(URI, "extra", "extra");
  +            ch.endElement(URI, "extra", "error:extra");
           }
   
           // End root element.
  -        ch.endElement(URI, "notify", "notify");
  +        ch.endElement(URI, "notify", "error:notify");
   
           // End the document.
           ch.endPrefixMapping(PREFIX);
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.12  +15 -16    xml-cocoon/src/org/apache/cocoon/components/language/generator/Attic/ProgramGeneratorImpl.java
  
  Index: ProgramGeneratorImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/generator/Attic/ProgramGeneratorImpl.java,v
  retrieving revision 1.1.2.11
  retrieving revision 1.1.2.12
  diff -u -r1.1.2.11 -r1.1.2.12
  --- ProgramGeneratorImpl.java	2000/09/22 20:27:29	1.1.2.11
  +++ ProgramGeneratorImpl.java	2000/10/12 16:43:13	1.1.2.12
  @@ -5,7 +5,7 @@
    * version 1.1, a copy of which has been included  with this distribution in *
    * the LICENSE file.                                                         *
    *****************************************************************************/
  - 
  +
   package org.apache.cocoon.components.language.generator;
   
   import java.io.File;
  @@ -49,7 +49,7 @@
    * The default implementation of <code>ProgramGenerator</code>
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.11 $ $Date: 2000/09/22 20:27:29 $
  + * @version CVS $Revision: 1.1.2.12 $ $Date: 2000/10/12 16:43:13 $
    */
   public class ProgramGeneratorImpl
     implements ProgramGenerator, Composer, Configurable
  @@ -126,7 +126,7 @@
       if (programmingLanguage instanceof Composer) {
           ((Composer) programmingLanguage).setComponentManager(this.manager);
       }
  -    
  +
       // Create filesystem store
       FilesystemStore repository = new FilesystemStore(this.workDir);
   
  @@ -142,7 +142,7 @@
       synchronized(filename.intern()) {
         // Attempt to load program object from cache
         program = this.cache.get(filename);
  -  
  +
         try {
           if (program == null) {
             /*
  @@ -152,7 +152,7 @@
             program = programmingLanguage.load(
               normalizedName, this.workDir, null
             );
  -  
  +
             // Store loaded program in cache
             this.cache.store(filename, program);
           }
  @@ -160,7 +160,7 @@
           // Instantiate program
           programInstance = programmingLanguage.instantiate(program);
         } catch (LanguageException e) { }
  -      
  +
         /*
            FIXME: It's the program (not the instance) that must
            be queried for changes!!!
  @@ -176,31 +176,30 @@
           programmingLanguage.unload(
             program, normalizedName, this.workDir
           );
  -  
  +
           // Invalidate previous program/instance pair
           program = null;
           programInstance = null;
         }
  -  
  +
         if (program == null) {
           // Generate code
  -        Document document =
  -          DOMUtils.DOMParse(new InputSource(new FileReader(file)));
  -        String encoding = markupLanguage.getEncoding(document);
           String code = markupLanguage.generateCode(
  -          document, normalizedName, programmingLanguage, resolver
  +          new InputSource(new FileReader(file)), normalizedName, programmingLanguage, resolver
           );
  -  
  +
  +        String encoding = markupLanguage.getEncoding();
  +
           // Format source code if applicable
           CodeFormatter codeFormatter = programmingLanguage.getCodeFormatter();
           if (codeFormatter != null) {
             code = codeFormatter.format(code, encoding);
           }
  -  
  +
           // Store generated code
           String sourceFilename = filename + "." + sourceExtension;
           repository.store(sourceFilename, code);
  -  
  +
           // Verify source file generation was successful
           File sourceFile = (File) repository.get(sourceFilename);
           if (sourceFile == null) {
  @@ -208,7 +207,7 @@
               "Error creating source file: " + sourceFilename
             );
           }
  -  
  +
           // [Compile]/Load generated program
           program = programmingLanguage.load(
             normalizedName, this.workDir, encoding
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +600 -477  xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/AbstractMarkupLanguage.java
  
  Index: AbstractMarkupLanguage.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/AbstractMarkupLanguage.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- AbstractMarkupLanguage.java	2000/10/02 11:07:26	1.1.2.7
  +++ AbstractMarkupLanguage.java	2000/10/12 16:43:15	1.1.2.8
  @@ -13,18 +13,23 @@
   import java.net.MalformedURLException;
   import java.util.Date;
   import java.util.Vector;
  +import java.util.List;
  +import java.util.ArrayList;
   import java.util.Hashtable;
   import java.util.Enumeration;
   
  -import org.w3c.dom.Attr;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.NamedNodeMap;
  -
   import org.xml.sax.InputSource;
   import org.xml.sax.EntityResolver;
   import org.xml.sax.SAXException;
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.XMLFilter;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.helpers.XMLFilterImpl;
  +import org.xml.sax.helpers.XMLReaderFactory;
  +
  +import trax.Processor;
  +import trax.Transformer;
  +import trax.Templates;
   
   import org.apache.avalon.Composer;
   import org.apache.avalon.Component;
  @@ -42,482 +47,600 @@
   /**
    * Base implementation of <code>MarkupLanguage</code>. This class uses
    * logicsheets as the only means of code generation. Code generation should
  - * be decoupled from this context!!! Moreover, this class uses DOM documents
  - * (as opposed to Cocoon2's standard SAX events)
  + * be decoupled from this context!!!
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.7 $ $Date: 2000/10/02 11:07:26 $
  + * @version CVS $Revision: 1.1.2.8 $ $Date: 2000/10/12 16:43:15 $
    */
   public abstract class AbstractMarkupLanguage
  -  extends AbstractNamedComponent
  -  implements MarkupLanguage, Composer
  +    extends AbstractNamedComponent
  +    implements MarkupLanguage, Composer
   {
  -  /**
  -   * The supported language table
  -   */
  -  protected Hashtable languages;
  -
  -  /**
  -   * The in-memory code-generation logicsheet cache
  -   */
  -  protected MemoryStore logicsheetCache;
  -
  -  /**
  -   * The markup language's namespace uri
  -   */
  -  protected String uri;
  -
  -  /**
  -   * The markup language's namespace prefix
  -   */
  -  protected String prefix;
  -
  -  /** The component manager */
  -  protected ComponentManager manager;
  -
  -  /**
  -   * Set the global component manager.
  -   *
  -   * @param manager The sitemap-specified component manager
  -   */
  -  public void setComponentManager(ComponentManager manager) {
  -    this.manager = manager;
  -  }
  -
  -  /**
  -   * The defualt constructor.
  -   */
  -  public AbstractMarkupLanguage() throws SAXException, IOException {
  -    // Initialize language table
  -    this.languages = new Hashtable();
  -
  -    // Initialize logicsheet cache
  -    this.logicsheetCache = new MemoryStore();
  -  }
  -
  -  /**
  -   * Initialize the (required) markup language namespace definition.
  -   *
  -   * @param params The sitemap-supplied parameters
  -   * @exception Exception Not actually thrown
  -   */
  -  protected void setParameters(Parameters params) throws Exception
  -  {
  -    this.uri = getRequiredParameter(params, "uri");
  -    this.prefix = getRequiredParameter(params, "prefix");
  -  }
  -
  -  /**
  -   * Process additional configuration. Load supported programming language
  -   * definitions
  -   *
  -   * @param conf The language configuration
  -   * @exception ConfigurationException If an error occurs loading logichseets
  -   */
  -  protected void setAdditionalConfiguration(Configuration conf)
  -    throws ConfigurationException
  -  {
  -    try {
  -      Enumeration l = conf.getConfigurations("target-language");
  -      while (l.hasMoreElements()) {
  -        Configuration lc = (Configuration) l.nextElement();
  -
  -        LanguageDescriptor language = new LanguageDescriptor();
  -        language.setName(lc.getAttribute("name"));
  -
  -	      Parameters lcp = Parameters.fromConfiguration(lc);
  -        String logicsheetLocation =
  -	        getRequiredParameter(lcp, "core-logicsheet");
  -
  -        URL logicsheetURL = NetUtils.getURL(logicsheetLocation);
  -        String logicsheetName = logicsheetURL.toExternalForm();
  -        Logicsheet logicsheet = new Logicsheet();
  -        logicsheet.setInputSource(new InputSource(logicsheetURL.openStream()));
  -        CachedURL entry = new CachedURL(logicsheetURL, logicsheet);
  -        this.logicsheetCache.store(logicsheetName, entry);
  -        language.setLogicsheet(logicsheetName);
  -
  -        Enumeration n = lc.getConfigurations("builtin-logicsheet");
  -        while (n.hasMoreElements()) {
  -          Configuration nc = (Configuration) n.nextElement();
  -	        Parameters ncp = Parameters.fromConfiguration(nc);
  -
  -          String namedLogicsheetPrefix = getRequiredParameter(ncp, "prefix");
  -          String namedLogicsheetUri = getRequiredParameter(ncp, "uri");
  -          String namedLogicsheetLocation = getRequiredParameter(ncp, "href");
  -
  -          // FIXME: This is repetitive; add method for both cases
  -          URL namedLogicsheetURL = NetUtils.getURL(namedLogicsheetLocation);
  -          String namedLogicsheetName = namedLogicsheetURL.toExternalForm();
  -          NamedLogicsheet namedLogicsheet = new NamedLogicsheet();
  -          namedLogicsheet.setInputSource(
  -            new InputSource(namedLogicsheetURL.openStream())
  -          );
  -          namedLogicsheet.setPrefix(namedLogicsheetPrefix);
  -          namedLogicsheet.setUri(namedLogicsheetUri);
  -          CachedURL namedEntry =
  -            new CachedURL(namedLogicsheetURL, namedLogicsheet);
  -          this.logicsheetCache.store(namedLogicsheetName, namedEntry);
  -          language.addNamedLogicsheet(
  -            namedLogicsheetPrefix, namedLogicsheetName
  -          );
  -        }
  -
  -        this.languages.put(language.getName(), language);
  -      }
  -    } catch (Exception e) {
  -      throw new ConfigurationException(e.getMessage(), conf);
  -    }
  -  }
  -
  -  /**
  -   * Return the source document's encoding. This can be <code>null</code> for
  -   * the platform's default encoding. The default implementation returns
  -   * <code>null, but derived classes may override it if encoding applies to
  -   * their concrete languages. FIXME: There should be a way to get the
  -   * XML document's encoding as seen by the parser; unfortunately, this
  -   * information is not returned by current DOM or SAX parsers...
  -   *
  -   * @param document The input document
  -   * @return The document-specified encoding
  -   */
  -  public String getEncoding(Document document) {
  -    return null;
  -  }
  -
  -  /**
  -   * Prepare the document for logicsheet processing and code generation. The
  -   * default implementation does nothing, but derived classes should (at least)
  -   * use the passed programming language to quote <code>Strings</code>
  -   *
  -   * @param document The input document
  -   * @param filename The input source filename
  -   * @param language The target programming language
  -   * @return The augmented document
  -   */
  -  protected Document preprocessDocument(
  -    Document document, String filename, ProgrammingLanguage language
  -  )
  -  {
  -    return document;
  -  }
  -
  -  /**
  -   * Returns a list of logicsheets to be applied to this document for source
  -   * code generation.
  -   *
  -   * @param document The input document
  -   * @return An array of logicsheet <i>names</i>
  -   */
  -  protected abstract String[] getLogicsheets(Document document);
  -
  -  /**
  -   * Add a dependency on an external file to the document for inclusion in
  -   * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  -   * to populate a list of <code>File</code>'s tested for change on each
  -   * invocation; this information, in turn, is used by
  -   * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  -   * necessary.
  -   *
  -   * @param PARAM_NAME Param description
  -   * @return the value
  -   * @exception EXCEPTION_NAME If an error occurs
  -   * @see ServerPages <code>AbstractServerPagesGenerator</code>
  -   *      and <code>ServerPagesLoaderImpl</code>
  -   */
  -  protected abstract void addDependency(Document document, String location);
  -
  -  /**
  -   * Generate source code from the input document for the target
  -   * <code>ProgrammingLanguage</code>. After preprocessing the input document,
  -   * this method applies logicsheets in the following order:
  -   * <ul>
  -   *   <li>User-defined logicsheets</li>
  -   *   <li>Namespace-mapped logicsheets</li>
  -   *   <li>Language-specific logicsheet</li>
  -   * </ul>
  -   *
  -   * @param document The input document
  -   * @param filename The input document's original filename
  -   * @param programmingLanguage The target programming language
  -   * @return The generated source code
  -   * @exception Exception If an error occurs during code generation
  -   */
  -  public String generateCode(
  -    Document document, String filename, ProgrammingLanguage programmingLanguage,
  -    EntityResolver resolver
  -  ) throws Exception {
  -    String languageName = programmingLanguage.getName();
  -
  -    LanguageDescriptor language =
  -      (LanguageDescriptor) this.languages.get(languageName);
  -
  -    if (language == null) {
  -      throw new IllegalArgumentException(
  -        "Unsupported programming language: " + languageName
  -      );
  -    }
  -
  -    // Preprocess document as needed
  -    document = this.preprocessDocument(document, filename, programmingLanguage);
  -
  -    // Create code generator
  -    LogicsheetCodeGenerator codeGenerator = new LogicsheetCodeGenerator(); 
  -
  -    // Add user-defined logicsheets
  -    String[] logicsheetNames = this.getLogicsheets(document);
  -    for (int i = 0; i < logicsheetNames.length; i++) {
  -      this.addLogicsheet(codeGenerator, logicsheetNames[i], document, resolver);
  -    }
  -
  -    // Add namespace-mapped logicsheets
  -    Element root = document.getDocumentElement();
  -    NamedNodeMap attrs = root.getAttributes();
  -    int attrCount = attrs.getLength();
  -    for (int i = 0; i < attrCount; i++) {
  -      Attr attr = (Attr) attrs.item(i);
  -      String name = attr.getName();
  -
  -      if (name.startsWith("xmlns:")) {
  -        String prefix = name.substring(6);
  -        String namedLogicsheetName = language.getNamedLogicsheet(prefix);
  -
  -        if (namedLogicsheetName != null) {
  -          this.addLogicsheet(codeGenerator, namedLogicsheetName, document, resolver);
  -        }
  -      }
  -    }
  -
  -    // Add language-specific logicsheet (always last!)
  -    this.addLogicsheet(codeGenerator, language.getLogicsheet(), document, resolver);
  -
  -    return codeGenerator.generateCode(document, filename);
  -  }
  -
  -  /**
  -   * Add a logicsheet to the code generator.
  -   *
  -   * @param codeGenerator The code generator
  -   * @param logicsheetLocation Location of the logicsheet to be added
  -   * @param document The input document
  -   * @exception MalformedURLException If location is invalid
  -   * @exception IOException IO Error
  -   * @exception SAXException Logicsheet parse error
  -   */
  -  protected void addLogicsheet(
  -    LogicsheetCodeGenerator codeGenerator,
  -    String logicsheetLocation,
  -    Document document,
  -    EntityResolver entityResolver
  -  ) throws MalformedURLException, IOException, SAXException
  -  {
  -    String systemId = null;
  -    InputSource inputSource = null;
  -
  -    if (logicsheetLocation.indexOf(":/") < 0) { // Relative to Cocoon root
  -      inputSource = entityResolver.resolveEntity(null, logicsheetLocation);
  -      systemId = inputSource.getSystemId();
  -    } else { // Fully resolved URL
  -      systemId = logicsheetLocation;
  -      inputSource = new InputSource(systemId);
  -    }
  -
  -    URL url = new URL(systemId);
  -    String logicsheetName = url.toExternalForm();
  -    CachedURL entry = (CachedURL) this.logicsheetCache.get(logicsheetName);
  -
  -    Logicsheet logicsheet = null;
  -
  -    if (entry == null) {
  -      logicsheet = new Logicsheet();
  -      logicsheet.setInputSource(inputSource);
  -      entry = new CachedURL(url, logicsheet);
  -      this.logicsheetCache.store(logicsheetName, entry);
  -    }
  -
  -    logicsheet = entry.getLogicsheet();
  -
  -    if (entry.hasChanged()) {
  -      logicsheet.setInputSource(inputSource);
  -    }
  -
  -    if (entry.isFile()) {
  -      this.addDependency(document, IOUtils.getFullFilename(entry.getFile()));
  -    }
  -
  -    codeGenerator.addLogicsheet(logicsheet);
  -  }
  -
  -  // Inner classes
  -
  -  /**
  -   * This class holds transient information about a target programming
  -   * language.
  -   *
  -   */
  -  protected class LanguageDescriptor {
  -    /**
  -     * The progamming language name
  -     */
  -    protected String name;
  -
  -    /**
  -     * The progamming language core logicsheet
  -     */
  -    protected String logicsheet;
  -
  -    /**
  -     * The list of built-in logicsheets defined for this target language
  -     */
  -    protected Hashtable namedLogicsheets;
  -
  -    /**
  -     * The default constructor
  -     */
  -    protected LanguageDescriptor() {
  -      this.namedLogicsheets = new Hashtable();
  -    }
  -
  -    /**
  -     * Set the programming language's name
  -     *
  -     * @param name The programming language's name
  -     */
  -    protected void setName(String name) {
  -      this.name = name;
  -    }
  -
  -    /**
  -     * Return the programming language's name
  -     *
  -     * @return The programming language's name
  -     */
  -    protected String getName() {
  -      return this.name;
  -    }
  -
  -    /**
  -     * Set the programming language's core logichseet location
  -     *
  -     * @param logicsheet The programming language's core logichseet location
  -     */
  -    protected void setLogicsheet(String logicsheet) {
  -      this.logicsheet = logicsheet;
  -    }
  -
  -    /**
  -     * Return the programming language's core logichseet location
  -     *
  -     * @return The programming language's core logichseet location
  -     */
  -    protected String getLogicsheet() {
  -      return this.logicsheet;
  -    }
  -
  -    /**
  -     * Add a namespace-mapped logicsheet to this language
  -     *
  -     * @param prefix The logichseet's namespace prefix
  -     * @param uri The logichseet's namespace uri
  -     * @param namedLogicsheet The logichseet's location
  -     */
  -    protected void addNamedLogicsheet(String prefix, String namedLogicsheet) {
  -      this.namedLogicsheets.put(
  -        prefix,
  -        namedLogicsheet
  -      );
  -    }
  -
  -    /**
  -     * Return a namespace-mapped logicsheet given its name
  -     *
  -     * @return The namespace-mapped logicsheet
  -     */
  -    protected String getNamedLogicsheet(String prefix) {
  -      return (String) this.namedLogicsheets.get(prefix);
  -    }
  -  }
  -
  -  /**
  -   * This class holds a cached URL entry associated with a logicsheet
  -   *
  -   */
  -  protected class CachedURL {
  -    /**
  -     * The logicsheet URL
  -     */
  -    protected URL url;
  -    /**
  -     * The logicsheet's <code>File</code> if it's actually a file.
  -     * This is used to provide last modification information not
  -     * otherwise available for URL's in Java :-(
  -     */
  -    protected File file;
  -    /**
  -     * The cached logicsheet 
  -     */
  -    protected Logicsheet logicsheet;
  -    /**
  -     * The las time this logicsheet was changed/loaded
  -     */
  -    protected long lastModified;
  -
  -    /**
  -     * The constructor.
  -     */
  -    protected CachedURL(URL url, Logicsheet logicsheet) throws IOException {
  -      this.url = url;
  -      this.logicsheet = logicsheet;
  -
  -      if (this.isFile()) {
  -        this.file = new File(url.getFile());
  -      }
  -
  -      this.lastModified = (new Date()).getTime();
  -    }
  -
  -    /**
  -     * Return this entry's URL
  -     *
  -     * @return The cached logicsheet's URL
  -     */
  -    protected URL getURL() {
  -      return this.url;
  -    }
  -
  -    protected boolean isFile() {
  -      return this.url.getProtocol().equals("file");
  -    }
  -
  -    /**
  -     * Return this entry's <code>File</code>
  -     *
  -     * @return The cached logicsheet's <code>File</code>
  -     */
  -    protected File getFile() {
  -      return this.file;
  -    }
  -
  -    /**
  -     * Return this entry's cached logicsheet
  -     *
  -     * @return The cached logicsheet
  -     */
  -    protected Logicsheet getLogicsheet() {
  -      return this.logicsheet;
  -    }
  -
  -    /**
  -     * Assert whether this entry's logicsheet should be reloaded
  -     *
  -     * @return Whether the cached logicsheet has changed
  -     */
  -    protected boolean hasChanged() {
  -      if (this.file == null) {
  -        return false;
  -      }
  +    /**
  +    * The supported language table
  +    */
  +    protected Hashtable languages;
  +
  +    /**
  +    * The in-memory code-generation logicsheet cache
  +    */
  +    protected MemoryStore logicsheetCache;
  +
  +    /**
  +    * The markup language's namespace uri
  +    */
  +    protected String uri;
  +
  +    /**
  +    * The markup language's namespace prefix
  +    */
  +    protected String prefix;
  +
  +    /** The component manager */
  +    protected ComponentManager manager;
  +
  +    /**
  +    * Set the global component manager.
  +    *
  +    * @param manager The sitemap-specified component manager
  +    */
  +    public void setComponentManager(ComponentManager manager) {
  +        this.manager = manager;
  +    }
  +
  +    /**
  +    * The default constructor.
  +    */
  +    public AbstractMarkupLanguage() throws SAXException, IOException {
  +        // Initialize language table
  +        this.languages = new Hashtable();
  +
  +        // Initialize logicsheet cache
  +        this.logicsheetCache = new MemoryStore();
  +    }
  +
  +    /**
  +    * Initialize the (required) markup language namespace definition.
  +    *
  +    * @param params The sitemap-supplied parameters
  +    * @exception Exception Not actually thrown
  +    */
  +    protected void setParameters(Parameters params) throws Exception
  +    {
  +        this.uri = getRequiredParameter(params, "uri");
  +        this.prefix = getRequiredParameter(params, "prefix");
  +    }
  +
  +    /**
  +    * Process additional configuration. Load supported programming language
  +    * definitions
  +    *
  +    * @param conf The language configuration
  +    * @exception ConfigurationException If an error occurs loading logichseets
  +    */
  +    protected void setAdditionalConfiguration(Configuration conf)
  +        throws ConfigurationException
  +    {
  +        try {
  +            Enumeration l = conf.getConfigurations("target-language");
  +            while (l.hasMoreElements()) {
  +                Configuration lc = (Configuration) l.nextElement();
  +
  +                LanguageDescriptor language = new LanguageDescriptor();
  +                language.setName(lc.getAttribute("name"));
  +
  +                Parameters lcp = Parameters.fromConfiguration(lc);
  +                String logicsheetLocation =
  +                	        getRequiredParameter(lcp, "core-logicsheet");
  +
  +                URL logicsheetURL = NetUtils.getURL(logicsheetLocation);
  +                String logicsheetName = logicsheetURL.toExternalForm();
  +                // FIXME (SSA) should be abstracted
  +                Logicsheet logicsheet = new Logicsheet();
  +                logicsheet.setInputSource(new InputSource(logicsheetURL.toString()));
  +                CachedURL entry = new CachedURL(logicsheetURL, logicsheet);
  +                this.logicsheetCache.store(logicsheetName, entry);
  +                language.setLogicsheet(logicsheetName);
  +
  +                Enumeration n = lc.getConfigurations("builtin-logicsheet");
  +                while (n.hasMoreElements()) {
  +                    Configuration nc = (Configuration) n.nextElement();
  +                    Parameters ncp = Parameters.fromConfiguration(nc);
  +
  +                    String namedLogicsheetPrefix = getRequiredParameter(ncp, "prefix");
  +                    String namedLogicsheetUri = getRequiredParameter(ncp, "uri");
  +                    String namedLogicsheetLocation = getRequiredParameter(ncp, "href");
  +
  +                    // FIXME: This is repetitive; add method for both cases
  +                    URL namedLogicsheetURL = NetUtils.getURL(namedLogicsheetLocation);
  +                    String namedLogicsheetName = namedLogicsheetURL.toExternalForm();
  +                    NamedLogicsheet namedLogicsheet = new NamedLogicsheet();
  +                    namedLogicsheet.setInputSource(
  +                        new InputSource(namedLogicsheetURL.toString())
  +                    );
  +                    namedLogicsheet.setPrefix(namedLogicsheetPrefix);
  +                    namedLogicsheet.setUri(namedLogicsheetUri);
  +                    CachedURL namedEntry =
  +                    new CachedURL(namedLogicsheetURL, namedLogicsheet);
  +                    this.logicsheetCache.store(namedLogicsheetName, namedEntry);
  +                    language.addNamedLogicsheet(
  +                        namedLogicsheetPrefix, namedLogicsheetName
  +                    );
  +                }
  +
  +            this.languages.put(language.getName(), language);
  +            }
  +        } catch (Exception e) {
  +            // FIXME (SSA) Better error handling
  +            e.printStackTrace();
  +            throw new ConfigurationException(e.getMessage(), conf);
  +        }
  +    }
  +
  +    /**
  +    * Return the source document's encoding. This can be <code>null</code> for
  +    * the platform's default encoding. The default implementation returns
  +    * <code>null, but derived classes may override it if encoding applies to
  +    * their concrete languages. FIXME: There should be a way to get the
  +    * XML document's encoding as seen by the parser; unfortunately, this
  +    * information is not returned by current DOM or SAX parsers...
  +    *
  +    * @return The document-specified encoding
  +    */
  +    public String getEncoding() {
  +        return null;
  +    }
  +
  +    /**
  +    * Returns a filter that chains on the fly the requested transformers for source
  +    * code generation. This method scans the input SAX events for built-in logicsheet
  +    * declared as namespace attribute on the root element.
  +    *
  +    * Derived class should overide this method and the public inner class in
  +    * order to add more specif action and to build a more specific transformer
  +    * chain.
  +    *
  +    * @param logicsheetMarkupGenerator the logicsheet markup generator
  +    * @param resolver the entity resolver
  +    * @return XMLFilter the filter that build on the fly the transformer chain
  +    */
  +    protected TransformerChainBuilderFilter getTranformerChainBuilder (
  +                                LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +                                EntityResolver resolver) {
  +        return new TransformerChainBuilderFilter(logicsheetMarkupGenerator, resolver);
  +    }
  +
  +    /**
  +    * Prepare the input source for logicsheet processing and code generation
  +    * with a preprocess filter.
  +    * The return <code>XMLFilter</code> object is the first filter on the
  +    * transformer chain.
  +    *
  +    * The default implementation does nothing by returning a identity filter, but
  +    * derived classes should (at least) use the passed programming language to
  +    * quote <code>Strings</code>
  +    *
  +    * @param filename The source filename
  +    * @param language The target programming language
  +    * @return The preprocess filter
  +    */
  +    protected XMLFilter getPreprocessFilter(
  +        String filename, ProgrammingLanguage language
  +    )
  +    {
  +        return new XMLFilterImpl();
  +    }
  +
  +    /**
  +    * Add a dependency on an external file to the document for inclusion in
  +    * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  +    * to populate a list of <code>File</code>'s tested for change on each
  +    * invocation; this information, in turn, is used by
  +    * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  +    * necessary.
  +    *
  +    * @param PARAM_NAME Param description
  +    * @return the value
  +    * @exception EXCEPTION_NAME If an error occurs
  +    * @see ServerPages <code>AbstractServerPagesGenerator</code>
  +    *      and <code>ServerPagesLoaderImpl</code>
  +    */
  +    protected abstract void addDependency(String location);
  +
  +    /**
  +    * Generate source code from the input document for the target
  +    * <code>ProgrammingLanguage</code>. After preprocessing the input document,
  +    * this method applies logicsheets in the following order:
  +    * <ul>
  +    *   <li>User-defined logicsheets</li>
  +    *   <li>Namespace-mapped logicsheets</li>
  +    *   <li>Language-specific logicsheet</li>
  +    * </ul>
  +    *
  +    * @param input The input source
  +    * @param filename The input document's original filename
  +    * @param programmingLanguage The target programming language
  +    * @return The generated source code
  +    * @exception Exception If an error occurs during code generation
  +    */
  +    public String generateCode(
  +        InputSource input, String filename, ProgrammingLanguage programmingLanguage,
  +        EntityResolver resolver
  +    ) throws Exception {
  +        String languageName = programmingLanguage.getName();
  +        LanguageDescriptor language =
  +            (LanguageDescriptor) this.languages.get(languageName);
  +
  +        if (language == null) {
  +            throw new IllegalArgumentException(
  +                "Unsupported programming language: " + languageName
  +            );
  +        }
  +
  +        // Create a XMLReader
  +        XMLReader reader = XMLReaderFactory.createXMLReader();
  +        reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
  +
  +        // Get the needed preprocess filter
  +        XMLFilter preprocessFilter = this.getPreprocessFilter(filename, programmingLanguage);
  +        preprocessFilter.setParent(reader);
  +
  +        // Create code generator
  +        LogicsheetCodeGenerator codeGenerator = new LogicsheetCodeGenerator();
  +
  +        // set the transformer chain builder filter
  +        TransformerChainBuilderFilter tranBuilder = getTranformerChainBuilder(codeGenerator, resolver);
  +        tranBuilder.setLanguageDescriptor(language);
  +        tranBuilder.setParent(preprocessFilter);
  +
  +        return codeGenerator.generateCode(tranBuilder, input, filename);
  +    }
  +
  +    /**
  +    * Add a logicsheet to the code generator.
  +    *
  +    * @param codeGenerator The code generator
  +    * @param logicsheetLocation Location of the logicsheet to be added
  +    * @param document The input document
  +    * @exception MalformedURLException If location is invalid
  +    * @exception IOException IO Error
  +    * @exception SAXException Logicsheet parse error
  +    */
  +    protected void addLogicsheet(
  +        LogicsheetCodeGenerator codeGenerator,
  +        String logicsheetLocation,
  +        EntityResolver entityResolver
  +    ) throws MalformedURLException, IOException, SAXException
  +    {
  +        String systemId = null;
  +        InputSource inputSource = null;
  +
  +        if (logicsheetLocation.indexOf(":/") < 0) { // Relative to Cocoon root
  +            inputSource = entityResolver.resolveEntity(null, logicsheetLocation);
  +            systemId = inputSource.getSystemId();
  +        } else { // Fully resolved URL
  +            systemId = logicsheetLocation;
  +            inputSource = new InputSource(systemId);
  +        }
  +
  +        URL url = new URL(systemId);
  +        String logicsheetName = url.toExternalForm();
  +
  +        CachedURL entry = (CachedURL) this.logicsheetCache.get(logicsheetName);
  +
  +        Logicsheet logicsheet = null;
  +
  +        if (entry == null) {
  +            logicsheet = new Logicsheet();
  +            logicsheet.setInputSource(inputSource);
  +            entry = new CachedURL(url, logicsheet);
  +            this.logicsheetCache.store(logicsheetName, entry);
  +        }
  +
  +        logicsheet = entry.getLogicsheet();
  +
  +        if (entry.hasChanged()) {
  +            logicsheet.setInputSource(inputSource);
  +        }
  +
  +        if (entry.isFile()) {
  +            this.addDependency(IOUtils.getFullFilename(entry.getFile()));
  +        }
  +
  +        codeGenerator.addLogicsheet(logicsheet);
  +    }
  +
  +//
  +// Inner classes
  +//
  +
  +    /**
  +    * This class holds transient information about a target programming
  +    * language.
  +    *
  +    */
  +    protected class LanguageDescriptor {
  +        /**
  +         * The progamming language name
  +         */
  +        protected String name;
  +
  +        /**
  +         * The progamming language core logicsheet
  +         */
  +        protected String logicsheet;
  +
  +        /**
  +         * The list of built-in logicsheets defined for this target language
  +         */
  +        protected Hashtable namedLogicsheets;
  +
  +        /**
  +         * The default constructor
  +         */
  +        protected LanguageDescriptor() {
  +            this.namedLogicsheets = new Hashtable();
  +        }
  +
  +        /**
  +         * Set the programming language's name
  +         *
  +         * @param name The programming language's name
  +         */
  +        protected void setName(String name) {
  +            this.name = name;
  +        }
  +
  +        /**
  +        * Return the programming language's name
  +        *
  +        * @return The programming language's name
  +        */
  +        protected String getName() {
  +            return this.name;
  +        }
  +
  +        /**
  +         * Set the programming language's core logichseet location
  +         *
  +         * @param logicsheet The programming language's core logichseet location
  +         */
  +        protected void setLogicsheet(String logicsheet) {
  +            this.logicsheet = logicsheet;
  +        }
  +
  +        /**
  +         * Return the programming language's core logichseet location
  +         *
  +         * @return The programming language's core logichseet location
  +         */
  +        protected String getLogicsheet() {
  +            return this.logicsheet;
  +        }
  +
  +        /**
  +         * Add a namespace-mapped logicsheet to this language
  +         *
  +         * @param prefix The logichseet's namespace prefix
  +         * @param uri The logichseet's namespace uri
  +         * @param namedLogicsheet The logichseet's location
  +         */
  +        protected void addNamedLogicsheet(String prefix, String namedLogicsheet) {
  +            this.namedLogicsheets.put(
  +                prefix,
  +                namedLogicsheet
  +            );
  +        }
   
  -      return this.lastModified < this.file.lastModified();
  +        /**
  +         * Return a namespace-mapped logicsheet given its name
  +         *
  +         * @return The namespace-mapped logicsheet
  +         */
  +        protected String getNamedLogicsheet(String prefix) {
  +            return (String) this.namedLogicsheets.get(prefix);
  +        }
  +    }
  +
  +    /**
  +    * This class holds a cached URL entry associated with a logicsheet
  +    *
  +    */
  +    protected class CachedURL {
  +        /**
  +         * The logicsheet URL
  +         */
  +        protected URL url;
  +        /**
  +         * The logicsheet's <code>File</code> if it's actually a file.
  +         * This is used to provide last modification information not
  +         * otherwise available for URL's in Java :-(
  +         */
  +        protected File file;
  +        /**
  +         * The cached logicsheet
  +         */
  +        protected Logicsheet logicsheet;
  +        /**
  +         * The las time this logicsheet was changed/loaded
  +         */
  +        protected long lastModified;
  +
  +        /**
  +         * The constructor.
  +         */
  +        protected CachedURL(URL url, Logicsheet logicsheet) throws IOException {
  +            this.url = url;
  +            this.logicsheet = logicsheet;
  +
  +            if (this.isFile()) {
  +                this.file = new File(url.getFile());
  +            }
  +
  +            this.lastModified = (new Date()).getTime();
  +        }
  +
  +        /**
  +         * Return this entry's URL
  +         *
  +         * @return The cached logicsheet's URL
  +         */
  +        protected URL getURL() {
  +            return this.url;
  +        }
  +
  +        protected boolean isFile() {
  +            return this.url.getProtocol().equals("file");
  +        }
  +
  +        /**
  +         * Return this entry's <code>File</code>
  +         *
  +         * @return The cached logicsheet's <code>File</code>
  +         */
  +        protected File getFile() {
  +            return this.file;
  +        }
  +
  +        /**
  +         * Return this entry's cached logicsheet
  +         *
  +         * @return The cached logicsheet
  +         */
  +        protected Logicsheet getLogicsheet() {
  +            return this.logicsheet;
  +        }
  +
  +        /**
  +         * Assert whether this entry's logicsheet should be reloaded
  +         *
  +         * @return Whether the cached logicsheet has changed
  +         */
  +        protected boolean hasChanged() {
  +            if (this.file == null) {
  +                return false;
  +            }
  +
  +            return this.lastModified < this.file.lastModified();
  +        }
  +    }
  +
  +    /**
  +    * a XMLFilter that build the chain of transformers on the fly.
  +    * Each time a stylesheet is found, a call to the code generator is done
  +    * to add the new transformer at the end of the current transformer chain.
  +    *
  +    */
  +    public class TransformerChainBuilderFilter extends XMLFilterImpl {
  +
  +        /**
  +         * The markup generator
  +         */
  +        protected LogicsheetCodeGenerator logicsheetMarkupGenerator;
  +
  +        /**
  +         * the language description
  +         */
  +        protected LanguageDescriptor language;
  +
  +        /**
  +         * the entity resolver
  +         */
  +        protected EntityResolver resolver;
  +
  +        private boolean isRootElem;
  +
  +        private List startPrefixes;
  +
  +        /**
  +        * the constructor depends on the code generator, and the entity resolver
  +        *
  +        * @param logicsheetMarkupGenerator The code generator
  +        * @param resolver
  +        */
  +        protected TransformerChainBuilderFilter (
  +            LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +                EntityResolver resolver
  +        ) {
  +            this.logicsheetMarkupGenerator = logicsheetMarkupGenerator;
  +            this.resolver = resolver;
  +        }
  +
  +        /**
  +        * This method should be called prior to receiving any SAX event.
  +        * Indeed the language information is needed to get the core stylesheet.
  +        *
  +        * @language the language in used
  +        */
  +        protected void setLanguageDescriptor(LanguageDescriptor language) {
  +            this.language = language;
  +        }
  +
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startDocument () throws SAXException {
  +            isRootElem=true;
  +            startPrefixes = new ArrayList();
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startPrefixMapping(String prefix, String uri) throws SAXException {
  +            if(!isRootElem) {
  +                super.startPrefixMapping(prefix, uri);
  +            } else {
  +                // cache the prefix mapping
  +                String[] prefixArray = new String [2];
  +                prefixArray[0]= prefix;
  +                prefixArray[1]= uri;
  +                this.startPrefixes.add(prefixArray);
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startElement (
  +            String namespaceURI, String localName,
  +        	String qName, Attributes atts
  +         ) throws SAXException {
  +            if(isRootElem) {
  +                isRootElem=false;
  +                try {
  +                    // Add namespace-mapped logicsheets
  +                    int prefixesCount = this.startPrefixes.size();
  +                    for (int i = 0; i < prefixesCount; i++) {
  +                        String[] prefixNamingArray = (String[]) this.startPrefixes.get(i);
  +                        String namedLogicsheetName =
  +                            this.language.getNamedLogicsheet(prefixNamingArray[0]);
  +                        if (namedLogicsheetName != null) {
  +                            AbstractMarkupLanguage.this.addLogicsheet(
  +                                this.logicsheetMarkupGenerator, namedLogicsheetName, resolver
  +                            );
  +                        }
  +                    }
  +                    // Add the language stylesheet (Always the last one)
  +                    AbstractMarkupLanguage.this.addLogicsheet(
  +                        this.logicsheetMarkupGenerator, this.language.getLogicsheet(), resolver
  +                    );
  +                } catch (IOException ioe) {
  +                    throw new SAXException (ioe);
  +                }
  +                // All stylesheet have been configured and correctly setup.
  +                // Starts firing SAX events, especially the startDocument event,
  +                // and the cached prefixNaming.
  +                super.startDocument();
  +                int prefixesCount = this.startPrefixes.size();
  +                for (int i = 0; i < prefixesCount; i++) {
  +                    String[] prefixNamingArray = (String[]) this.startPrefixes.get(i);
  +                    super.startPrefixMapping(prefixNamingArray[0], prefixNamingArray[1]);
  +                }
  +            }
  +            // Call super method
  +            super.startElement(namespaceURI, localName, qName, atts);
  +        }
       }
  -  }
   }
  
  
  
  1.1.2.4   +352 -76   xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/Logicsheet.java
  
  Index: Logicsheet.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/Logicsheet.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- Logicsheet.java	2000/07/29 18:30:27	1.1.2.3
  +++ Logicsheet.java	2000/10/12 16:43:15	1.1.2.4
  @@ -7,95 +7,371 @@
    *****************************************************************************/
   package org.apache.cocoon.components.language.markup;
   
  -import java.net.URL;
  -import java.util.Vector;
  -
  -import org.w3c.dom.Attr;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.NamedNodeMap;
  +import java.io.IOException;
  +import java.io.StringWriter;
  +import java.io.PrintWriter;
  +import java.util.Map;
  +import java.util.HashMap;
  +import java.util.Set;
  +import java.util.HashMap;
  +import java.util.Iterator;
   
   import org.xml.sax.InputSource;
  -
  -import org.apache.cocoon.util.DOMUtils;
  -
  -import java.io.IOException;
  +import org.xml.sax.helpers.XMLFilterImpl;
   import org.xml.sax.SAXException;
  -import java.net.MalformedURLException;
  +import org.xml.sax.SAXNotSupportedException;
  +import org.xml.sax.SAXNotRecognizedException;
  +import org.xml.sax.XMLFilter;
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.EntityResolver;
  +import org.xml.sax.DTDHandler;
  +import org.xml.sax.ContentHandler;
  +import org.xml.sax.ErrorHandler;
  +import org.xml.sax.helpers.AttributesImpl;
  +import org.xml.sax.helpers.XMLReaderFactory;
  +
  +
  +import trax.Templates;
  +import trax.Processor;
  +import trax.Transformer;
  +import trax.TemplatesBuilder;
   
   /**
    * A code-generation logicsheet. This class is actually a wrapper for
  - * a "standard" XSLT stylesheet though this will change shortly: a new markup
  - * language will be used for logicsheet authoring; logicsheets written in this
  - * language will be transformed into an equivalent XSLT stylesheet anyway...
  + * a "standard" XSLT stylesheet stored as <code>trax.Templates</code> object.
  + * Though this will change shortly: a new markup language will be used
  + * for logicsheet authoring; logicsheets written in this language will be
  + * transformed into an equivalent XSLT stylesheet anyway...
    * This class should probably be based on an interface...
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/07/29 18:30:27 $
  + * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/10/12 16:43:15 $
    */
   public class Logicsheet {
  -  /**
  -   * The wrapped XSLT stylesheet
  -   */
  -  protected Document stylesheet;
  -
  -  /**
  -   * The list of preserved namespaces
  -   */
  -  protected Vector namespaces;
  -  /**
  -   * A time-saving trick: this is actually the namespace's vector size()
  -   */
  -  protected int namespaceCount;
  -
  -  /**
  -   * The constructor. This method scans the logicsheet collecting namespaces to
  -   * be preserved on output; this ensures that no namespaces will be dropped
  -   * from the original document
  -   *
  -   * @param inputSource The stylesheet's input source
  -   * @exception IOException IOError processing input source
  -   * @exception SAXException Input source parse error
  -   */
  -  public void setInputSource(InputSource inputSource)
  -    throws SAXException, IOException
  -  {
  -    this.stylesheet = DOMUtils.DOMParse(inputSource);
  -    this.namespaces = DOMUtils.namespaces(this.stylesheet.getDocumentElement());
  -    this.namespaceCount = this.namespaces.size();
  -  }
  -
  -  /**
  -   * Apply this logicsheet to an input document. This method does additional
  -   * namesapace preserving as stylsheet processing may drop namespaces required
  -   * by further code-generation steps
  -   *
  -   * @param input Param The input document
  -   * @return The transformed document
  -   * @exception SAXException If a stylesheet processing error occurs
  -   */
  -  public Document apply(Document input) throws SAXException {
  -    // Save original namespaces
  -    Vector inputNamespaces = DOMUtils.namespaces(input.getDocumentElement());
  -    int inputCount = inputNamespaces.size();
  -
  -    // Transform input document
  -    Document output = DOMUtils.transformDocument(input, this.stylesheet);
  -
  -    // Restore original namespaces
  -    Element root = output.getDocumentElement();
  -
  -    for (int i = 0; i < inputCount; i++) {
  -      String[] pair = (String[]) inputNamespaces.elementAt(i);
  -      root.setAttribute(pair[0], pair[1]);
  +    /**
  +    * The trax templates
  +    */
  +    protected Templates templates;
  +
  +    /**
  +    * the template namespace's list
  +    */
  +    protected Map namespaces;
  +
  +
  +    /**
  +    * The constructor. It does preserve the namespace from the stylesheet.
  +    *
  +    * @param inputSource The stylesheet's input source
  +    * @exception IOException IOError processing input source
  +    * @exception SAXException Input source parse error
  +    */
  +    public void setInputSource(InputSource inputSource)
  +        throws SAXException, IOException
  +    {
  +        Processor processor = Processor.newInstance("xslt");
  +        // Create a XMLReader with the namespace-prefixes feature
  +        XMLReader reader = XMLReaderFactory.createXMLReader();
  +        reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
  +        namespaces = new HashMap();
  +        // Create a XMLFilter that save the namespace hold in the stylesheet
  +        XMLFilter saveNSFilter = new SaveNamespaceFilter(namespaces);
  +        saveNSFilter.setParent(reader);
  +        // Create the TemplatesBuilder and register as ContentHandler
  +        TemplatesBuilder temBuilder = processor.getTemplatesBuilder();
  +        saveNSFilter.setContentHandler(temBuilder);
  +        // Parse and get the templates
  +        reader.parse(inputSource);
  +        this.templates = temBuilder.getTemplates();
       }
   
  -    // Restore stylesheet namespaces
  -    for (int i = 0; i < this.namespaceCount; i++) {
  -      String[] pair = (String[]) this.namespaces.elementAt(i);
  -      root.setAttribute(pair[0], pair[1]);
  +    /**
  +    * Get the XMLFilter that performs the stylesheet transformation.
  +    * The XMLFilter might be an aggregation of XMLFilter that does additional
  +    * namespace preserving as stylesheet processing may drop namespace required
  +    * by further code-generation steps.
  +    *
  +    * @return The XMLFilter for the associated stylesheet.
  +    */
  +    public XMLFilter getXMLFilter() {
  +        XMLFilter transformer = templates.newTransformer();
  +
  +        // The collection that hold the original namespace's declarations
  +        Map originalNamespaces = new HashMap();
  +
  +        // 'Wraps' the transformer with two filters that do the the namespace preserving.
  +        XMLFilter saveNSFilter = new SaveNamespaceFilter(originalNamespaces);
  +        XMLFilter restoreNSFilter = new RestoreNamepaceFilter(this.namespaces, originalNamespaces);
  +
  +        // constructs and returns an aggregate filter.
  +        return new AggregateFilter(saveNSFilter, transformer, restoreNSFilter);
  +
       }
   
  -    return output;
  -  }
  +    /**
  +     * The aggregator filter aggregate 3 filters as if there were one filter.
  +     * This allows us to work with one filter, whereas it internally manage the
  +     * SaveNamespaceFilter as prefilter, a Transformer as a mainfilter, and a
  +     * RestoreNamepaceFilter as a postfilter.
  +     */
  +    protected class AggregateFilter implements XMLFilter {
  +
  +        /**
  +         * the preFilter, usually an instance of SaveNamespaceFilter
  +         */
  +        protected XMLFilter preFilter;
  +
  +        /**
  +         * the mainFilter, usually an instance of Transformer
  +         */
  +        protected XMLFilter mainFilter;
  +
  +        /**
  +         * the postFilter, usually an instance of RestoreNamepaceFilter
  +         */
  +        protected XMLFilter postFilter;
  +
  +        private XMLReader parent;
  +
  +        /**
  +         * The constructor chaina the prefilter, the mainfilter and the
  +         * postfilter in the respective order.
  +         */
  +        public AggregateFilter (XMLFilter preFilter, XMLFilter mainFilter, XMLFilter postFilter) {
  +            this.preFilter = preFilter;
  +            this.mainFilter = mainFilter;
  +            this.postFilter = postFilter;
  +        }
  +
  +        //
  +        // Implements XMLFilter interface
  +        //
  +        public void setParent (XMLReader parent) {
  +        	this.parent = parent;
  +            preFilter.setParent(parent);
  +            mainFilter.setParent(preFilter);
  +            postFilter.setParent(mainFilter);
  +        }
  +
  +        public XMLReader getParent () {
  +	        return parent;
  +        }
  +
  +        //
  +        // Implements XMLReader interface
  +        //
  +        public boolean getFeature (String name)
  +            throws SAXNotRecognizedException, SAXNotSupportedException {
  +            return parent.getFeature(name);
  +        }
  +
  +        public void setFeature (String name, boolean value)
  +            throws SAXNotRecognizedException, SAXNotSupportedException {
  +            parent.setFeature(name, value);
  +        }
  +
  +        public Object getProperty (String name)
  +            throws SAXNotRecognizedException, SAXNotSupportedException {
  +            return parent.getProperty(name);
  +        }
  +
  +        public void setProperty (String name, Object value)
  +            throws SAXNotRecognizedException, SAXNotSupportedException {
  +            parent.setProperty(name, value);
  +        }
  +
  +        public void setEntityResolver (EntityResolver resolver) { }
  +
  +        public EntityResolver getEntityResolver () { return null; }
  +
  +        public void setDTDHandler (DTDHandler handler) { }
  +
  +        public DTDHandler getDTDHandler () { return null; }
  +
  +        public void setContentHandler (ContentHandler handler) {
  +            this.postFilter.setContentHandler(handler);
  +        }
  +
  +        public ContentHandler getContentHandler () {
  +            return this.postFilter.getContentHandler();
  +        }
  +
  +        public void setErrorHandler (ErrorHandler handler) { }
  +
  +        public ErrorHandler getErrorHandler () { return null; }
  +
  +        public void parse (InputSource input)
  +            throws SAXException, IOException  {
  +            this.getParent().parse(input);
  +        }
  +
  +        public void parse (String systemId)
  +            throws SAXException, IOException {
  +            this.parse(new InputSource(systemId));
  +        }
  +
  +    }
  +
  +    /**
  +     * This filter listen for source SAX events, and register the declared
  +     * namespaces into a <code>Map</code> object.
  +     *
  +     */
  +    protected class SaveNamespaceFilter extends XMLFilterImpl {
  +
  +        private boolean isRootElem;
  +
  +        private Map originalNamepaces;
  +
  +        /**
  +         * The contructor needs an initialized <code>Map</code> object where it
  +         * can store the found namespace declarations.
  +         * @param originalNamepaces a initialized <code>Map</code> instance.
  +         */
  +        public SaveNamespaceFilter(Map originalNamepaces) {
  +            this.originalNamepaces = originalNamepaces;
  +        }
  +
  +        /**
  +         * @param reader the parent reader
  +         * @see XMLFilter
  +         */
  +        public void setParent(XMLReader reader) {
  +            super.setParent(reader);
  +            reader.setContentHandler(this);
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startDocument () throws SAXException {
  +            isRootElem=true;
  +            super.startDocument();
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startPrefixMapping(String prefix, String uri) throws SAXException {
  +            originalNamepaces.put(prefix, uri);
  +            super.startPrefixMapping(prefix, uri);
  +        }
  +
  +        public void startElement (String namespaceURI, String localName,
  +        			      String qName, Attributes atts) throws SAXException {
  +            super.startElement(namespaceURI, localName, qName, atts);
  +        }
  +
  +    }
  +
  +    /**
  +     * This filter listen for SAX events generated by the transformer filter,
  +     * and store back the registered namespaces to the output SAX stream.
  +     *
  +     */
  +    protected class RestoreNamepaceFilter extends XMLFilterImpl {
  +
  +        private boolean isRootElem;
  +
  +        // FIXME (SSA) Xalan2 workaround, should be removed
  +        private boolean hasStarted;
  +
  +        private Map originalNamespaces;
  +
  +        /**
  +         * Contructor needs a <code>Map</code> object where the stylesheet namespace
  +         * have been stored, plus another <code>Map</code> object where the original
  +         * namespaces from input document have been stored.
  +         */
  +        public RestoreNamepaceFilter(Map stylesheetNamespaces, Map originalNamespaces) {
  +            this.originalNamespaces = originalNamespaces;
  +            this.originalNamespaces.putAll(stylesheetNamespaces);
  +        }
  +
  +        /**
  +         * @see XMLFilter
  +         */
  +        public void setParent(XMLReader reader) {
  +            super.setParent(reader);
  +            reader.setContentHandler(this);
  +        }
  +
  +        public void startDocument () throws SAXException {
  +            super.startDocument();
  +            isRootElem=true;
  +            // FIXME (SSA) Xalan2 workaround, should be removed
  +            hasStarted= true;
  +        }
  +
  +        public void endDocument () throws SAXException {
  +            // endMappingPrefix for orginal namespace
  +            // FIXME (SSA) Xalan2j workaround, should be removed
  +            Set prefixes = originalNamespaces.keySet();
  +            Object[] keys = prefixes.toArray();
  +            for (int i=(keys.length-1); i>=0; i--) {
  +                super.endPrefixMapping((String) keys[i]);
  +            }
  +            // FIXME (SSA) Xalan2j workaround, should be replaced
  +    //      Iterator iter = prefixes.iterator();
  +    //      String prefix;
  +    //      while(iter.hasNext()) {
  +    //          prefix = (String) iter.next();
  +    //          super.endPrefixMapping(prefix);
  +    //      }
  +            // Forward endDocument event
  +            super.endDocument();
  +
  +            // FIXME (SSA) Xalan2 workaround, should be removed
  +            hasStarted= false;
  +        }
  +
  +
  +        public void startPrefixMapping(String prefix, String uri) throws SAXException {
  +            // FIXME (SSA) Xalan2 workaround, should be put back
  +    //      if(isRootElem ) {
  +    //          if (originalNamespaces.containsKey(prefix)) {
  +    //              originalNamespaces.remove(prefix);
  +    //          }
  +    //      }
  +            // FIXME (SSA) Xalan2 workaround, should be removed
  +            if (hasStarted)
  +                super.startPrefixMapping(prefix, uri);
  +
  +        }
  +
  +        public void endPrefixMapping(String prefix) throws SAXException {
  +            super.endPrefixMapping(prefix);
  +        }
  +
  +
  +
  +        public void startElement (String namespaceURI, String localName,
  +        			      String qName, Attributes atts) throws SAXException {
  +            if(isRootElem) {
  +                isRootElem=false;
  +                // We are in the root element so send the registered namespaces
  +                Set prefixes = originalNamespaces.keySet();
  +                Iterator iter = prefixes.iterator();
  +                String prefix;
  +                while(iter.hasNext()) {
  +                    prefix = (String) iter.next();
  +                    super.startPrefixMapping(prefix, (String) originalNamespaces.get(prefix));
  +                }
  +                // FIXME (SSA) Xalan2 workaround, should be removed
  +                AttributesImpl newAtts = new AttributesImpl(atts);
  +                int attsLen = newAtts.getLength();
  +                for (int i=0; i<attsLen; i++) {
  +                    // force the URI to empty string, otherwise Xalan2J doesn't
  +                    // interpret correctly the 'namespace::' axis (XPath axis)
  +                    newAtts.setURI(i, "");
  +                }
  +                atts = newAtts;
  +            }
  +            super.startElement(namespaceURI, localName, qName, atts);
  +        }
  +
  +    }
  +
   }
  +
  
  
  
  1.1.2.4   +99 -44    xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/LogicsheetCodeGenerator.java
  
  Index: LogicsheetCodeGenerator.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/LogicsheetCodeGenerator.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- LogicsheetCodeGenerator.java	2000/07/29 18:30:28	1.1.2.3
  +++ LogicsheetCodeGenerator.java	2000/10/12 16:43:16	1.1.2.4
  @@ -7,62 +7,117 @@
    *****************************************************************************/
   package org.apache.cocoon.components.language.markup;
   
  -import java.util.Vector;
  +import java.io.StringWriter;
  +import java.util.ArrayList;
  +import java.util.List;
   
  -import org.w3c.dom.Element;
  -import org.w3c.dom.Document;
   import org.xml.sax.InputSource;
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.XMLFilter;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.ContentHandler;
  +import org.xml.sax.helpers.XMLFilterImpl;
   
   import java.io.IOException;
   import org.xml.sax.SAXException;
   
  +import serialize.SerializerFactory;
  +import serialize.Method;
  +import serialize.Serializer;
  +import serialize.OutputFormat;
  +
  +import trax.Transformer;
  +
   /**
  - * A logicsheet-based implementation of <code>MarkupGenerator</code>
  + * A logicsheet-based implementation of <code>MarkupCodeGenerator</code>
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/07/29 18:30:28 $
  + * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/10/12 16:43:16 $
    */
   public class LogicsheetCodeGenerator implements MarkupCodeGenerator {
  -  /**
  -   * Ordered list of logicsheet to be used in code generation
  -   */
  -  protected Vector logicsheets;
  -
  -  /**
  -   * The default constructor
  -   */
  -  public LogicsheetCodeGenerator() {
  -    this.logicsheets = new Vector();
  -  }
  -
  -  /**
  -   * Add a logicsheet to the logicsheet list
  -   *
  -   * @param logicsheet The logicsheet to be added
  -   */
  -  public void addLogicsheet(Logicsheet logicsheet) {
  -    this.logicsheets.addElement(logicsheet);
  -  }
  -
  -  /**
  -   * Generate source code from the input document. Filename information is
  -   * ignored in the logicsheet-based code generation approach
  -   *
  -   * @param input The input document
  -   * @param filename The input source original filename
  -   * @return The generated source code
  -   * @exception Exception If an error occurs during code generation
  -   */
  -  public String generateCode(Document input, String filename) throws Exception {
  -    int count = this.logicsheets.size();
  -    for (int i = 0; i < count; i++) {
  -      Logicsheet logicsheet = (Logicsheet) this.logicsheets.elementAt(i);
  -      input = logicsheet.apply(input);
  +
  +    private Logicsheet corelogicsheet;
  +
  +    private Serializer serializer;
  +
  +    private ContentHandler serializerContentHandler;
  +
  +    private XMLReader rootReader;
  +
  +    private XMLFilter currentParent;
  +
  +    /**
  +    * The default constructor
  +    */
  +    public LogicsheetCodeGenerator() {
  +        // set the serializer which would act as ContentHandler for the last transformer
  +        // FIXME (SSA) change a home made content handler, that extract the PCDATA
  +        // from the last remaining element
  +        this.serializer = SerializerFactory.getSerializer(Method.Text);
  +        OutputFormat outformat = new OutputFormat();
  +        // FIXME (SSA) set the right encoding set
  +        //outformat.setEncoding("");
  +        // FIXME (SSA) remove the nice identing. For debug purpose only.
  +        outformat.setIndent(true);
  +        outformat.setPreserveSpace(true);
  +        this.serializer.setOutputFormat(outformat);
  +
  +        this.serializer.setWriter(new StringWriter());
  +        try {
  +            this.serializerContentHandler = this.serializer.asContentHandler();
  +        } catch (IOException ioe) {
  +            // This should never happen, because we're not dealing with IO file,
  +            // but rather with StringWriter
  +            ioe.printStackTrace();
  +        }
       }
   
  -    Element result = input.getDocumentElement();
  -    result.normalize();
  +    /**
  +    * Add a logicsheet to the logicsheet list
  +    *
  +    * @param logicsheet The logicsheet to be added
  +    */
  +    public void addLogicsheet(Logicsheet logicsheet) {
  +        if (this.currentParent==null) {
  +            // Setup the first transformer of the chain.
  +            this.currentParent = logicsheet.getXMLFilter();
  +
  +            // the parent is the rootReader
  +            this.currentParent.setParent(this.rootReader);
  +
  +            // Set content handler for the end of the chain : serializer
  +            this.currentParent.setContentHandler(this.serializerContentHandler);
  +
  +        } else {
  +            // Build the transformer chain on the fly
  +            XMLFilter newParent=logicsheet.getXMLFilter();
  +
  +            // the currentParent is the parent of the new logicsheet filter
  +            newParent.setParent(this.currentParent);
  +
  +            // reset the new parent and the contentHanlder
  +            this.currentParent = newParent;
  +            this.currentParent.setContentHandler(this.serializerContentHandler);
  +        }
  +    }
   
  -    return result.getFirstChild().getNodeValue();
  -  }
  +    /**
  +    * Generate source code from the input document. Filename information is
  +    * ignored in the logicsheet-based code generation approach.
  +    *
  +    * @param reader The reader
  +    * @param input The input source
  +    * @param filename The input source original filename
  +    * @return The generated source code
  +    * @exception Exception If an error occurs during code generation
  +    */
  +    public String generateCode(XMLReader reader, InputSource input, String filename) throws Exception {
  +        // set the root XMLReader of the transformer chain
  +        this.rootReader = reader;
  +        // start the parsing
  +        this.rootReader.parse(input);
  +        return this.serializer.getWriter().toString();
  +    }
  +
   }
  +
  
  
  
  1.1.2.4   +15 -13    xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/MarkupCodeGenerator.java
  
  Index: MarkupCodeGenerator.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/MarkupCodeGenerator.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- MarkupCodeGenerator.java	2000/07/29 18:30:28	1.1.2.3
  +++ MarkupCodeGenerator.java	2000/10/12 16:43:16	1.1.2.4
  @@ -7,24 +7,26 @@
    *****************************************************************************/
   package org.apache.cocoon.components.language.markup;
   
  -import org.w3c.dom.Document;
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.InputSource;
   
   /**
    * This interfaces defines the functionality of a source code generator
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/07/29 18:30:28 $
  + * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/10/12 16:43:16 $
    */
   public interface MarkupCodeGenerator {
  -  /**
  -   * Generate source code from the input document. Filename information may be
  -   * needed by certain code-generation approaches and programming languages
  -   *
  -   * @param input The input document
  -   * @param filename The input source original filename
  -   * @return The generated source code
  -   * @exception Exception If an error occurs during code generation
  -   */
  -  public String generateCode(Document document, String filename)
  -    throws Exception;
  +    /**
  +    * Generate source code from the input reader. Filename information may be
  +    * needed by certain code-generation approaches and programming languages
  +    *
  +    * @param reader The input reader
  +    * @param input The input source
  +    * @param filename The input source original filename
  +    * @return The generated source code
  +    * @exception Exception If an error occurs during code generation
  +    */
  +    public String generateCode(XMLReader reader, InputSource input, String filename)
  +        throws Exception;
   }
  
  
  
  1.1.2.6   +28 -25    xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/MarkupLanguage.java
  
  Index: MarkupLanguage.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/MarkupLanguage.java,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- MarkupLanguage.java	2000/08/04 21:11:12	1.1.2.5
  +++ MarkupLanguage.java	2000/10/12 16:43:17	1.1.2.6
  @@ -7,7 +7,8 @@
    *****************************************************************************/
   package org.apache.cocoon.components.language.markup;
   
  -import org.w3c.dom.Document;
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.InputSource;
   import org.apache.avalon.NamedComponent;
   
   import org.apache.cocoon.components.language.programming.ProgrammingLanguage;
  @@ -15,34 +16,36 @@
   import org.xml.sax.EntityResolver;
   
   /**
  - * This interface defines a markup language whose instance documents are to be
  - * translated into an executable program capable or rebuilding the original
  + * This interface defines a markup language whose SAX producer's instance are to
  + * be translated into an executable program capable or transforming the original
    * document augmenting it with dynamic content
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.5 $ $Date: 2000/08/04 21:11:12 $
  + * @version CVS $Revision: 1.1.2.6 $ $Date: 2000/10/12 16:43:17 $
    */
   public interface MarkupLanguage extends NamedComponent {
  -  /**
  -   * Return the input document's encoding or <code>null</code> if it is the
  -   * platform's default encoding
  -   *
  -   * @return The document's encoding
  -   */
  -  public String getEncoding(Document document);
  +    /**
  +    * Return the input document's encoding or <code>null</code> if it is the
  +    * platform's default encoding.
  +    * This method should be called after <code>generateCode<code> method.
  +    *
  +    * @return The input document's encoding
  +    */
  +    public String getEncoding();
   
  -  /**
  -   * Generate source code from the input document for the target
  -   * <code>ProgrammingLanguage</code>.
  -   *
  -   * @param document The input document
  -   * @param filename The input document's original filename
  -   * @param programmingLanguage The target programming language
  -   * @return The generated source code
  -   * @exception Exception If an error occurs during code generation
  -   */
  -  public String generateCode(
  -    Document document, String filename, ProgrammingLanguage programmingLanguage,
  -    EntityResolver resolver
  -  ) throws Exception;
  +    /**
  +    * Generate source code from the input source for the target
  +    * <code>ProgrammingLanguage</code>.
  +    *
  +    * @param input The input source document
  +    * @param filename The input document's original filename
  +    * @param programmingLanguage The target programming language
  +    * @return The generated source code
  +    * @exception Exception If an error occurs during code generation
  +    */
  +    public String generateCode(
  +        InputSource input, String filename,
  +        ProgrammingLanguage programmingLanguage,
  +        EntityResolver resolver
  +    ) throws Exception;
   }
  
  
  
  1.1.2.4   +42 -42    xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/NamedLogicsheet.java
  
  Index: NamedLogicsheet.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/Attic/NamedLogicsheet.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- NamedLogicsheet.java	2000/07/29 18:30:28	1.1.2.3
  +++ NamedLogicsheet.java	2000/10/12 16:43:18	1.1.2.4
  @@ -16,55 +16,55 @@
    * An extension to <code>Logicsheet</code> that is associated with a namespace.
    * Named logicsheets are implicitly declared (and automagically applied) when
    * the markup language document's root element declares the same logichseet's
  - * namespace 
  + * namespace
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/07/29 18:30:28 $
  + * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/10/12 16:43:18 $
    */
   public class NamedLogicsheet extends Logicsheet {
  -  /**
  -   * The namespace uri
  -   */
  -  protected String uri;
  +    /**
  +    * The namespace uri
  +    */
  +    protected String uri;
   
  -  /**
  -   * The namespace prefix
  -   */
  -  protected String prefix;
  +    /**
  +    * The namespace prefix
  +    */
  +    protected String prefix;
   
  -  /**
  -   * Set the logichseet's namespace prefix
  -   *
  -   * @param prefix The namespace prefix
  -   */
  -  public void setPrefix(String prefix) {
  -    this.prefix = prefix;
  -  }
  +    /**
  +    * Set the logichseet's namespace prefix
  +    *
  +    * @param prefix The namespace prefix
  +    */
  +    public void setPrefix(String prefix) {
  +        this.prefix = prefix;
  +    }
   
  -  /**
  -   * Return the logicsheet's namespace prefix
  -   *
  -   * @return The logicsheet's namespace prefix
  -   */
  -  public String getPrefix() {
  -    return this.prefix;
  -  }
  +    /**
  +    * Return the logicsheet's namespace prefix
  +    *
  +    * @return The logicsheet's namespace prefix
  +    */
  +    public String getPrefix() {
  +        return this.prefix;
  +    }
   
  -  /**
  -   * Set the logichseet's namespace uri
  -   *
  -   * @param prefix The namespace uri
  -   */
  -  public void setUri(String uri) {
  -    this.uri = uri;
  -  }
  +    /**
  +    * Set the logichseet's namespace uri
  +    *
  +    * @param prefix The namespace uri
  +    */
  +    public void setUri(String uri) {
  +        this.uri = uri;
  +    }
   
  -  /**
  -   * Return the logicsheet's namespace uri
  -   *
  -   * @return The logicsheet's namespace uri
  -   */
  -  public String getUri() {
  -    return this.uri;
  -  }
  +    /**
  +    * Return the logicsheet's namespace uri
  +    *
  +    * @return The logicsheet's namespace uri
  +    */
  +    public String getUri() {
  +        return this.uri;
  +    }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.6   +385 -225  xml-cocoon/src/org/apache/cocoon/components/language/markup/sitemap/Attic/SitemapMarkupLanguage.java
  
  Index: SitemapMarkupLanguage.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/sitemap/Attic/SitemapMarkupLanguage.java,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- SitemapMarkupLanguage.java	2000/07/29 18:30:28	1.1.2.5
  +++ SitemapMarkupLanguage.java	2000/10/12 16:43:42	1.1.2.6
  @@ -9,18 +9,22 @@
   
   import java.io.File;
   import java.util.Date;
  -import java.util.Vector;
  -import java.util.Hashtable;
  +import java.util.List;
  +import java.util.ArrayList;
  +import java.util.Set;
  +import java.util.HashSet;
  +import java.util.Iterator;
  +
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.XMLFilter;
  +import org.xml.sax.EntityResolver;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.helpers.XMLFilterImpl;
  +import org.xml.sax.helpers.AttributesImpl;
   
  -import org.w3c.dom.Node;
  -import org.w3c.dom.Text;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.ProcessingInstruction;
  +import org.apache.cocoon.components.language.markup.*;
  +import org.apache.cocoon.components.language.markup.sitemap.*;
   
  -import org.apache.cocoon.util.DOMUtils;
  -import org.apache.cocoon.components.language.markup.AbstractMarkupLanguage;
   
   import org.apache.cocoon.components.language.programming.ProgrammingLanguage;
   
  @@ -33,226 +37,382 @@
    * <a href="http://xml.apache.org/cocoon/sitemap.html">Sitemap</a>.
    *
    * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
  - * @version CVS $Revision: 1.1.2.5 $ $Date: 2000/07/29 18:30:28 $
  + * @version CVS $Revision: 1.1.2.6 $ $Date: 2000/10/12 16:43:42 $
    */
   public class SitemapMarkupLanguage extends AbstractMarkupLanguage {
  -  /**
  -   * The default constructor.
  -   */
  -  public SitemapMarkupLanguage() throws SAXException, IOException {
  -    super();
  -  }
  -
  -  /**
  -   * Return the Sitemap language name: <i>map</i> :-)
  -   *
  -   * @return The <i>map</i> constant
  -   */
  -  public String getName() {
  -    return "map";
  -  }
  -
  -  /**
  -   * Return the document-declared encoding or <code>null</code> if it's the
  -   * platform's default encoding
  -   *
  -   * @param document The input document
  -   * @return The document-declared encoding
  -   */
  -  public String getEncoding(Document document) {
  -    String encoding = document.getDocumentElement().getAttribute("encoding");
  -
  -    if (encoding.length() > 0) {
  -      return encoding;
  -    }
  -
  -    return null;
  -  }
  -
  -  /**
  -   * Prepare the document for logicsheet processing and code generation. This
  -   * method sets the base filename, file path and creation date as root element
  -   * attibutes and encodes text nodes as strings.
  -   *
  -   * @param document The input document
  -   * @param filename The input source filename
  -   * @param language The target programming language
  -   * @return The augmented document
  -   */
  -  protected Document preprocessDocument(
  -    Document document, String filename, ProgrammingLanguage language
  -  )
  -  {
  -    // Store path and file name
  -    int pos = filename.lastIndexOf(File.separatorChar);
  -    String name = filename.substring(pos + 1);
  -    String path = filename.substring(0, pos).replace(File.separatorChar, '/');
  -
  -    Element root = document.getDocumentElement();
  -
  -    root.setAttribute("file-name", name);
  -    root.setAttribute("file-path", path);
  -    root.setAttribute("creation-date", String.valueOf(new Date().getTime()));
  -
  -    this.quoteStrings(document, language);
  -
  -    return document;
  -  }
  -
  -  /**
  -   * Encode text nodes as strings according to the target programming languages
  -   * string constant escaping rules.
  -   *
  -   * @param node The node to be escaped
  -   * @param language The target programming language
  -   */
  -  protected void quoteStrings(Node node, ProgrammingLanguage language) {
  -    switch (node.getNodeType()) {
  -      case Node.PROCESSING_INSTRUCTION_NODE:
  -        ProcessingInstruction pi = (ProcessingInstruction) node;
  -	if (!pi.getTarget().equals("xml-logicsheet")) {
  -          pi.setData(language.quoteString(pi.getData()));
  -	}
  -        break;
  -      case Node.TEXT_NODE:
  -        if (true) break; // the sitemap shouldn't have any text node
  -        Element parent = (Element) node.getParentNode();
  -
  -        String tagName = parent.getTagName();
  -
  -        if (
  -          tagName.equals("xsp:expr") ||
  -          tagName.equals("xsp:logic") ||
  -          tagName.equals("xsp:structure") ||
  -          tagName.equals("xsp:include")
  +
  +    /**
  +    * the dependencies' list
  +    */
  +    private Set dependencies;
  +
  +    /**
  +    * The default constructor.
  +    */
  +    public SitemapMarkupLanguage() throws SAXException, IOException {
  +        super();
  +        dependencies = new HashSet();
  +    }
  +
  +    /**
  +    * Return the Sitemap language name: <i>map</i> :-)
  +    *
  +    * @return The <i>map</i> constant
  +    */
  +    public String getName() {
  +        return "map";
  +    }
  +
  +    /**
  +    * FIXME (SSA) : See interface. For now returns null.
  +    *
  +    * Return the document-declared encoding or <code>null</code> if it's the
  +    * platform's default encoding
  +    *
  +    * @return The document-declared encoding
  +    */
  +    public String getEncoding() {
  +        return null;
  +    }
  +
  +    /**
  +    * Prepare the input source for logicsheet processing and code generation
  +    * with a preprocess filter.
  +    * The return <code>XMLFilter</code> object is the first filter on the
  +    * transformer chain.
  +    *
  +    * The Sitemap preprocess filter adds information on the root element such as
  +    * creation-date, file-name and file-path, plus it use the the passed
  +    * programming language to quote <code>Strings</code> on PCDATA node.
  +    *
  +    * @param filename The source filename
  +    * @param language The target programming language
  +    * @return The preprocess filter
  +    *
  +    * @see SitemapMarkupLanguage.PreProcessFilter
  +    *
  +    */
  +    protected XMLFilter getPreprocessFilter( String filename, ProgrammingLanguage language  )
  +    {
  +        return new PreProcessFilter(filename, language);
  +    }
  +
  +    /**
  +    * Add a dependency on an external file to the document for inclusion in
  +    * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  +    * to populate a list of <code>File</code>'s tested for change on each
  +    * invocation; this information, in turn, is used by
  +    * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  +    * necessary.
  +    *
  +    * @param location The file path of the dependent file
  +    * @see ServerPages <code>AbstractServerPagesGenerator</code>
  +    *      and <code>ServerPagesLoaderImpl</code>
  +    */
  +    protected void addDependency(String location) {
  +        dependencies.add(location);
  +    }
  +
  +
  +    /**
  +    * Returns a filter that chain on the fly the requested transformers
  +    * for source code generation. This method scans the input SAX events for
  +    * &lt;?xml-logicsheet?&gt; processing instructions and top-level
  +    * &lt;map:logicsheet&gt; elements. Logicsheet declarations are removed from
  +    * the input document.
  +    *
  +    * @param logicsheetMarkupGenerator the logicsheet markup generator
  +    * @param language the language descriptor
  +    * @param resolver the entity resolver
  +    * @return XMLFilter the filter that build on the fly the transformer chain
  +    */
  +    protected TransformerChainBuilderFilter getTranformerChainBuilder (
  +        LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +        EntityResolver resolver
  +    ) {
  +        return new SitemapTransformerChainBuilderFilter(
  +            logicsheetMarkupGenerator,
  +            resolver
  +        );
  +    }
  +
  +
  +//
  +//  Inner classes
  +//
  +
  +    /**
  +    * Preprocess filter for Sitemap Markup language.
  +    * It looks for PI event other that &lt;?xml-logisheet href=&quot;...&quot;&gt;
  +    * for quoting them;
  +    * It adds creation-date, file-name and file-path attributes to the root
  +    * Element;
  +    * And it quotes the PCDATA based by calling the quote method of the
  +    * programming language.
  +    *
  +    */
  +    protected class PreProcessFilter extends XMLFilterImpl {
  +
  +        private String filename;
  +
  +        private boolean isRootElem;
  +
  +        private ProgrammingLanguage language;
  +
  +        public PreProcessFilter (String filename, ProgrammingLanguage language) {
  +            super ();
  +            this.filename = filename;
  +            this.language = language;
  +        }
  +
  +        public void startDocument() throws SAXException {
  +            super.startDocument();
  +            isRootElem = true;
  +        }
  +
  +        public void processingInstruction(String target, String data) throws SAXException {
  +            if (!"xml-logicsheet".equals(target)) {
  +                data = this.language.quoteString(data);
  +            }
  +            super.processingInstruction(target, data);
  +        }
  +
  +        public void startElement (String namespaceURI, String localName,
  +		    String qName, Attributes atts) throws SAXException {
  +            if (isRootElem) {
  +                 isRootElem=false;
  +                // Store path and file name
  +                int pos = this.filename.lastIndexOf(File.separatorChar);
  +                String name = this.filename.substring(pos + 1);
  +                String path =
  +                    this.filename.substring(0, pos).replace(File.separatorChar, '/');
  +                // update the attributes
  +                AttributesImpl newAtts = new AttributesImpl(atts);
  +                newAtts.addAttribute("", "file-name", "file-name", "CDATA", name);
  +                newAtts.addAttribute("", "file-path", "file-path", "CDATA", path);
  +                newAtts.addAttribute("", "creation-date", "creation-date",
  +                    "CDATA", String.valueOf(new Date().getTime())
  +                );
  +                // forward element with the modified attribute
  +                super.startElement(namespaceURI, localName, qName, newAtts);
  +            } else {
  +                super.startElement(namespaceURI, localName, qName, atts);
  +            }
  +        }
  +    }
  +
  +    /**
  +    * This filter builds on the fly a chain of transformers. It extends the
  +    * <code>AbstractMArkupLanguage.TransformerChainBuilderFilter</code> so
  +    * it can adds XSP specific feature such as :
  +    * looking for &lt;?xml-logisheet href=&quot;...&quot?;&gt; PI and
  +    * &lt;map:xml-logisheet location=&quot;...&quot;&gt; elements to register
  +    * user defined logicsheets ;
  +    * adding all the dependencies related to the Sitemap as
  +    * &lt;map:dependency;&gt;...&lt;/map:dependency;&gt;
  +    *
  +    */
  +    protected  class SitemapTransformerChainBuilderFilter extends TransformerChainBuilderFilter {
  +
  +        private Object[] rootElement;
  +
  +        private List startPrefix;
  +
  +        private List endPrefix;
  +
  +        private StringBuffer rootChars;
  +
  +        private boolean isRootElem;
  +
  +        private boolean insideRootElement;
  +
  +        private boolean finished;
  +
  +        /**
  +         * default constructor
  +         *
  +         * @param logicsheetMarkupGenerator the code generator
  +         * @param resolver the entity resolver
  +         */
  +        protected SitemapTransformerChainBuilderFilter (
  +            LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +            EntityResolver resolver
           ) {
  -          return;
  +            super(logicsheetMarkupGenerator, resolver);
           }
   
  -        String value = language.quoteString(node.getNodeValue());
  -        Text textNode = node.getOwnerDocument().createTextNode(value);
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startDocument () throws SAXException {
  +            isRootElem=true;
  +            insideRootElement=false;
  +            finished=false;
  +            startPrefix = new ArrayList();
  +            rootChars = new StringBuffer();
  +        }
   
  -        Element textElement = node.getOwnerDocument().createElement("xsp:text");
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void processingInstruction(String target, String data) throws SAXException {
  +            // Retrieve logicsheets declared by processing-instruction
  +            if ("xml-logicsheet".equals(target)) {
  +                int start = data.indexOf("href");
  +                if (start >=0) {
  +                    // add 6, for lenght of 'href', plus '=' char, plus '"' char
  +                    start += 6;
  +                    // get the quote char. Can be " or '
  +                    char quote = data.charAt(start-1);
  +                    String href = data.substring(start);
  +                    int end = href.indexOf(quote);
  +                    href = href.substring(0, end);
  +                    try {
  +                        SitemapMarkupLanguage.this.addLogicsheet(
  +                            this.logicsheetMarkupGenerator, href, this.resolver
  +                        );
  +                    } catch (IOException ioe) {
  +                        throw new SAXException (ioe);
  +                    }
  +                }
  +                // Do not forward the PI event.
  +                return;
  +            }
  +            // Call super when this is not a logicsheet related PI
  +            super.processingInstruction(target,data);
  +        }
   
  -        textElement.appendChild(textNode);
  -        parent.replaceChild(textElement, node);
  -
  -        break;
  -      case Node.ELEMENT_NODE:
  -        ((Element) node).normalize();
  -        // Fall through
  -      default:
  -        NodeList childList = node.getChildNodes();
  -        int childCount = childList.getLength();
  -
  -        for (int i = 0; i < childCount; i++) {
  -          this.quoteStrings(childList.item(i), language);
  -        }
  -
  -        break;
  -    }
  -  }
  -
  -  /**
  -   * Returns a list of logicsheets to be applied to this document for source
  -   * code generation. This method scans the input document for
  -   * &lt;?xml-logicsheet?&gt; processing instructions and top-level
  -   * &lt;xsp:logicsheet&gt; elements. Logicsheet declarations are removed from
  -   * the input document.
  -   *
  -   * @param document The input document
  -   * @return An array of logicsheet <i>names</i>
  -   */
  -  protected String[] getLogicsheets(Document document) {
  -    Vector removedNodes = new Vector();
  -    Vector logicsheetList = new Vector();
  -    Element root = document.getDocumentElement();
  -
  -    // Retrieve logicsheets declared by processing-instruction
  -    NodeList nodeList = document.getChildNodes();
  -    int count = nodeList.getLength();
  -    for (int i = 0; i < count; i++) {
  -      Node node = nodeList.item(i);
  -      if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
  -	ProcessingInstruction pi = (ProcessingInstruction) node;
  -
  -	if (pi.getTarget().equals("xml-logicsheet")) {
  -          Hashtable attrs = DOMUtils.getPIPseudoAttributes(pi);
  -	  logicsheetList.addElement(attrs.get("href"));
  -
  -	  removedNodes.addElement(pi);
  -	}
  -      }
  -    }
  -
  -    // Retrieve logicsheets declared by top-level elements
  -    nodeList = root.getElementsByTagName("map:logicsheet");
  -    count = nodeList.getLength();
  -
  -    for (int i = 0; i < count; i++) {
  -      Element logicsheetElement = (Element) nodeList.item(i);
  -      removedNodes.addElement(logicsheetElement);
  -      logicsheetList.addElement(logicsheetElement.getAttribute("location"));
  -    }
  -
  -    String[] logicsheetLocations = new String[logicsheetList.size()];
  -    logicsheetList.copyInto(logicsheetLocations);
  -
  -
  -    // Remove logicsheet directives
  -    count = removedNodes.size();
  -    for (int i = 0; i < count; i++) {
  -      Node node = (Node) removedNodes.elementAt(i); 
  -      Node parent = node.getParentNode();
  -      parent.removeChild(node);
  -    }
  -
  -    return logicsheetLocations;
  -  }
  -
  -  /**
  -   * Add a dependency on an external file to the document for inclusion in
  -   * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  -   * to populate a list of <code>File</code>'s tested for change on each
  -   * invocation; this information, in turn, is used by
  -   * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  -   * necessary. XSP uses &lt;xsp:dependency&gt; elements for this purpose
  -   *
  -   * @param PARAM_NAME Param description
  -   * @return the value
  -   * @exception EXCEPTION_NAME If an error occurs
  -   * @see ServerPages <code>AbstractServerPagesGenerator</code>
  -   *      and <code>ServerPagesLoaderImpl</code>
  -   */
  -/** Sitemaps don't (yet) have dependencies */
  -  protected void addDependency(Document document, String location) {
  -    Element root = document.getDocumentElement();
  -    Element dependency = document.createElement("xsp:dependency");
  -    dependency.appendChild(document.createTextNode(location));
  -    root.appendChild(dependency);
  -  }
  -/* */
  -
  -  /**
  -   * Scan top-level document elements for non-xsp tag names returning the first
  -   * (and hopefully <i>only</i>) user-defined element
  -   *
  -   * @param document The input document
  -   * @return The first non-xsp element
  -   */
  -/** Sitemaps don't have a user root
  -  protected Element getUserRoot(Document document) {
  -    Element root = document.getDocumentElement();
  -    NodeList elements = root.getElementsByTagName("*");
  -    int elementCount = elements.getLength();
  -    for (int i = 0; i < elementCount; i++) {
  -      Element userRoot = (Element) elements.item(i);
  -      if (!userRoot.getTagName().startsWith("map:")) {
  -        return userRoot;
  -      }
  -    }
  -
  -    return null;
  -  }
  -*/
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startElement (String namespaceURI, String localName,
  +            String qName, Attributes atts) throws SAXException {
  +
  +            if (finished) {
  +                // Call super method
  +                super.startElement(namespaceURI, localName, qName, atts);
  +            } else {
  +                // Need more work
  +                if(isRootElem) {
  +                    isRootElem = false;
  +                    // cache the root element so that we resend the SAX event when
  +                    // we've finished dealing with <map:logicsheet > elements
  +                    rootElement = new Object[4];
  +                    rootElement[0]=namespaceURI;
  +                    rootElement[1]=localName;
  +                    rootElement[2]=qName;
  +                    rootElement[3]=atts;
  +                } else {
  +                    insideRootElement = true;
  +                    // Retrieve logicsheets declared by top-level elements <map:logicsheet ...>
  +                    // And do not forward the startElement event
  +                    if ("map:logicsheet".equals(qName)) {
  +                        String location = atts.getValue("location");
  +                        try {
  +                            SitemapMarkupLanguage.this.addLogicsheet(
  +                                this.logicsheetMarkupGenerator,
  +                                location,
  +                                this.resolver
  +                            );
  +                        } catch (IOException ioe) {
  +                            throw new SAXException (ioe);
  +                        }
  +                    } else {
  +                        // This element is not a <map:logicsheet element, so finish
  +                        // by :
  +                        // * setting the 'fisnished' flag to true ;
  +                        // * refiring all the cached events ;
  +                        // * firing all the necessary event dealing with file dependencies
  +                        finished=true;
  +
  +                        // send SAX events 'startDocument'
  +                        super.startDocument();
  +
  +                        // send all prefix namespace
  +                        String [] prefixArray;
  +                        for (int i=0; i<startPrefix.size(); i++) {
  +                            prefixArray = (String []) startPrefix.get(i);
  +                            super.startPrefixMapping(
  +                                prefixArray[0],
  +                                prefixArray[1]
  +                            );
  +                        }
  +
  +                        // send cached RootElement event
  +                        super.startElement(
  +                            (String) rootElement[0],
  +                            (String) rootElement[1],
  +                            (String) rootElement[2],
  +                            (Attributes) rootElement[3]
  +                        );
  +
  +                        // send cached characters
  +                        char[] ch = rootChars.toString().toCharArray();
  +                        super.characters( ch, 0, ch.length);
  +
  +                        // send the events dealing with dependencies.
  +                        // If some dependencies exist, then create <map:dependency elements
  +                        char[] locationChars;
  +                        Iterator iter = SitemapMarkupLanguage.this.dependencies.iterator();
  +                        while(iter.hasNext()) {
  +                            super.startElement(namespaceURI,
  +                                "dependency", "map:dependency",
  +                                new AttributesImpl()
  +                            );
  +                            locationChars = ((String) iter.next()).toCharArray();
  +                            super.characters(locationChars, 0 ,
  +                                locationChars.length
  +                            );
  +                            super.endElement(namespaceURI,
  +                                "dependency", "map:dependency"
  +                            );
  +                        }
  +
  +                        // And finally forward current Element.
  +                        super.startElement(namespaceURI, localName, qName, atts);
  +                    }
  +                }
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void endElement (String namespaceURI, String localName,
  +        			      String qName) throws SAXException {
  +            if (finished) {
  +                // Forward the events
  +                super.endElement(namespaceURI, localName, qName);
  +            }
  +        }
  +
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +         public void characters(char[] ch, int start, int length) throws SAXException {
  +            if (finished) {
  +                super.characters(ch, start, length);
  +            } else {
  +                if(!insideRootElement) {
  +                    // caching the PCDATA for the root element
  +                    rootChars.append(ch, start, length);
  +                }
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startPrefixMapping(String prefix, String uri) throws SAXException {
  +            if(finished) {
  +                super.startPrefixMapping(prefix, uri);
  +            } else {
  +                String[] prefixArray = new String [2];
  +                prefixArray[0]= prefix;
  +                prefixArray[1]= uri;
  +                startPrefix.add(prefixArray);
  +            }
  +        }
  +    }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.47  +2 -2      xml-cocoon/src/org/apache/cocoon/components/language/markup/sitemap/java/Attic/sitemap.xsl
  
  Index: sitemap.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/sitemap/java/Attic/sitemap.xsl,v
  retrieving revision 1.1.2.46
  retrieving revision 1.1.2.47
  diff -u -r1.1.2.46 -r1.1.2.47
  --- sitemap.xsl	2000/10/09 06:43:57	1.1.2.46
  +++ sitemap.xsl	2000/10/12 16:43:45	1.1.2.47
  @@ -70,7 +70,7 @@
        * This is the automatically generated class from the sitemap definitions
        *
        * @author &lt;a href="mailto:Giacomo.Pati@pwr.ch"&gt;Giacomo Pati&lt;/a&gt;
  -     * @version CVS $Revision: 1.1.2.46 $ $Date: 2000/10/09 06:43:57 $
  +     * @version CVS $Revision: 1.1.2.47 $ $Date: 2000/10/12 16:43:45 $
        */
       public class <xsl:value-of select="@file-name"/> extends AbstractSitemap {
         static {
  @@ -412,7 +412,7 @@
               List list;
               Parameters param;
               pipeline.setGenerator (generator_error_handler, e.getMessage(), emptyParam);
  -            ErrorNotifier eg = (ErrorNotifier) pipeline.getGenerator();
  +            ErrorNotifier eg = (ErrorNotifier)pipeline.getGenerator().get();
               eg.setException (e);
               <xsl:apply-templates select="./map:handle-errors/*"/>
               return false;
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.5   +434 -191  xml-cocoon/src/org/apache/cocoon/components/language/markup/xsp/Attic/XSPMarkupLanguage.java
  
  Index: XSPMarkupLanguage.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/language/markup/xsp/Attic/XSPMarkupLanguage.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- XSPMarkupLanguage.java	2000/08/31 15:51:20	1.1.2.4
  +++ XSPMarkupLanguage.java	2000/10/12 16:44:04	1.1.2.5
  @@ -9,19 +9,22 @@
   
   import java.io.File;
   import java.util.Date;
  -import java.util.Vector;
  -import java.util.Hashtable;
  +import java.util.HashSet;
  +import java.util.Set;
  +import java.util.ArrayList;
  +import java.util.List;
  +import java.util.Iterator;
  +import java.util.Stack;
  +
  +import org.xml.sax.XMLReader;
  +import org.xml.sax.XMLFilter;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.EntityResolver;
  +import org.xml.sax.helpers.AttributesImpl;
  +import org.xml.sax.helpers.XMLFilterImpl;
   
  -import org.w3c.dom.Node;
  -import org.w3c.dom.Text;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.ProcessingInstruction;
  -
  -import org.apache.cocoon.util.DOMUtils;
   import org.apache.cocoon.components.language.markup.AbstractMarkupLanguage;
  -
  +import org.apache.cocoon.components.language.markup.LogicsheetCodeGenerator;
   import org.apache.cocoon.components.language.programming.ProgrammingLanguage;
   
   
  @@ -33,209 +36,122 @@
    * <a href="http://xml.apache.org/cocoon/xsp.html">XSP</a>.
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/08/31 15:51:20 $
  + * @author <a href="mailto:ssahuc@apache.org">Sebastien Sahuc</a>
  + * @version CVS $Revision: 1.1.2.5 $ $Date: 2000/10/12 16:44:04 $
    */
   public class XSPMarkupLanguage extends AbstractMarkupLanguage {
  -  /**
  -   * The default constructor.
  -   */
  -  public XSPMarkupLanguage() throws SAXException, IOException {
  -    super();
  -  }
  -
  -  /**
  -   * Return the XSP language name: <i>xsp</i> :-)
  -   *
  -   * @return The <i>xsp</i> constant
  -   */
  -  public String getName() {
  -    return "xsp";
  -  }
  -
  -  /**
  -   * Return the document-declared encoding or <code>null</code> if it's the
  -   * platform's default encoding
  -   *
  -   * @param document The input document
  -   * @return The document-declared encoding
  -   */
  -  public String getEncoding(Document document) {
  -    String encoding = document.getDocumentElement().getAttribute("encoding");
   
  -    if (encoding.length() > 0) {
  -      return encoding;
  +    /**
  +    * store the dependencies.
  +    *
  +    * FIXME (SSA) Should not be shared between different calls.
  +    * Should be passed as argument of method getPreprocessFilter ?
  +    */
  +    private Set dependencies;
  +
  +    /**
  +    * The default constructor.
  +    */
  +    public XSPMarkupLanguage() throws SAXException, IOException {
  +        super();
  +        dependencies = new HashSet();
       }
  -
  -    return null;
  -  }
   
  -  /**
  -   * Prepare the document for logicsheet processing and code generation. This
  -   * method sets the base filename, file path and creation date as root element
  -   * attibutes and encodes text nodes as strings.
  -   *
  -   * @param document The input document
  -   * @param filename The input source filename
  -   * @param language The target programming language
  -   * @return The augmented document
  -   */
  -  protected Document preprocessDocument(
  -    Document document, String filename, ProgrammingLanguage language
  -  )
  -  {
  -    // Store path and file name
  -    int pos = filename.lastIndexOf(File.separatorChar);
  -    String name = filename.substring(pos + 1);
  -    String path = filename.substring(0, pos).replace(File.separatorChar, '/');
  -
  -    Element root = document.getDocumentElement();
  -
  -    root.setAttribute("file-name", name);
  -    root.setAttribute("file-path", path);
  -    root.setAttribute("creation-date", String.valueOf(new Date().getTime()));
  -
  -    this.quoteStrings(document, language);
  -
  -    return document;
  -  }
  -
  -  /**
  -   * Encode text nodes as strings according to the target programming languages
  -   * string constant escaping rules.
  -   *
  -   * @param node The node to be escaped
  -   * @param language The target programming language
  -   */
  -  protected void quoteStrings(Node node, ProgrammingLanguage language) {
  -    switch (node.getNodeType()) {
  -      case Node.PROCESSING_INSTRUCTION_NODE:
  -        ProcessingInstruction pi = (ProcessingInstruction) node;
  -        if (!pi.getTarget().equals("xml-logicsheet")) {
  -          pi.setData(language.quoteString(pi.getData()));
  -        }
  -        break;
  -      case Node.TEXT_NODE:
  -        Element parent = (Element) node.getParentNode();
  -
  -        String tagName = parent.getTagName();
  -
  -        if (
  -          tagName.equals("xsp:expr") ||
  -          tagName.equals("xsp:logic") ||
  -          tagName.equals("xsp:structure") ||
  -          tagName.equals("xsp:include")
  -        ) {
  -          return;
  -        }
  -
  -        String value = language.quoteString(node.getNodeValue());
  -        Text textNode = node.getOwnerDocument().createTextNode(value);
  -
  -        Element textElement = node.getOwnerDocument().createElement("xsp:text");
  -
  -        textElement.appendChild(textNode);
  -        parent.replaceChild(textElement, node);
  -
  -        break;
  -      case Node.ELEMENT_NODE:
  -        ((Element) node).normalize();
  -        // Fall through
  -      default:
  -        NodeList childList = node.getChildNodes();
  -        int childCount = childList.getLength();
  -
  -        for (int i = 0; i < childCount; i++) {
  -          this.quoteStrings(childList.item(i), language);
  -        }
  -
  -        break;
  +    /**
  +    * Return the XSP language name: <i>xsp</i> :-)
  +    *
  +    * @return The <i>xsp</i> constant
  +    */
  +    public String getName() {
  +        return "xsp";
       }
  -  }
   
  -  /**
  -   * Returns a list of logicsheets to be applied to this document for source
  -   * code generation. This method scans the input document for
  -   * &lt;?xml-logicsheet?&gt; processing instructions and top-level
  -   * &lt;xsp:logicsheet&gt; elements. Logicsheet declarations are removed from
  -   * the input document.
  -   *
  -   * @param document The input document
  -   * @return An array of logicsheet <i>names</i>
  -   */
  -  protected String[] getLogicsheets(Document document) {
  -    Vector removedNodes = new Vector();
  -    Vector logicsheetList = new Vector();
  -    Element root = document.getDocumentElement();
  -
  -    // Retrieve logicsheets declared by processing-instruction
  -    NodeList nodeList = document.getChildNodes();
  -    int count = nodeList.getLength();
  -    for (int i = 0; i < count; i++) {
  -      Node node = nodeList.item(i);
  -      if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
  -        ProcessingInstruction pi = (ProcessingInstruction) node;
  -
  -        if (pi.getTarget().equals("xml-logicsheet")) {
  -          Hashtable attrs = DOMUtils.getPIPseudoAttributes(pi);
  -          logicsheetList.addElement(attrs.get("href"));
  -
  -          removedNodes.addElement(pi);
  -        }
  -      }
  +    /**
  +    * FIXME (SSA) : See interface. For now returns null.
  +    *
  +    * Return the document-declared encoding or <code>null</code> if it's the
  +    * platform's default encoding
  +    *
  +    * @return The document-declared encoding
  +    */
  +    public String getEncoding() {
  +        return null;
       }
   
  -    // Retrieve logicsheets declared by top-level elements
  -    nodeList = root.getElementsByTagName("xsp:logicsheet");
  -    count = nodeList.getLength();
  +    /**
  +    * Prepare the input source for logicsheet processing and code generation
  +    * with a preprocess filter.
  +    * The return <code>XMLFilter</code> object is the first filter on the
  +    * transformer chain.
  +    *
  +    * The XSP preprocess filter adds information on the root element such as
  +    * creation-date, file-name and file-path, plus it use the the passed
  +    * programming language to quote <code>Strings</code> on PCDATA node.
  +    *
  +    * @param filename The source filename
  +    * @param language The target programming language
  +    * @return The preprocess filter
  +    *
  +    * @see XSPMarkupLanguage.PreProcessFilter
  +    */
  +    protected XMLFilter getPreprocessFilter( String filename, ProgrammingLanguage language  )
  +    {
  +        return new PreProcessFilter(filename, language);
  +    }
   
  -    for (int i = 0; i < count; i++) {
  -      Element logicsheetElement = (Element) nodeList.item(i);
  -      removedNodes.addElement(logicsheetElement);
  -      logicsheetList.addElement(logicsheetElement.getAttribute("location"));
  +    /**
  +    * Add a dependency on an external file to the document for inclusion in
  +    * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  +    * to populate a list of <code>File</code>'s tested for change on each
  +    * invocation; this information, in turn, is used by
  +    * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  +    * necessary. XSP uses &lt;xsp:dependency&gt; elements for this purpose
  +    *
  +    * @param location The file path of the dependent file
  +    * @see ServerPages <code>AbstractServerPagesGenerator</code>
  +    *      and <code>ServerPagesLoaderImpl</code>
  +    */
  +    protected void addDependency(String location) {
  +        dependencies.add(location);
       }
   
  -    String[] logicsheetLocations = new String[logicsheetList.size()];
  -    logicsheetList.copyInto(logicsheetLocations);
   
  -    // Remove logicsheet directives
  -    count = removedNodes.size();
  -    for (int i = 0; i < count; i++) {
  -      Node node = (Node) removedNodes.elementAt(i); 
  -      Node parent = node.getParentNode();
  -      parent.removeChild(node);
  +    /**
  +    * Returns a filter that chain on the fly the requested transformers for source
  +    * code generation. This method scans the input SAX events for
  +    * &lt;?xml-logicsheet?&gt; processing instructions and top-level
  +    * &lt;xsp:logicsheet&gt; elements. Logicsheet declarations are removed from
  +    * the input document.
  +    *
  +    * @param logicsheetMarkupGenerator the logicsheet markup generator
  +    * @param language the language descriptor
  +    * @param resolver the entity resolver
  +    * @return XMLFilter the filter that build on the fly the transformer chain
  +    */
  +    protected TransformerChainBuilderFilter getTranformerChainBuilder (
  +        LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +        EntityResolver resolver
  +    ) {
  +        return new XSPTransformerChainBuilderFilter(
  +            logicsheetMarkupGenerator,
  +            resolver
  +        );
       }
   
  -    return logicsheetLocations;
  -  }
  -
     /**
  -   * Add a dependency on an external file to the document for inclusion in
  -   * generated code. This is used by <code>AbstractServerPagesGenerator</code>
  -   * to populate a list of <code>File</code>'s tested for change on each
  -   * invocation; this information, in turn, is used by
  -   * <code>ServerPagesLoaderImpl</code> to assert whether regeneration is
  -   * necessary. XSP uses &lt;xsp:dependency&gt; elements for this purpose
  +   * FIXME (SSA) What do we do with that method ?
  +   * + Should we stay with the Text serializer that returns the wanted String,
  +   * + Or should we go along with another contentHandler that retrieve the PCDATA
  +   * from <xsp: element. The last option is way faster because it would avoid the
  +   * String construction, and would allow working on array of char[] instead.
      *
  -   * @param PARAM_NAME Param description
  -   * @return the value
  -   * @exception EXCEPTION_NAME If an error occurs
  -   * @see ServerPages <code>AbstractServerPagesGenerator</code>
  -   *      and <code>ServerPagesLoaderImpl</code>
  -   */
  -  protected void addDependency(Document document, String location) {
  -    Element root = document.getDocumentElement();
  -    Element dependency = document.createElement("xsp:dependency");
  -    dependency.appendChild(document.createTextNode(location));
  -    root.appendChild(dependency);
  -  }
  -
  -  /**
      * Scan top-level document elements for non-xsp tag names returning the first
      * (and hopefully <i>only</i>) user-defined element
      *
      * @param document The input document
      * @return The first non-xsp element
      */
  +   /*
     protected Element getUserRoot(Document document) {
       Element root = document.getDocumentElement();
       NodeList elements = root.getElementsByTagName("*");
  @@ -249,4 +165,331 @@
   
       return null;
     }
  +  */
  +
  +//
  +//  Inner classes
  +//
  +
  +    /**
  +    * Preprocess filter for XSP Markup language.
  +    * It looks for PI event other that &lt;?xml-logisheet href=&quot;...&quot;&gt;
  +    * for quoting them;
  +    * It adds creation-date, file-name and file-path attributes to the root
  +    * Element;
  +    * And it quotes the PCDATA based by calling the quote method of the
  +    * programming language.
  +    *
  +    */
  +    protected class PreProcessFilter extends XMLFilterImpl {
  +
  +        private Stack stack;
  +
  +        private String filename;
  +
  +        private boolean isRootElem;
  +
  +        private ProgrammingLanguage language;
  +
  +        /**
  +         * default constructor
  +         *
  +         * @param filename the filename
  +         * @param the programming language
  +         */
  +        public PreProcessFilter (String filename, ProgrammingLanguage language) {
  +            super ();
  +            this.filename = filename;
  +            this.language = language;
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startDocument() throws SAXException {
  +            super.startDocument();
  +            isRootElem = true;
  +            stack = new Stack();
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void processingInstruction(String target, String data) throws SAXException {
  +            if (!"xml-logicsheet".equals(target)) {
  +              data = this.language.quoteString(data);
  +            }
  +            super.processingInstruction(target, data);
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startElement (String namespaceURI, String localName,
  +        			      String qName, Attributes atts) throws SAXException {
  +             if (isRootElem) {
  +                 stack.push(new String[] { namespaceURI, localName, qName} );
  +                 isRootElem=false;
  +                // Store path and file name
  +                int pos = this.filename.lastIndexOf(File.separatorChar);
  +                String name = this.filename.substring(pos + 1);
  +                String path = this.filename.substring(0, pos).replace(File.separatorChar, '/');
  +                // update the attributes
  +                AttributesImpl newAtts = new AttributesImpl(atts);
  +                newAtts.addAttribute("", "file-name", "file-name", "CDATA", name);
  +                newAtts.addAttribute("", "file-path", "file-path", "CDATA", path);
  +                newAtts.addAttribute("", "creation-date", "creation-date", "CDATA",
  +                    String.valueOf(new Date().getTime())
  +                );
  +                // forward element with the modified attribute
  +                super.startElement(namespaceURI, localName, qName, newAtts);
  +            } else {
  +                stack.push(new String[] { namespaceURI, localName, qName} );
  +                super.startElement(namespaceURI, localName, qName, atts);
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void endElement (String namespaceURI, String localName,
  +            			      String qName) throws SAXException {
  +            stack.pop();
  +            super.endElement(namespaceURI, localName, qName);
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void characters(char[] ch, int start, int length) throws SAXException {
  +            String[] tag = (String[]) stack.peek();
  +            String tagName = tag[2];
  +            if (
  +              tagName.equals("xsp:expr") ||
  +              tagName.equals("xsp:logic") ||
  +              tagName.equals("xsp:structure") ||
  +              tagName.equals("xsp:include")
  +            ) {
  +              super.characters(ch, start, length);
  +            } else {
  +                // Quote the string depending on the programming language
  +                String value = this.language.quoteString(String.valueOf(ch, start, length));
  +                // Create a new element <xsp:text that wrap the quoted PCDATA
  +                super.startElement(tag[0], "text", "xsp:text", new AttributesImpl() );
  +                super.characters(value.toCharArray(), 0, value.length());
  +                super.endElement(tag[0], "text", "xsp:text");
  +            }
  +
  +        }
  +
  +
  +
  +    }
  +
  +
  +    /**
  +    * This filter builds on the fly a chain of transformers. It extends the
  +    * <code>AbstractMArkupLanguage.TransformerChainBuilderFilter</code> so
  +    * it can adds XSP specific feature such as :
  +    * looking for &lt;?xml-logisheet href=&quot;...&quot?;&gt; PI and
  +    * &lt;xsp:xml-logisheet location=&quot;...&quot;&gt; elements to register
  +    * user defined logicsheets ;
  +    * adding all the dependencies related to the XSP pages as
  +    * &lt;xsp:dependency;&gt;...&lt;/xsp:dependency;&gt;
  +    *
  +    */
  +    protected  class XSPTransformerChainBuilderFilter extends TransformerChainBuilderFilter {
  +
  +
  +        private List startPrefix;
  +
  +        private Object[] rootElement;
  +
  +        private StringBuffer rootChars;
  +
  +        private boolean isRootElem;
  +
  +        private boolean insideRootElement;
  +
  +        private boolean finished;
  +
  +        /**
  +         * default constructor
  +         *
  +         * @param logicsheetMarkupGenerator the code generator
  +         * @param resolver the entity resolver
  +         */
  +        protected XSPTransformerChainBuilderFilter (
  +            LogicsheetCodeGenerator logicsheetMarkupGenerator,
  +            EntityResolver resolver
  +        ) {
  +            super(logicsheetMarkupGenerator, resolver);
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void processingInstruction(String target, String data) throws SAXException {
  +            // Retrieve logicsheets declared by processing-instruction
  +            if ("xml-logicsheet".equals(target)) {
  +                int start = data.indexOf("href");
  +                if (start >=0) {
  +                    // add 6, for lenght of 'href', plus '=' char, plus '"' char
  +                    start += 6;
  +                    // get the quote char. Can be " or '
  +                    char quote = data.charAt(start-1);
  +                    String href = data.substring(start);
  +                    int end = href.indexOf(quote);
  +                    href = href.substring(0, end);
  +                    try {
  +                        XSPMarkupLanguage.this.addLogicsheet(
  +                            this.logicsheetMarkupGenerator,
  +                            href, this.resolver
  +                        );
  +                    } catch (IOException ioe) {
  +                        throw new SAXException (ioe);
  +                    }
  +                }
  +                // Do not forward the PI event.
  +                return;
  +            }
  +            // Call super when this is not a logicsheet related PI
  +            super.processingInstruction(target,data);
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startDocument () throws SAXException {
  +            isRootElem=true;
  +            insideRootElement=false;
  +            finished=false;
  +            startPrefix = new ArrayList();
  +            rootChars = new StringBuffer();
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startElement (String namespaceURI, String localName,
  +            String qName, Attributes atts ) throws SAXException {
  +            if (finished) {
  +            // Call super method
  +            super.startElement(namespaceURI, localName, qName, atts);
  +            } else {
  +                // Need more work
  +                if(isRootElem) {
  +                    isRootElem = false;
  +                    // cache the root element and resend the SAX event when
  +                    // we've finished dealing with <xsp:logicsheet > elements
  +                    rootElement = new Object[4];
  +                    rootElement[0]=namespaceURI;
  +                    rootElement[1]=localName;
  +                    rootElement[2]=qName;
  +                    rootElement[3]=atts;
  +                } else {
  +                    insideRootElement = true;
  +                    // Retrieve logicsheets declared by top-level elements <xsp:logicsheet ...>
  +                    // And do not forward the startElement event
  +                    if ("xsp:logicsheet".equals(qName)) {
  +                        String location = atts.getValue("location");
  +                        try {
  +                            XSPMarkupLanguage.this.addLogicsheet(
  +                                this.logicsheetMarkupGenerator,
  +                                location, this.resolver
  +                            );
  +                        } catch (IOException ioe) {
  +                            throw new SAXException (ioe);
  +                        }
  +                    } else {
  +                        // This element is not a <xsp:logicsheet element, so finish
  +                        // by :
  +                        // * setting the 'fisnished' flag to true ;
  +                        // * refiring all the cached events ;
  +                        // * firing all the necessary event dealing with file dependencies
  +                        finished=true;
  +
  +                        // send SAX events 'startDocument'
  +                        super.startDocument();
  +
  +                        // send all prefix namespace
  +                        String [] prefixArray;
  +                        for (int i=0; i<startPrefix.size(); i++) {
  +                            prefixArray = (String []) startPrefix.get(i);
  +                            super.startPrefixMapping(prefixArray[0], prefixArray[1]);
  +                        }
  +
  +                        // send cached RootElement event
  +                        super.startElement(
  +                            (String) rootElement[0],
  +                            (String) rootElement[1],
  +                            (String) rootElement[2],
  +                            (Attributes) rootElement[3]
  +                        );
  +
  +                        // send cached characters
  +                        char[] ch = rootChars.toString().toCharArray();
  +                        super.characters( ch, 0, ch.length);
  +
  +                        // send the events dealing with dependencies.
  +                        // If some dependencies exist, then creates
  +                        // <xsp:dependency elements
  +                        char[] locationChars;
  +                        Iterator iter = XSPMarkupLanguage.this.dependencies.iterator();
  +                        while(iter.hasNext()) {
  +                            super.startElement(
  +                                namespaceURI, "dependency",
  +                                "xsp:dependency", new AttributesImpl()
  +                            );
  +                            locationChars = ((String) iter.next()).toCharArray();
  +                            super.characters(locationChars, 0 , locationChars.length);
  +                            super.endElement(namespaceURI, "dependency", "xsp:dependency");
  +                        }
  +
  +                        // And finally forward current Element.
  +                        super.startElement(namespaceURI, localName, qName, atts);
  +                    }
  +                }
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void endElement (String namespaceURI, String localName,
  +            String qName) throws SAXException {
  +            if (finished) {
  +                // Forward the events
  +                super.endElement(namespaceURI, localName, qName);
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void characters(char[] ch, int start, int length) throws SAXException {
  +            if (finished) {
  +                super.characters(ch, start, length);
  +            } else {
  +                if(!insideRootElement) {
  +                    // caching the PCDATA for the root element
  +                    rootChars.append(ch, start, length);
  +                }
  +            }
  +        }
  +
  +        /**
  +         * @see ContentHandler
  +         */
  +        public void startPrefixMapping(String prefix, String uri) throws SAXException {
  +            if(finished) {
  +                super.startPrefixMapping(prefix, uri);
  +            } else {
  +                String[] prefixArray = new String [2];
  +                prefixArray[0]= prefix;
  +                prefixArray[1]= uri;
  +                startPrefix.add(prefixArray);
  +            }
  +        }
  +    }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.3   +9 -9      xml-cocoon/src/org/apache/cocoon/sitemap/Attic/ComponentHolderFactory.java
  
  Index: ComponentHolderFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/sitemap/Attic/ComponentHolderFactory.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- ComponentHolderFactory.java	2000/10/09 09:30:12	1.1.2.2
  +++ ComponentHolderFactory.java	2000/10/12 16:44:05	1.1.2.3
  @@ -21,20 +21,20 @@
    * interfaces the passed component implements.
    *
    * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
  - * @version CVS $Revision: 1.1.2.2 $ $Date: 2000/10/09 09:30:12 $
  + * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/10/12 16:44:05 $
    */
   public class ComponentHolderFactory {
   
       public static ComponentHolder getComponentHolder (String componentName, Configuration configuration, ComponentManager manager)
       throws Exception {
  -        if (ClassUtils.implementsInterface (componentName, Poolable.class.getName())) {
  -            return new PoolableComponentHolder (componentName, configuration, manager);
  -        } else if (ClassUtils.implementsInterface (componentName, SingleThreaded.class.getName())) {
  -            return new DefaultComponentHolder (componentName, configuration, manager);
  -        } else if (ClassUtils.implementsInterface (componentName, ThreadSafe.class.getName())) {
  +          /* if (ClassUtils.implementsInterface (componentName, Poolable.class.getName())) {
  +              return new PoolableComponentHolder (componentName, configuration, manager);
  +          } else if (ClassUtils.implementsInterface (componentName, SingleThreaded.class.getName())) {
  +              return new DefaultComponentHolder (componentName, configuration, manager);
  +          } else */ if (ClassUtils.implementsInterface (componentName, ThreadSafe.class.getName())) {
               return new ThreadSafeComponentHolder (componentName, configuration, manager);
  -        } else  {
  +          } else  {
               return new DefaultComponentHolder (componentName, configuration, manager);
  -        }
  +          }
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.1.2.3   +4 -2      xml-cocoon/src/org/apache/cocoon/sitemap/Attic/ErrorNotifier.java
  
  Index: ErrorNotifier.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/sitemap/Attic/ErrorNotifier.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- ErrorNotifier.java	2000/09/29 01:05:18	1.1.2.2
  +++ ErrorNotifier.java	2000/10/12 16:44:06	1.1.2.3
  @@ -19,16 +19,18 @@
   
   import org.apache.cocoon.generation.ComposerGenerator;
   
  +import org.apache.avalon.ThreadSafe;
  +
   /**
    * Generates an XML representation of the current notification.
    *
    * @author <a href="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a> Aisa
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @created 31 July 2000
  - * @version CVS $Revision: 1.1.2.2 $ $Date: 2000/09/29 01:05:18 $
  + * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/10/12 16:44:06 $
    */
    
  -public class ErrorNotifier extends ComposerGenerator {
  +public class ErrorNotifier extends ComposerGenerator implements ThreadSafe {
   
       /**
        * The <code>Notification</code> to report.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +2 -2      xml-cocoon/src/org/apache/cocoon/transformation/Attic/XIncludeTransformer.java
  
  Index: XIncludeTransformer.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/transformation/Attic/XIncludeTransformer.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- XIncludeTransformer.java	2000/10/01 00:17:37	1.1.2.7
  +++ XIncludeTransformer.java	2000/10/12 16:44:07	1.1.2.8
  @@ -32,7 +32,7 @@
   import org.apache.cocoon.components.parser.Parser;
   import org.apache.cocoon.xml.dom.DOMBuilder;
   import org.apache.cocoon.xml.dom.DOMStreamer;
  -import org.apache.cocoon.xml.xpath.XPathAPI;
  +import org.apache.xpath.XPathAPI;
   
   /**
    * My first pass at an XInclude transformation. Currently it should set the base URI
  @@ -42,7 +42,7 @@
    * by the SAX event FSM yet.
    *
    * @author <a href="mailto:balld@webslingerZ.com">Donald Ball</a>
  - * @version CVS $Revision: 1.1.2.7 $ $Date: 2000/10/01 00:17:37 $ $Author: stefano $
  + * @version CVS $Revision: 1.1.2.8 $ $Date: 2000/10/12 16:44:07 $ $Author: giacomo $
    */
   public class XIncludeTransformer extends AbstractTransformer implements Composer {
   
  
  
  
  1.1.2.12  +40 -21    xml-cocoon/src/org/apache/cocoon/transformation/Attic/XalanTransformer.java
  
  Index: XalanTransformer.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/transformation/Attic/XalanTransformer.java,v
  retrieving revision 1.1.2.11
  retrieving revision 1.1.2.12
  diff -u -r1.1.2.11 -r1.1.2.12
  --- XalanTransformer.java	2000/10/08 21:09:53	1.1.2.11
  +++ XalanTransformer.java	2000/10/12 16:44:08	1.1.2.12
  @@ -10,6 +10,7 @@
   import java.io.IOException;
   import java.util.Enumeration;
   import java.util.Map;
  +import java.util.Hashtable;
   import java.text.StringCharacterIterator;
   
   import javax.servlet.http.HttpServletRequest;
  @@ -27,31 +28,52 @@
   import org.apache.cocoon.xml.DocumentHandlerAdapter;
   import org.apache.cocoon.xml.DocumentHandlerWrapper;
   
  -import org.apache.xalan.xslt.StylesheetRoot;
  -import org.apache.xalan.xslt.XSLTInputSource;
  -import org.apache.xalan.xslt.XSLTProcessor;
  -import org.apache.xalan.xslt.XSLTProcessorFactory;
  -
   import org.xml.sax.ContentHandler;
   import org.xml.sax.EntityResolver;
   import org.xml.sax.InputSource;
   import org.xml.sax.SAXException;
   import org.xml.sax.ext.LexicalHandler;
  +import org.xml.sax.helpers.XMLReaderFactory;
  +import org.xml.sax.XMLReader;
   
   /**
    *
    * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
    *         (Apache Software Foundation, Exoffice Technologies)
  - * @version CVS $Revision: 1.1.2.11 $ $Date: 2000/10/08 21:09:53 $
  + * @version CVS $Revision: 1.1.2.12 $ $Date: 2000/10/12 16:44:08 $
    */
   public class XalanTransformer extends DocumentHandlerWrapper
   implements Transformer, Composer, Poolable {
   
       /** The store service instance */
       private Store store = null;
  +
  +    /** The XALAN Transformer */
  +	trax.Transformer transformer = null;
  +
  +    /** Hash table for Templates */
  +    private static Hashtable templatesCache = new Hashtable();
   
  -    /** The XALAN XSLTProcessor */
  -    private XSLTProcessor processor = null;
  +    private static trax.Transformer getTransformer(EntityResolver resolver, String xsluri)
  +      throws SAXException, ProcessingException, IOException
  +    {
  +        trax.Templates templates = (trax.Templates)templatesCache.get(xsluri);
  +        if(templates == null)
  +        {
  +    	    trax.Processor processor = 
  +                org.apache.cocoon.util.DOMUtils.getXSLTProcessor();
  +    	    XMLReader reader =
  +        	    XMLReaderFactory.createXMLReader();
  +            reader.setFeature("http://xml.org/sax/features/namespaces", true);
  +    	    trax.TemplatesBuilder templatesBuilder =
  +        	    processor.getTemplatesBuilder();
  +    	    reader.setContentHandler (templatesBuilder);
  +    	    reader.parse(resolver.resolveEntity(null,xsluri));
  +    	    templates = templatesBuilder.getTemplates();
  +            templatesCache.put(xsluri,templates);
  +        }
  +        return templates.newTransformer();
  +    }
   
       /**
        * Set the current <code>ComponentManager</code> instance used by this
  @@ -70,35 +92,32 @@
       throws SAXException, ProcessingException, IOException {
   
           /** The Request object */
  -        HttpServletRequest request = (HttpServletRequest) objectModel.get(Cocoon.REQUEST_OBJECT);
  +        HttpServletRequest request = (HttpServletRequest) objectModel.get(Cocoon.REQUEST_OBJECT);        
   
           // Check the stylesheet uri
           String xsluri = src;
           if (xsluri == null) {
               throw new ProcessingException("Stylesheet URI can't be null");
           }
  +
  +        /** get a transformer */
  +    	transformer = getTransformer(resolver,xsluri);
   
  -        // Load the stylesheet
  -        XSLTProcessor loaderprocessor = XSLTProcessorFactory.getProcessor();
  -        InputSource xslsrc = resolver.resolveEntity(null,xsluri);
  -        XSLTInputSource style = new XSLTInputSource(xslsrc);
  -        StylesheetRoot stylesheet = loaderprocessor.processStylesheet(style);
  -
  -        // Create the processor and set it as this documenthandler
  -        this.processor = XSLTProcessorFactory.getProcessor();
  -        this.processor.setStylesheet(stylesheet);
           if (request != null) {
               Enumeration parameters = request.getParameterNames();
               while (parameters.hasMoreElements()) {
                   String name = (String) parameters.nextElement();
                   if (isValidXSLTParameterName(name)) {
                       String value = request.getParameter(name);
  -                    processor.setStylesheetParam(name, this.processor.createXString(value));
  +                    transformer.setParameter(name, null /* namespace */,value);
                   }
               }
           }
   
  -        this.setDocumentHandler(this.processor);
  +        ContentHandler chandler = transformer.getInputContentHandler();
  +        this.setDocumentHandler(new DocumentHandlerAdapter(chandler));
  +        if(chandler instanceof org.xml.sax.ext.LexicalHandler)
  +            this.setLexicalHandler((org.xml.sax.ext.LexicalHandler)chandler);
       }
   
       /**
  @@ -118,7 +137,7 @@
        * accessing the protected <code>super.contentHandler</code> field.
        */
       public void setContentHandler(ContentHandler content) {
  -        this.processor.setDocumentHandler(new DocumentHandlerAdapter(content));
  +        this.transformer.setContentHandler(content);
       }
   
       /**
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.4   +154 -41   xml-cocoon/src/org/apache/cocoon/util/Attic/DOMUtils.java
  
  Index: DOMUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/util/Attic/DOMUtils.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- DOMUtils.java	2000/07/29 18:30:42	1.1.2.3
  +++ DOMUtils.java	2000/10/12 16:44:09	1.1.2.4
  @@ -24,17 +24,21 @@
   import java.net.MalformedURLException;
   import java.util.NoSuchElementException;
   
  -/* Start Xalan/Xerces kludge */
   import org.w3c.dom.*;
  -import org.apache.xerces.dom.DocumentImpl;
  +import javax.xml.parsers.DocumentBuilder;
  +import javax.xml.parsers.DocumentBuilderFactory;
  +import javax.xml.parsers.ParserConfigurationException; 
   import org.apache.xerces.parsers.DOMParser;
  -import org.apache.xalan.xslt.XSLTProcessor;
  -import org.apache.xalan.xslt.XSLTInputSource;
  -import org.apache.xalan.xslt.XSLTResultTarget;
  -import org.apache.xalan.xslt.XSLTProcessorFactory;
  -import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  -/* End Xalan/Xerces kludge */
   
  +import trax.Processor;
  +import trax.Result;
  +import trax.Transformer;
  +import trax.Templates;
  +
  +import serialize.OutputFormat;
  +import org.apache.xalan.templates.StylesheetRoot;
  +import org.apache.xalan.templates.Stylesheet;
  +
   /**
    * Collection of utility methods for DOM manipulation.
    * This class contains ugly dependencies on Xerces and Xalan
  @@ -42,25 +46,77 @@
    * add (needed!) DOM support.
    *
    * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
  - * @version CVS $Revision: 1.1.2.3 $ $Date: 2000/07/29 18:30:42 $
  + * @version CVS $Revision: 1.1.2.4 $ $Date: 2000/10/12 16:44:09 $
    */
   public class DOMUtils {
  -  // *** Start Xalan/Xerces kludge ***
  +
  +  /** reuse the trax.Processor instance */
  +  private static trax.Processor traxProcessor = null;
  +
  +  /** reuse the DocumentBuilder instance */
  +  private static DocumentBuilder docBuilder = null;
   
     /**
  -   * Static stylesheet processor with an augmented default liaison capable
  -   * of creating empty documents
  +   * Return a trax.Processor which can be used to process a style sheet.
  +   *
  +   * @return The Processor instance.
      */
  -  private static XSLTProcessor xsltProcessor =
  -      XSLTProcessorFactory.getProcessor(
  -        new XMLParserLiaisonDefault() {
  -          public Document createDocument() {
  -            return new DocumentImpl();
  -          }
  -	}
  -      );
  +  public static trax.Processor getXSLTProcessor() 
  +    throws trax.ProcessorFactoryException
  +  {
  +    if(traxProcessor == null)
  +      traxProcessor = Processor.newInstance("xslt");
  +	return traxProcessor;
  +  }
  +
  +  /**
  +   * Return a DocumentBuilder which can be used to parse a document.
  +   *
  +   * @return The DocumentBuilder instance.
  +   */
  +  private static DocumentBuilder getDocumentBuilder() 
  +    throws javax.xml.parsers.ParserConfigurationException
  +  {
  +    if(docBuilder == null)
  +    {
  +      DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
  +      dfactory.setNamespaceAware(true);
  +      docBuilder = dfactory.newDocumentBuilder();
  +    }
  +	return docBuilder;
  +  }
  +
   
     /**
  +   * Parse an input source returning a Transformer. <code>Transformer</code>
  +   *
  +   * @param inputSource The input source
  +   * @return A Transformer <code>Document</code>
  +   * @exception IOException IO Error
  +   * @exception SAXException Parse Error
  +   * @exception ParserConfigurationException Parser Configuration Error
  +   */
  +  public static Templates getTemplates(InputSource inputSource)
  +    throws SAXException, IOException, ParserConfigurationException
  +  {
  +    Processor processor = getXSLTProcessor();
  +    if(processor.getFeature("http://xml.org/trax/features/dom/input"))
  +    {
  +      try {
  +        return processor.process(inputSource);
  +      } catch (SAXException e){
  +        e.printStackTrace();
  +        throw(e);
  +      } catch (IOException e){
  +        e.printStackTrace();
  +        throw(e);
  +      }
  +    } else {
  +      throw new org.xml.sax.SAXNotSupportedException("DOM node processing not supported!");
  +    }
  +  }
  +
  +  /**
      * Parse an input source returning a DOM. <code>Document</code>
      *
      * @param inputSource The input source
  @@ -71,36 +127,47 @@
     public static Document DOMParse(InputSource inputSource)
       throws IOException, SAXException
     {
  -    DOMParser parser = new DOMParser();
  -    parser.parse(inputSource);
  -
  -    return parser.getDocument();
  +    try {
  +      return getDocumentBuilder().parse(inputSource);
  +    } catch (javax.xml.parsers.ParserConfigurationException e) {
  +      e.printStackTrace();        
  +      throw new org.xml.sax.SAXNotSupportedException("caught javax.xml.parsers.ParserConfigurationException!!!" + e);
  +    } catch (IOException e){
  +      e.printStackTrace();
  +      throw(e);
  +    } catch (SAXException e){
  +      e.printStackTrace();
  +      throw(e);
  +    }
     }
   
     /**
      * Apply a stylesheet to a given document
      *
      * @param input The input document
  -   * @param stylehseet The stylesheet document
  +   * @param transformer The stylesheet document
      * @return The transformed document
      * @exception SAXException SAX Error
      */
  -  public static Document transformDocument(Document input, Document stylesheet)
  -    throws SAXException
  +  public static Document transformDocument(Document input, Transformer transformer)
  +    throws SAXException, ParserConfigurationException
     {
  -    Document output = new DocumentImpl();
  -
  -    xsltProcessor.process(
  -      new XSLTInputSource(input),
  -      new XSLTInputSource(stylesheet),
  -      new XSLTResultTarget(output)
  -    );
  -
  -    return output;
  +    // Use an implementation of the JAVA API for XML Parsing 1.0 to
  +    // create a DOM Document node to contain the result.
  +    Document outNode = getDocumentBuilder().newDocument();
  +
  +    // Perform the transformation, placing the output in the DOM
  +    // Document Node.
  +    try 
  +    {
  +      transformer.transformNode(input, new Result(outNode));
  +    } catch (SAXException e){
  +      e.printStackTrace();
  +      throw(e);
  +    }    
  +    return outNode;
     }
   
  -  // *** End Xalan/Xerces kludge ***
  -
     /**
      * This method returns an hashtable of pseudo attributes found in the first
      * occurrence of the PI with the given name in the given document.
  @@ -144,7 +211,53 @@
       }
     }
   
  -
  +  /**
  +   * Return a list of all namespace-declaring attributes in the element.
  +   * This method returns both prefix-mapped namespaces and the optional
  +   * "unnamed" uri.
  +   *
  +   * @param Templates The compiled stylesheet
  +   * @return A (possibly empty) vector containing all namespace declarations
  +   *         as a <code>String</code> array of 2 elements (attribue name, uri)
  +   */
  +  public static Vector getNamespaces(trax.Templates templates) 
  +  {
  +    Vector vector = new Vector();
  +    // FIXME: Need to figure out how to get the namespaces from Templates.
  +    //        The following code throws an exception. 
  +    /*
  +    try 
  +    {
  +        StylesheetRoot stylesheet = (StylesheetRoot)templates;
  +        int n = stylesheet.getGlobalImportCount();
  +        for(int j = 0; j < n; j++)
  +        {
  +          Stylesheet imported = stylesheet.getGlobalImport(j);
  +          Element element = imported.getDocumentElement();
  +          NamedNodeMap map = element.getAttributes();
  +          int attrCount = map.getLength();
  +          for (int i = 0; i < attrCount; i++) 
  +          {
  +            Attr attr = (Attr) map.item(i);
  +            String attrName = attr.getName();
  +            if (
  +             !attrName.equals("xmlns:xsl") &&
  +                 (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
  +            ) {
  +              String[] pair = new String[2];
  +              pair[0] = attrName;
  +              pair[1] = attr.getValue();
  +              vector.addElement(pair);
  +            }
  +          }  
  +        }
  +    } catch (Exception e){
  +        //e.printStackTrace();
  +    }
  +    */
  +    return vector;
  +  }
  +  
     /**
      * Return a list of all namespace-declaring attributes in the element.
      * This method returns both prefix-mapped namespaces and the optional
  @@ -154,7 +267,7 @@
      * @return A (possibly empty) vector containing all namespace declarations
      *         as a <code>String</code> array of 2 elements (attribue name, uri)
      */
  -  public static Vector namespaces(Element element) {
  +  public static Vector getNamespaces(Element element) {
      Vector vector = new Vector();
      NamedNodeMap map = element.getAttributes();
      int attrCount = map.getLength();
  @@ -162,7 +275,7 @@
        Attr attr = (Attr) map.item(i);
        String attrName = attr.getName();
        if (
  -	  !attrName.equals("xmlns:xsl") &&
  +      !attrName.equals("xmlns:xsl") &&
             (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
        ) {
          String[] pair = new String[2];
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +7 -44     xml-cocoon/src/org/apache/cocoon/xml/xpath/Attic/XPathAPI.java
  
  Index: XPathAPI.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/xml/xpath/Attic/XPathAPI.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XPathAPI.java	2000/09/05 17:25:38	1.1.2.1
  +++ XPathAPI.java	2000/10/12 16:44:11	1.1.2.2
  @@ -14,12 +14,7 @@
   import org.w3c.dom.Document;
   import org.w3c.dom.NodeList;
   
  -import org.apache.xalan.xpath.XPathSupport;
  -import org.apache.xalan.xpath.XPath;
  -import org.apache.xalan.xpath.XPathProcessorImpl;
  -import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  -import org.apache.xalan.xpath.xml.PrefixResolverDefault;
  -import org.apache.xalan.xpath.XObject;
  +import org.apache.xpath.objects.XObject;
   
   /**
    * The methods in this class are convenience methods into the
  @@ -51,7 +46,7 @@
     public static Node selectSingleNode(Node contextNode, String str)
       throws SAXException
     {
  -    return selectSingleNode(contextNode, str, contextNode);
  +    return org.apache.xpath.XPathAPI.selectSingleNode(contextNode, str);
     }
   
     /**
  @@ -66,11 +61,7 @@
     public static Node selectSingleNode(Node contextNode, String str, Node namespaceNode)
       throws SAXException
     {
  -    // Have the XObject return its result as a NodeSet.
  -    NodeList nl = selectNodeList(contextNode, str, namespaceNode);
  -
  -    // Return the first node, or null
  -    return (nl.getLength() > 0) ? nl.item(0) : null;
  +    return org.apache.xpath.XPathAPI.selectSingleNode(contextNode, str, namespaceNode);
     }
   
    /**
  @@ -84,7 +75,7 @@
     public static NodeList selectNodeList(Node contextNode, String str)
       throws SAXException
     {
  -    return selectNodeList(contextNode, str, contextNode);
  +    return org.apache.xpath.XPathAPI.selectNodeList(contextNode, str);
     }
   
    /**
  @@ -99,12 +90,7 @@
     public static NodeList selectNodeList(Node contextNode, String str, Node namespaceNode)
       throws SAXException
     {
  -    // Execute the XPath, and have it return the result
  -    XObject list = eval(contextNode, str, namespaceNode);
  -
  -    // Have the XObject return its result as a NodeSet.
  -    return list.nodeset();
  -
  +    return org.apache.xpath.XPathAPI.selectNodeList(contextNode, str, namespaceNode);
     }
   
    /**
  @@ -124,7 +110,7 @@
     public static XObject eval(Node contextNode, String str)
       throws SAXException
     {
  -    return eval(contextNode, str, contextNode);
  +    return org.apache.xpath.XPathAPI.eval(contextNode, str);
     }
   
    /**
  @@ -148,29 +134,6 @@
     public static XObject eval(Node contextNode, String str, Node namespaceNode)
       throws SAXException
     {
  -    // Since we don't have a XML Parser involved here, install some default support
  -    // for things like namespaces, etc.
  -    // (Changed from: XPathSupportDefault xpathSupport = new XPathSupportDefault();
  -    //    because XPathSupportDefault is weak in a number of areas... perhaps
  -    //    XPathSupportDefault should be done away with.)
  -    XPathSupport xpathSupport = new XMLParserLiaisonDefault();
  -
  -    // Create an object to resolve namespace prefixes.
  -    // XPath namespaces are resolved from the input context node's document element
  -    // if it is a root node, or else the current context node (for lack of a better
  -    // resolution space, given the simplicity of this sample code).
  -    PrefixResolverDefault prefixResolver = new PrefixResolverDefault((contextNode.getNodeType() == Node.DOCUMENT_NODE)
  -                                                         ? ((Document)contextNode).getDocumentElement() :
  -                                                           contextNode);
  -
  -    // Create the XPath object.
  -    XPath xpath = new XPath();
  -
  -    // Create a XPath parser.
  -    XPathProcessorImpl parser = new XPathProcessorImpl(xpathSupport);
  -    parser.initXPath(xpath, str, prefixResolver);
  -
  -    // Execute the XPath, and have it return the result
  -    return xpath.execute(xpathSupport, contextNode, prefixResolver);
  +    return org.apache.xpath.XPathAPI.eval(contextNode, str, namespaceNode);
     }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.6   +11 -14    xml-cocoon/webapp/stylesheets/system/Attic/error2html.xsl
  
  Index: error2html.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/webapp/stylesheets/system/Attic/error2html.xsl,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- error2html.xsl	2000/09/03 13:43:23	1.1.2.5
  +++ error2html.xsl	2000/10/12 16:44:12	1.1.2.6
  @@ -2,13 +2,13 @@
   
   <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  - xmlns:err="http://apache.org/cocoon/2.0/error">
  + xmlns:error="http://apache.org/cocoon/2.0/error">
   
  -<xsl:template match="notify">
  +<xsl:template match="error:notify">
    <html>
     <head>
      <title>
  -    <xsl:value-of select="@type"/>:<xsl:value-of select="title"/>
  +    <xsl:value-of select="@type"/>:<xsl:value-of select="error:title"/>
      </title>
     </head>
     <body bgcolor="#ffffff">
  @@ -17,7 +17,7 @@
        <tr>
         <td bgcolor="#0086b2" colspan="2">
          <font color="#ffffff" face="arial,helvetica,sanserif" size="+2">
  -        <xsl:value-of select="title"/>
  +        <xsl:value-of select="error:title"/>
          </font>
         </td>
        </tr>
  @@ -29,7 +29,7 @@
          </font>
         </td>
         <td bgcolor="#ffffff" >
  -       <xsl:apply-templates select="message"/>
  +       <xsl:apply-templates select="error:message"/>
         </td>
        </tr>
   
  @@ -56,12 +56,12 @@
         </td>
         <td bgcolor="#ffffff">
          <font face="arial,helvetica,sanserif">
  -        <xsl:value-of select="source"/>
  +        <xsl:value-of select="error:source"/>
          </font>
         </td>
        </tr>
   
  -     <xsl:apply-templates select="description"/>
  +     <xsl:apply-templates select="error:description"/>
   
        <tr>
         <td bgcolor="#0086b2" valign="top" colspan="2">
  @@ -69,7 +69,7 @@
         </td>
        </tr>
   
  -     <xsl:apply-templates select="extra"/>
  +     <xsl:apply-templates select="error:extra"/>
   
       </tbody>
      </table>
  @@ -77,7 +77,7 @@
    </html>
   </xsl:template>
   
  - <xsl:template match="description">
  + <xsl:template match="error:description">
     <tr>
      <td bgcolor="#0086b2" valign="top">
       <font color="#ffffff" face="arial,helvetica,sanserif">description</font>
  @@ -90,13 +90,13 @@
     </tr>
    </xsl:template>
   
  - <xsl:template match="message">
  + <xsl:template match="error:message">
     <font face="arial,helvetica,sanserif">
      <xsl:value-of select="."/>
     </font>
    </xsl:template>
   
  - <xsl:template match="extra">
  + <xsl:template match="error:extra">
     <tr>
      <td bgcolor="#0086b2" valign="top">
       <font color="#ffffff" face="arial,helvetica,sanserif">
  @@ -110,7 +110,4 @@
      </td>
     </tr>
    </xsl:template>
  -
  - <xsl:template match="*"/>
  -
   </xsl:stylesheet>
  
  
  
  1.1.2.5   +3 -3      xml-cocoon/webapp/stylesheets/system/Attic/status2html.xsl
  
  Index: status2html.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/webapp/stylesheets/system/Attic/status2html.xsl,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- status2html.xsl	2000/09/10 09:13:37	1.1.2.4
  +++ status2html.xsl	2000/10/12 16:44:12	1.1.2.5
  @@ -4,7 +4,7 @@
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:status="http://apache.org/cocoon/2.0/status">
   
  -  <xsl:template match="statusinfo">
  +  <xsl:template match="status:statusinfo">
       <html>
         <head>
           <title>Cocoon2 status [<xsl:value-of select="@host"/>]</title>
  @@ -44,7 +44,7 @@
       </html>
     </xsl:template>
   
  -  <xsl:template match="group">
  +  <xsl:template match="status:group">
      <table bgcolor="#000000" noshade="noshade" border="0" cellspacing="2" cellpadding="6" width="100%">
       <tr>
         <td bgcolor="#0086b2" valign="top" align="left" colspan="2">
  @@ -71,7 +71,7 @@
   
     </xsl:template>
   
  -  <xsl:template match="value">
  +  <xsl:template match="status:value">
       <tr>
         <td bgcolor="#0086b2" valign="top" align="left">
          <FONT face="arial,helvetica,sanserif" color="#ffffff">
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.6.2.2   +1 -1      xml-cocoon/xdocs/faq.xml
  
  Index: faq.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/xdocs/faq.xml,v
  retrieving revision 1.6.2.1
  retrieving revision 1.6.2.2
  diff -u -r1.6.2.1 -r1.6.2.2
  --- faq.xml	2000/03/20 21:51:09	1.6.2.1
  +++ faq.xml	2000/10/12 16:44:13	1.6.2.2
  @@ -9,4 +9,4 @@
    <answer></answer>
   </faq>
   
  -</faqs>
  \ No newline at end of file
  +</faqs>
  
  
  
  1.2.2.2   +1 -1      xml-cocoon/xdocs/license.xml
  
  Index: license.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/xdocs/license.xml,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- license.xml	2000/03/20 21:51:09	1.2.2.1
  +++ license.xml	2000/10/12 16:44:14	1.2.2.2
  @@ -63,4 +63,4 @@
   ]]></source>
   </s1>
   </body>
  -</document>
  \ No newline at end of file
  +</document>