cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From un...@apache.org
Subject cvs commit: cocoon-2.1/src/blocks/xsp/java/org/apache/cocoon/generation AbstractServerPage.java ServerPagesGenerator.java
Date Wed, 10 Mar 2004 15:20:54 GMT
unico       2004/03/10 07:20:54

  Added:       src/blocks/xsp/java/org/apache/cocoon/generation
                        AbstractServerPage.java ServerPagesGenerator.java
  Removed:     src/blocks/xsp/java/org/apache/cocoon/generating
                        AbstractServerPage.java ServerPagesGenerator.java
  Log:
  fix package name
  
  Revision  Changes    Path
  1.1                  cocoon-2.1/src/blocks/xsp/java/org/apache/cocoon/generation/AbstractServerPage.java
  
  Index: AbstractServerPage.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.generation;
  
  import org.apache.avalon.framework.component.Recomposable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  
  import org.apache.cocoon.caching.CacheValidity;
  import org.apache.cocoon.caching.Cacheable;
  import org.apache.cocoon.caching.CacheableProcessingComponent;
  import org.apache.cocoon.components.language.generator.CompiledComponent;
  import org.apache.cocoon.environment.Request;
  
  import org.apache.excalibur.source.SourceValidity;
  import org.apache.excalibur.source.impl.validity.NOPValidity;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  
  import java.io.File;
  import java.io.Serializable;
  
  /**
   * Base implementation of <code>ServerPagesGenerator</code>. This class
   * declares variables that must be explicitly initialized by code generators.
   *
   * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
   * @version CVS $Id: AbstractServerPage.java,v 1.1 2004/03/10 15:20:51 unico Exp $
   */
  public abstract class AbstractServerPage
    extends ServletGenerator 
    implements CompiledComponent, CacheableProcessingComponent, Cacheable, Recomposable {
      /**
       * Code generators should produce a constructor
       * block that initializes the generator's
       * creation date and file dependency list.
       * Example:
       *
       *  {
       *    this.dateCreated = 958058788948L;
       *    this.dependencies = new File[] {
       *      new File("source.xml"),
       *    };
       *  }
       *
       */
  
      /** The creation date */
      protected long dateCreated = -1L;
      /** The dependency file list */
      protected File[] dependencies = null;
  
      /**
       * Recompose with the actual <code>ComponentManager</code> that should
       * be used.
       */
      public void recompose(ComponentManager manager) throws ComponentException {
          this.manager = manager;
      }
  
      /**
       * Determines whether this generator's source files have changed
       *
       * @return Whether any of the files this generator depends on has changed
       * since it was created
       */
      public boolean modifiedSince(long date) {
          if (date == 0 || dateCreated < date) {
              return true;
          }
  
          for (int i = 0; i < dependencies.length; i++) {
              if (dateCreated < dependencies[i].lastModified()) {
                  return true;
              }
          }
  
          return false;
      }
  
      /**
       * Determines whether generated content has changed since
       * last invocation. Users may override this method to take
       * advantage of SAX event cacheing
       *
       * @param request The request whose data must be inspected to assert whether
       * dynamically generated content has changed
       * @return Whether content has changes for this request's data
       */
      public boolean hasContentChanged(Request request) {
        return true;
      }
  
      /**
       * Generate the unique key.
       * This key must be unique inside the space of this component.
       * This method must be invoked before the generateValidity() method.
       *
       * @return The generated key or <code>null</code> if the component
       *         is currently not cacheable.
       */
      public Serializable getKey() {
          return null;
      }
  
      /**
       * Generate the validity object.
       * Before this method can be invoked the generateKey() method
       * must be invoked.
       *
       * @return The generated validity object, <code>NOPCacheValidity</code>
       *         is the default if hasContentChange() gives false otherwise
       *         <code>null</code> will be returned.
       */
      public SourceValidity getValidity() {
          if (hasContentChanged(request))
              return null;
          else
              return NOPValidity.SHARED_INSTANCE;
      }
  
      // FIXME: Add more methods!
      /* SAX Utility Methods */
      /**
       * Add an attribute
       *
       * @param attr The attribute list to add to
       * @param name The attribute name
       * @param value The attribute value
       */
      protected void attribute(AttributesImpl attr, String name, String value) {
          attr.addAttribute("", name, name, "CDATA", value);
      }
  
      /**
       * Start an element
       *
       * @param name The element name
       * @param attr The element attributes
       */
      protected void start(String name, AttributesImpl attr) throws SAXException {
          this.contentHandler.startElement("", name, name, attr);
          attr.clear();
      }
  
      /**
       * End an element
       *
       * @param name The element name
       */
      protected void end(String name) throws SAXException {
          this.contentHandler.endElement("", name, name);
      }
  
      /**
       * Add character data
       *
       * @param data The character data
       */
      protected void characters(String data) throws SAXException {
          this.contentHandler.characters(data.toCharArray(), 0, data.length());
      }
  
      /**
       * Add a comment
       *
       * @param data The comment data
       */
      protected void comment(String data) throws SAXException {
          this.lexicalHandler.comment(data.toCharArray(), 0, data.length());
      }
  
      /**
       * Generates the unique key.
       * This key must be unique inside the space of this component.
       * Users may override this method to take
       * advantage of SAX event cacheing
       *
       * @return A long representing the cache key (defaults to not cachable)
       */
      public long generateKey() {
          return 0;
      }
  
      /**
       * Generate the validity object.
       *
       * @return The generated validity object, <code>NOPCacheValidity</code>
       *         is the default if hasContentChange() gives false otherwise
       *         <code>null</code> will be returned.
       */
      public CacheValidity generateValidity() {
          if (hasContentChanged(request))
              return null;
          else
              return NOPCacheValidity.CACHE_VALIDITY;
      }
  
  }
  
  /** 
   * This is here to avaid references to the deprecated package.
   * It is required to support the deprecated caching algorithm
   */
  final class NOPCacheValidity
  implements CacheValidity {
  
      public static final CacheValidity CACHE_VALIDITY = new NOPCacheValidity();
  
      public boolean isValid(CacheValidity validity) {
          return validity instanceof NOPCacheValidity;
      }
  
      public String toString() {
          return "NOP Validity";
      }
  }
  
  
  1.1                  cocoon-2.1/src/blocks/xsp/java/org/apache/cocoon/generation/ServerPagesGenerator.java
  
  Index: ServerPagesGenerator.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.generation;
  
  import org.apache.commons.collections.ArrayStack;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.ResourceNotFoundException;
  import org.apache.cocoon.caching.CacheableProcessingComponent;
  import org.apache.cocoon.components.language.generator.ProgramGenerator;
  import org.apache.cocoon.components.source.SourceUtil;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.xml.AbstractXMLPipe;
  import org.apache.excalibur.source.Source;
  import org.apache.excalibur.source.SourceException;
  import org.apache.excalibur.source.SourceValidity;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.Map;
  
  /**
   * This class acts as a proxy to a dynamically loaded<code>Generator</code>
   * delegating actual SAX event generation.
   * <p>
   * It has a single configuration item :
   * <code>&lt;autocomplete-documents&gttrue|false&lt;autocomplete-documents&gt;</code>
   * (default is <code>false</code>).
   * <p>
   * This tells the generator to automatically close all elements that weren't properly closed
   * by the XSP, such as when a <code>return</code> statement is used to prematurely
end
   * processing. Activating this feature <em>sensibly increases CPU-usage</em>
and should
   * therefore be used only if really needed (it's better to have clean XSP pages that don't
   * break abruptly generation flow).
   *
   * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
   * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
   * @version CVS $Id: ServerPagesGenerator.java,v 1.1 2004/03/10 15:20:51 unico Exp $
   */
  public class ServerPagesGenerator extends ServletGenerator
          implements Disposable, CacheableProcessingComponent, Configurable {
      /**
       * The sitemap-defined server pages program generator
       */
      protected ProgramGenerator programGenerator = null;
  
      protected AbstractServerPage generator = null;
  
      /** The source */
      private Source inputSource;
  
      private CompletionPipe completionPipe;
  
      /**
       * Set the global component manager. This method sets the sitemap-defined
       * program generator
       *
       * @param manager The global component manager
       */
      public void compose(ComponentManager manager) throws ComponentException {
          super.compose(manager);
  
          if (programGenerator == null) {
              this.programGenerator =
                      (ProgramGenerator) manager.lookup(ProgramGenerator.ROLE);
          }
      }
  
      public void configure(Configuration config) throws ConfigurationException {
          boolean autoComplete = config.getChild("autocomplete-documents").getValueAsBoolean(false);
  
          if (autoComplete) {
              this.completionPipe = new CompletionPipe();
              this.completionPipe.enableLogging(getLogger());
          }
  
          this.markupLanguage = config.getChild("markup-language").getValue(DEFAULT_MARKUP_LANGUAGE);
          this.programmingLanguage = config.getChild("programming-language").getValue(DEFAULT_PROGRAMMING_LANGUAGE);
      }
  
      /**
       * Generate the unique key.
       * This key must be unique inside the space of this component.
       * This method must be invoked before the generateValidity() method.
       *
       * @return The generated key or <code>null</code> if the component
       *         is currently not cacheable.
       */
      public Serializable getKey() {
          Object key = generator.getKey();
          if (key == null) {
              return this.inputSource.getURI();
          }
          return this.inputSource.getURI() + '-' + key;
      }
  
      /**
       * Generate the validity object.
       * Before this method can be invoked the generateKey() method
       * must be invoked.
       *
       * @return The generated validity object or <code>null</code> if the
       *         component is currently not cacheable.
       */
      public SourceValidity getValidity() {
          // VG: Input source's systemID is part of the key,
          // and need not be included into the validity.
          return generator.getValidity();
      }
  
      /**
       * The loaded generator's <code>MarkupLanguage</code>
       */
      protected String markupLanguage;
  
      /**
       * The loaded generator's <code>ProgrammingLanguage</code>
       */
      protected String programmingLanguage;
  
      /**
       * The default <code>MarkupLanguage</code>
       */
      public final static String DEFAULT_MARKUP_LANGUAGE = "xsp";
  
      /**
       * The default <code>ProgrammingLanguage</code>
       */
      public final static String DEFAULT_PROGRAMMING_LANGUAGE = "java";
  
      public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
              throws ProcessingException, SAXException, IOException {
  
          super.setup(resolver, objectModel, src, par);
  
          String markupLanguage = this.parameters.getParameter(
                  "markup-language", this.markupLanguage);
          String programmingLanguage = this.parameters.getParameter(
                  "programming-language", this.programmingLanguage);
  
          try {
              this.inputSource = this.resolver.resolveURI(src);
          } catch (SourceException se) {
              throw SourceUtil.handle("Error during resolving of '" + src + "'.", se);
              //throw SourceUtil.handle(se);
          }
  
          try {
              this.generator = (AbstractServerPage) programGenerator.load(this.manager,
                      this.inputSource, markupLanguage, programmingLanguage, this.resolver);
          } catch (ProcessingException e) {
              throw e;
          } catch (Exception e) {
              getLogger().warn("setup()", e);
              throw new ProcessingException(e.getMessage(), e);
          } catch (NoClassDefFoundError e) {
              // VG: Usually indicates that page invoked with the wrong case.
              // I.e., it was compiled as "my.xsp" and inoked as "My.xsp",
              // results in different class name and an error.
              getLogger().warn("Failed to load class: " + e);
              throw new ResourceNotFoundException(e.getMessage());
          }
  
          // Give our own logger to the generator so that logs go in the correct category
          generator.enableLogging(getLogger());
  
          generator.setup(super.resolver, super.objectModel, super.source, super.parameters);
      }
  
      /**
       * Generate XML data. This method loads a server pages generator associated
       * with its (file) input source and delegates SAX event generator to it
       * taking care of "closing" any event left open by the loaded generator as a
       * result of its possible "premature" return (a common situation in server
       * pages)
       *
       * @exception IOException IO Error
       * @exception SAXException SAX event generation error
       * @exception ProcessingException Error during load/execution
       */
      public void generate() throws IOException, SAXException, ProcessingException {
  
          if (this.completionPipe != null) {
              generator.setConsumer(this.completionPipe);
              if (this.xmlConsumer != null) {
                  this.completionPipe.setConsumer(this.xmlConsumer);
              } else {
                  this.completionPipe.setContentHandler(this.contentHandler);
                  this.completionPipe.setLexicalHandler(this.lexicalHandler);
              }
          } else {
              if (this.xmlConsumer != null) {
                  generator.setConsumer(this.xmlConsumer);
              } else {
                  generator.setContentHandler(this.contentHandler);
                  generator.setLexicalHandler(this.lexicalHandler);
              }
          }
  
          // Fixes BUG#4062: Set document locator which is used by XIncludeTransformer
          org.xml.sax.helpers.LocatorImpl locator = new org.xml.sax.helpers.LocatorImpl();
          locator.setSystemId(this.inputSource.getURI());
          this.contentHandler.setDocumentLocator(locator);
  
          // Log exception and ensure that generator is released.
          try {
              generator.generate();
          } catch (IOException e) {
              getLogger().debug("IOException in generate()", e);
              throw e;
          } catch (SAXException e) {
              getLogger().debug("SAXException in generate()", e);
              throw e;
          } catch (ProcessingException e) {
              getLogger().debug("ProcessingException in generate()", e);
              throw e;
          } catch (Exception e) {
              getLogger().debug("Exception in generate()", e);
              throw new ProcessingException("Exception in ServerPagesGenerator.generate()",
e);
          } finally {
              if (generator != null) {
                  programGenerator.release(generator);
              }
              generator = null;
          }
  
          if (this.completionPipe != null) {
              this.completionPipe.flushEvents();
          }
      }
  
      /**
       * Recycle the generator by removing references
       */
      public void recycle() {
          if (this.generator != null) {
              this.programGenerator.release(this.generator);
              this.generator = null;
          }
          if (this.inputSource != null) {
              this.resolver.release(this.inputSource);
              this.inputSource = null;
          }
          if (this.completionPipe != null) {
              this.completionPipe.recycle();
              this.completionPipe = null;
          }
          super.recycle();
      }
  
      /**
       * dispose
       */
      public void dispose() {
          this.manager.release(this.programGenerator);
          this.programGenerator = null;
          this.manager = null;
      }
  
      /* Completion pipe */
  
      // int values for event types
      private final static int DOCUMENT = 0;
      private final static int ELEMENT = 1;
      private final static int PREFIX_MAPPING = 2;
      private final static int CDATA = 3;
      private final static int DTD = 4;
      private final static int ENTITY = 5;
  
      // Integer equivalents to push on the stack
      private final static Integer DOCUMENT_OBJ = new Integer(DOCUMENT);
      private final static Integer ELEMENT_OBJ = new Integer(ELEMENT);
      private final static Integer PREFIX_MAPPING_OBJ = new Integer(PREFIX_MAPPING);
      private final static Integer CDATA_OBJ = new Integer(CDATA);
      private final static Integer DTD_OBJ = new Integer(DTD);
      private final static Integer ENTITY_OBJ = new Integer(ENTITY);
  
      public class CompletionPipe extends AbstractXMLPipe {
  
          /**
           * The SAX event stack. Used for "completing" pendind SAX events left "open"
           * by prematurely returning server pages generators
           */
          protected ArrayStack eventStack = new ArrayStack();
  
          /**
           * Receive notification of the beginning of a document.
           */
          public void startDocument() throws SAXException {
              super.startDocument();
              this.eventStack.push(DOCUMENT_OBJ);
          }
  
          /**
           * Receive notification of the end of a document.
           */
          public void endDocument() throws SAXException {
              this.eventStack.pop();
              super.endDocument();
          }
  
          /**
           * Receive notification of the beginning of an element.
           */
          public void startElement(String namespaceURI, String localName, String rawName,
Attributes atts)
                  throws SAXException {
              super.startElement(namespaceURI, localName, rawName, atts);
              this.eventStack.push(rawName);
              this.eventStack.push(localName);
              this.eventStack.push(namespaceURI);
              this.eventStack.push(ELEMENT_OBJ);
          }
  
          /**
           * Receive notification of the end of an element.
           */
          public void endElement(String namespaceURI, String localName, String rawName)
                  throws SAXException {
              this.eventStack.pop(); // ELEMENT_OBJ
              this.eventStack.pop(); // namespaceURI
              this.eventStack.pop(); // localName
              this.eventStack.pop(); // rawName
              super.endElement(namespaceURI, localName, rawName);
          }
  
          /**
           * Begin the scope of a prefix-URI Namespace mapping.
           */
          public void startPrefixMapping(String prefix, String uri) throws SAXException {
              super.startPrefixMapping(prefix, uri);
              this.eventStack.push(prefix);
              this.eventStack.push(PREFIX_MAPPING_OBJ);
          }
  
          /**
           * End the scope of a prefix-URI mapping.
           */
          public void endPrefixMapping(String prefix) throws SAXException {
              this.eventStack.pop(); // PREFIX_MAPPING_OBJ
              this.eventStack.pop(); // prefix
              super.endPrefixMapping(prefix);
          }
  
          public void startCDATA() throws SAXException {
              super.startCDATA();
              this.eventStack.push(CDATA_OBJ);
          }
  
          public void endCDATA() throws SAXException {
              this.eventStack.pop();
              super.endCDATA();
          }
  
          public void startDTD(String name, String publicId, String systemId)
                  throws SAXException {
              super.startDTD(name, publicId, systemId);
              this.eventStack.push(DTD_OBJ);
          }
  
          public void endDTD() throws SAXException {
              this.eventStack.pop();
              super.endDTD();
          }
  
          public void startEntity(String name) throws SAXException {
              super.startEntity(name);
              this.eventStack.push(name);
              this.eventStack.push(ENTITY_OBJ);
          }
  
          public void endEntity(String name) throws SAXException {
              this.eventStack.pop(); // ENTITY_OBJ
              this.eventStack.pop(); // name
              super.endEntity(name);
          }
  
          public void flushEvents() throws SAXException {
  
              if (this.getLogger().isWarnEnabled()) {
                  if (this.eventStack.size() > 0) {
                      this.getLogger().warn("Premature end of document generated by " + inputSource.getURI());
                  }
              }
  
              // End any started events in case of premature return
              while (this.eventStack.size() != 0) {
                  int event = ((Integer) eventStack.pop()).intValue();
  
                  switch (event) {
                      case DOCUMENT:
                          super.endDocument();
                          break;
  
                      case ELEMENT:
                          String namespaceURI = (String) eventStack.pop();
                          String localName = (String) eventStack.pop();
                          String rawName = (String) eventStack.pop();
                          super.endElement(namespaceURI, localName, rawName);
                          break;
  
                      case PREFIX_MAPPING:
                          super.endPrefixMapping((String) eventStack.pop());
                          break;
  
                      case CDATA:
                          super.endCDATA();
                          break;
  
                      case DTD:
                          super.endDTD();
                          break;
  
                      case ENTITY:
                          super.endEntity((String) eventStack.pop());
                          break;
                  }
              }
          }
  
          public void recycle() {
              this.eventStack.clear();
              super.recycle();
          }
      }
  }
  
  
  

Mime
View raw message