cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From u..@apache.org
Subject svn commit: rev 31040 - in cocoon/branches/butterfly: . lib src/java/org/apache/butterfly src/java/org/apache/butterfly/components/pipeline src/java/org/apache/butterfly/components/pipeline/impl src/java/org/apache/butterfly/environment src/java/org/apache/butterfly/environment/http src/java/org/apache/butterfly/generation src/java/org/apache/butterfly/reading src/java/org/apache/butterfly/serialization src/java/org/apache/butterfly/servlet src/java/org/apache/butterfly/servlet/multipart src/java/org/apache/butterfly/sitemap src/java/org/apache/butterfly/source src/java/org/apache/butterfly/source/impl src/java/org/apache/butterfly/source/impl/validity src/java/org/apache/butterfly/transformation src/java/org/apache/butterfly/util src/java/org/apache/butterfly/xml src/java/org/apache/butterfly/xml/dom src/java/org/apache/butterfly/xml/xslt src/test src/test/org/apache/butterfly/components/pipeline/impl src/test/org/apache/butterfly/generation src/test/org/apache/butterfly/serialization src/test/org/apache/butterfly/source src/test/org/apache/butterfly/test src/test/org/apache/butterfly/transformation testdata
Date Sat, 31 Jul 2004 16:06:09 GMT
Author: ugo
Date: Sat Jul 31 09:06:07 2004
New Revision: 31040

Added:
   cocoon/branches/butterfly/lib/commons-collections-3.1.jar   (contents, props changed)
   cocoon/branches/butterfly/lib/servlet-2_3.jar   (contents, props changed)
   cocoon/branches/butterfly/src/java/org/apache/butterfly/Constants.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/AbstractEnvironment.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Context.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Cookie.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/EnvironmentException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/ObjectModelHelper.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Request.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Response.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Session.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpContext.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpCookie.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpEnvironment.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpRequest.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpResponse.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpSession.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartHttpServletRequest.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartParser.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/Part.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartInMemory.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartOnDisk.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/RequestFactory.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/TokenStream.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/util/
   cocoon/branches/butterfly/src/java/org/apache/butterfly/util/BufferedOutputStream.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/util/NetUtils.java
Modified:
   cocoon/branches/butterfly/.classpath
   cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/InvalidPipelineException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineProcessingException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/ProcessingPipeline.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipeline.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Environment.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/FileGenerator.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/Generator.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/reading/Reader.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/Serializer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/XMLSerializer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/sitemap/SitemapOutputComponent.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/Source.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceFactory.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceNotFoundException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceResolver.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceUtil.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceValidity.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/URIAbsolutizer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSource.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSourceFactory.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSource.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSourceFactory.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/validity/FileTimeStampValidity.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/Transformer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/TraxTransformer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLPipe.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLProducer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/EmbeddedXMLPipe.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/Parser.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/WhitespaceFilter.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLConsumer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLProducer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMBuilder.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMStreamer.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxException.java
   cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxTransformerFactory.java
   cocoon/branches/butterfly/src/test/beans.xml
   cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/GroovySitemapTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/MyPipeline.groovy
   cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipelineTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/Pipeline.groovy
   cocoon/branches/butterfly/src/test/org/apache/butterfly/generation/FileGeneratorTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/serialization/XMLSerializerTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/source/SourceResolverTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/test/SitemapComponentTestCase.java
   cocoon/branches/butterfly/src/test/org/apache/butterfly/transformation/TraxTransformerTestCase.java
   cocoon/branches/butterfly/testdata/test1.xml
Log:
Environment.
Put ASF copyright notice in License headers.


Modified: cocoon/branches/butterfly/.classpath
==============================================================================
--- cocoon/branches/butterfly/.classpath	(original)
+++ cocoon/branches/butterfly/.classpath	Sat Jul 31 09:06:07 2004
@@ -18,5 +18,7 @@
 	<classpathentry kind="lib" path="lib/groovy-1.0-beta-6.jar"/>
 	<classpathentry kind="lib" path="lib/asm-util-1.4.3.jar"/>
 	<classpathentry kind="lib" path="lib/asm-1.4.1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-collections-3.1.jar"/>
+	<classpathentry kind="lib" path="lib/servlet-2_3.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Added: cocoon/branches/butterfly/lib/commons-collections-3.1.jar
==============================================================================
Binary file. No diff available.

Added: cocoon/branches/butterfly/lib/servlet-2_3.jar
==============================================================================
Binary file. No diff available.

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/Constants.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/Constants.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,288 @@
+/*
+ * 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.butterfly;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * The <code>Constants</code> use throughout the core of the Cocoon engine.
+ *
+ * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
+ * @author <a href="mailto:proyal@managingpartners.com">Peter Royal</a>
+ * @version CVS $Id: Constants.java,v 1.15 2004/06/11 21:37:04 vgritsenko Exp $
+ */
+public final class Constants {
+
+    /** Our properties are now here: */
+    private static final String PROPS_FILE = "org/apache/cocoon/cocoon.properties";
+
+    static final Properties properties;
+
+    /**
+     * Load the cocoon properties
+     */
+    static {
+        properties = new Properties();
+        try {
+            final InputStream is = Constants.class.getClassLoader().getResourceAsStream(PROPS_FILE);
+            if ( null == is ) {
+                throw new RuntimeException("Cocoon cannot find required properties from " + PROPS_FILE);
+            }
+            properties.load(is);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Cocoon cannot load required properties from " + PROPS_FILE);
+        }
+
+    }
+
+    /** The name of this project. */
+    public static final String NAME = properties.getProperty("name");
+
+    /** The version of this build. */
+    public static final String VERSION = properties.getProperty("version");
+
+    /** The full name of this project. */
+    public static final String COMPLETE_NAME = properties.getProperty("fullname") + " " + VERSION;
+
+    /** The version of the configuration schema */
+    public static final String CONF_VERSION  = "2.2";
+
+    /** The year of the build */
+    public static final String YEAR = properties.getProperty("year");
+
+    /**
+     * The request parameter name to reload the configuration.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String RELOAD_PARAM = "cocoon-reload";
+
+    /**
+     * The request parameter name to add a line of the request duration.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String SHOWTIME_PARAM = "cocoon-showtime";
+
+    /**
+     * The request parameter name to request a specific view of a resource.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String VIEW_PARAM = "cocoon-view";
+
+    /**
+     * The request parameter name to trigger a specific action.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String ACTION_PARAM = "cocoon-action";
+
+    /**
+     * The request parameter prefix to trigger a specific action.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String ACTION_PARAM_PREFIX = "cocoon-action-";
+
+    /** The name of the property holding the class for a XML parser */
+    public static final String PARSER_PROPERTY = "org.apache.excalibur.xml.sax.SAXParser";
+
+    /** The name of the class for the default XML parser to use */
+    public static final String DEFAULT_PARSER  = "org.apache.excalibur.xml.impl.JaxpParser";
+
+    /** The namespace for the XSP core logicsheet. */
+    public static final String XSP_URI = "http://apache.org/xsp";
+
+    /**
+     * The namespace prefix for the request logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_REQUEST_PREFIX = "xsp-request";
+
+    /**
+     * The namespace for the request logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_REQUEST_URI = XSP_URI + "/request/2.0";
+
+    /**
+     * The namespace prefix for the response logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_RESPONSE_PREFIX = "xsp-response";
+
+    /**
+     * The namespace for the response logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_RESPONSE_URI = XSP_URI + "/response/2.0";
+
+    /**
+     * The namespace prefix for the cookie logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_COOKIE_PREFIX = "xsp-cookie";
+
+    /**
+     * The namespace for the cookie logicsheet.
+     *
+     * FIXME(GP): Would logicsheets belong to the core?
+     */
+    public static final String XSP_COOKIE_URI = XSP_URI + "/cookie/2.0";
+
+    /**
+     * Don't know exactly what this is for. (I can guess it's for the FormValidator)
+     *
+     * FIXME(GP): Isn't this component specific?
+     */
+    public static final String XSP_FORMVALIDATOR_PATH = "org.apache.cocoon.acting.FormValidatorAction.results";
+
+    /** The URI for xml namespaces */
+    public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
+
+    /**
+     * Mime-type for the link view
+     *
+     * FIXME(GP): Isn't this Environment specific?
+     */
+    public static final String LINK_CONTENT_TYPE = "application/x-cocoon-links";
+
+    /**
+     * Name of the request value for the link view
+     *
+     * FIXME(GP): Isn't this Environment specific?
+     */
+    public static final String LINK_VIEW = "links";
+
+    /** Don't know exactly what this is for (and it is not used in the code base) */
+    public static final String LINK_CRAWLING_ROLE = "static";
+
+    /**
+     * Key of the Map of index translation table.
+     * <p>Presence of this Map in the ObjectModel indicates to the Sitemap that link
+     * translation mode has been requested by the environment. Sitemap adds LinkTranslator
+     * transformer to the pipeline, which replaces all the links in the input document with
+     * the links from this translation table.
+     * <p>
+     * TODO(VG): Move this declaration to ObjectModelHelper
+     * comment found at ObjectModelHelper(JH):
+     * LINK_OBJECT should also be moved to CommandLineEnvironment
+     */
+    public static final String LINK_OBJECT = "link";
+
+    /**
+     * Key of the List for collecting links.
+     * <p>Presence of this Map in the ObjectModel indicates to the Sitemap that link
+     * gathering mode has been requested by the environment. Sitemap adds LinkGatherer
+     * transformer to the pipeline, which gathers the links in the input document into
+     * this List.
+     * <p>
+     */
+    public static final String LINK_COLLECTION_OBJECT = "link-collection";
+
+    /**
+     * The name of a <code>NotifyingObject</code> in the so called objectModel <code>Map</code>.
+     */
+    public static final String NOTIFYING_OBJECT = "notifying-object";
+
+    /**
+     * The default URI to be used when a URI requested refers to
+     * a directory, e.g. http://localhost:8080/site/
+     */
+    public static final String INDEX_URI = "index";
+
+    /**
+     * The directory to use as context root.
+     */
+    public static final String DEFAULT_CONTEXT_DIR = "./webapp";
+
+    /**
+     * The diretory to use to use for the generated output.
+     */
+    public static final String DEFAULT_DEST_DIR = "./site";
+
+    /**
+     * The diretory to use for generated files.
+     */
+    public static final String DEFAULT_WORK_DIR = "./work";
+
+    /**
+     * How a default configuration file is named.
+     */
+    public static final String DEFAULT_CONF_FILE = "cocoon.xconf";
+
+    /** The namespace URI for the Error/Exception XML */
+    public static final String ERROR_NAMESPACE_URI = "http://apache.org/cocoon/error/2.1";
+
+    /** The namespace prefix for the Error/Exception XML */
+    public static final String ERROR_NAMESPACE_PREFIX = "error";
+
+    /** Application <code>Context</code> Key for the environmental Context */
+    public static final String CONTEXT_ENVIRONMENT_CONTEXT = "environment-context";
+
+    /** Application <code>Context</code> Key for the global classloader */
+    public static final String CONTEXT_CLASS_LOADER = "class-loader";
+
+    /** Application <code>Context</code> Key for the work directory path */
+    public static final String CONTEXT_WORK_DIR = "work-directory";
+
+    /** Application <code>Context</code> Key for the upload directory path */
+    public static final String CONTEXT_UPLOAD_DIR = "upload-directory";
+
+    /** Application <code>Context</code> Key for the cache directory path */
+    public static final String CONTEXT_CACHE_DIR = "cache-directory";
+
+    /** Application <code>Context</code> Key for the current classpath */
+    public static final String CONTEXT_CLASSPATH = "classpath";
+
+    /**
+     * Application <code>Context</code> Key for the URL to the configuration file
+     * (usually named cocoon.xconf)
+     */
+    public static final String CONTEXT_CONFIG_URL = "config-url";
+
+    /** Application <code>Context</code> Key for the default encoding */
+    public static final String CONTEXT_DEFAULT_ENCODING = "default-encoding";
+
+
+    /**
+     * Should descriptors be reloaded?
+     *
+     * FIXME(GP): Isn't this Action specific only?
+     */
+    public static final boolean DESCRIPTOR_RELOADABLE_DEFAULT = true;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/InvalidPipelineException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/InvalidPipelineException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/InvalidPipelineException.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineException.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineProcessingException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineProcessingException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/PipelineProcessingException.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/ProcessingPipeline.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/ProcessingPipeline.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/ProcessingPipeline.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipeline.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipeline.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipeline.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/AbstractEnvironment.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/AbstractEnvironment.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,288 @@
+/*
+ * 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.butterfly.environment;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.butterfly.Constants;
+import org.apache.butterfly.util.BufferedOutputStream;
+import org.apache.commons.collections.iterators.IteratorEnumeration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Base class for any environment
+ *
+ * @author <a href="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
+ * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: AbstractEnvironment.java,v 1.24 2004/06/25 15:36:38 cziegeler Exp $
+ */
+public abstract class AbstractEnvironment 
+    implements Environment {
+
+    /** The logger */
+    protected static final Log logger = LogFactory.getLog(AbstractEnvironment.class);
+
+    /** The current uri in progress */
+    protected String uri;
+
+    /** The prefix */
+    protected String prefix = "";
+    
+    /** The View requested */
+    protected String view;
+
+    /** The Action requested */
+    protected String action;
+
+    /** The object model */
+    protected Map objectModel = new HashMap();
+
+    /** The attributes */
+    private Map attributes = new HashMap();
+
+    /** The secure Output Stream */
+    protected BufferedOutputStream secureOutputStream;
+
+    /** The real output stream */
+    protected OutputStream outputStream;
+
+    /**
+     * Constructs the abstract environment
+     */
+    public AbstractEnvironment(String uri, String view) {
+        this(uri, view, null);
+    }
+
+    /**
+     * Constructs the abstract environment
+     */
+    public AbstractEnvironment(String uri, String view, String action) {
+        this.uri = uri;
+        this.view = view;
+        this.action = action;
+    }
+    
+    /**
+     * Allow implementations to set view later than in super() constructor.
+     * View can be set only once, and should be set in implementation's constructor.
+     */
+    protected void setView(String view) {
+        if (this.view != null) {
+            throw new IllegalStateException("View was already set on this environment");
+        }
+        this.view = view;
+    }
+
+    /**
+     * Allow implementations to set action later than in super() constructor
+     * Action can be set only once, and should be set in implementation's constructor.
+     */
+    protected void setAction(String action) {
+        if (this.action != null) {
+            throw new IllegalStateException("Action was already set on this environment");
+        }
+        this.action = action;
+    }
+
+    /**
+     * Helper method to extract the view name from the request.
+     */
+    protected static String extractView(Request request) {
+        return request.getParameter(Constants.VIEW_PARAM);
+    }
+
+    /**
+     * Helper method to extract the action name from the request.
+     */
+    protected static String extractAction(Request req) {
+        String action = req.getParameter(Constants.ACTION_PARAM);
+        if (action != null) {
+            /* TC: still support the deprecated syntax */
+            return action;
+        } else {
+            for(Enumeration e = req.getParameterNames(); e.hasMoreElements(); ) {
+                String name = (String)e.nextElement();
+                if (name.startsWith(Constants.ACTION_PARAM_PREFIX)) {
+                    if (name.endsWith(".x") || name.endsWith(".y")) {
+                        return name.substring(Constants.ACTION_PARAM_PREFIX.length(),name.length()-2);
+                    } else {
+                        return name.substring(Constants.ACTION_PARAM_PREFIX.length());
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURI()
+     */
+    public String getURI() {
+        return this.uri;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURIPrefix()
+     */
+    public String getURIPrefix() {
+        return this.prefix;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setURI(java.lang.String)
+     */
+    public void setURI(String prefix, String value) {
+        this.prefix = prefix;
+        this.uri = value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getView()
+     */
+    public String getView() {
+        return this.view;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAction()
+     */
+    public String getAction() {
+        return this.action;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setStatus(int)
+     */
+    public void setStatus(int statusCode) {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getObjectModel()
+     */
+    public Map getObjectModel() {
+        return this.objectModel;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isResponseModified(long)
+     */
+    public boolean isResponseModified(long lastModified) {
+        return true; // always modified
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setResponseIsNotModified()
+     */
+    public void setResponseIsNotModified() {
+        // does nothing
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.attributes.put(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.attributes.remove(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return new IteratorEnumeration(this.attributes.keySet().iterator());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getOutputStream(int)
+     */
+    public OutputStream getOutputStream(int bufferSize) {
+        if (bufferSize == -1) {
+            if (this.secureOutputStream == null) {
+                this.secureOutputStream = new BufferedOutputStream(this.outputStream);
+            }
+            return this.secureOutputStream;
+        } else if (bufferSize == 0) {
+            return this.outputStream;
+        } else {
+            this.outputStream = new java.io.BufferedOutputStream(this.outputStream, bufferSize);
+            return this.outputStream;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#tryResetResponse()
+     */
+    public boolean tryResetResponse()
+    throws IOException {
+        if (this.secureOutputStream != null) {
+            this.secureOutputStream.clearBuffer();
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#commitResponse()
+     */
+    public void commitResponse()
+    throws IOException {
+        if (this.secureOutputStream != null) {
+            this.secureOutputStream.realFlush();
+        } else if ( this.outputStream != null ){
+            this.outputStream.flush();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#startingProcessing()
+     */
+    public void startingProcessing() {
+        // do nothing here
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#finishingProcessing()
+     */
+    public void finishingProcessing() {
+        // do nothing here
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isInternRedirect()
+     */
+    public boolean isInternalRedirect() {
+        return false;
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Context.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Context.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,50 @@
+/*
+ * 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.butterfly.environment;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.io.InputStream;
+
+/**
+ * Defines an interface to provide client context information .
+ *
+ * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
+ * @version CVS $Id: Context.java,v 1.2 2004/03/05 13:02:54 bdelacretaz Exp $
+ *
+ */
+
+public interface Context {
+
+    Object getAttribute(String name);
+
+    void setAttribute(String name, Object value);
+
+    void removeAttribute(String name);
+
+    Enumeration getAttributeNames();
+
+    URL getResource(String path) throws MalformedURLException;
+
+    String getRealPath(String path);
+
+    String getMimeType(String file);
+
+    String getInitParameter(String name);
+
+    InputStream getResourceAsStream(String path);
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Cookie.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Cookie.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,363 @@
+/*
+ * 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.butterfly.environment;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link Response#addCookie(Cookie)} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link Request#getCookies()} method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: Cookie.java,v 1.4 2004/03/05 13:02:54 bdelacretaz Exp $
+ *
+ */
+
+public interface Cookie {
+
+    /**
+     *
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie
+     * to the user. Comments
+     * are not supported by Netscape Version 0 cookies.
+     *
+     * @param purpose		a <code>String</code> specifying the comment
+     *				to display to the user
+     *
+     * @see #getComment()
+     *
+     */
+
+    void setComment(String purpose);
+
+
+
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * <code>null</code> if the cookie has no comment.
+     *
+     * @return			a <code>String</code> containing the comment,
+     *				or <code>null</code> if none
+     *
+     * @see #setComment(String)
+     *
+     */
+
+    String getComment();
+
+
+
+
+    /**
+     *
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p>The form of the domain name is specified by RFC 2109. A domain
+     * name begins with a dot (<code>.foo.com</code>) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, <code>www.foo.com</code>, but not
+     * <code>a.b.foo.com</code>). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     *
+     * @param pattern		a <code>String</code> containing the domain name
+     *				within which this cookie is visible;
+     *				form is according to RFC 2109
+     *
+     * @see #getDomain()
+     *
+     */
+
+    void setDomain(String pattern);
+
+
+
+
+
+    /**
+     * Returns the domain name set for this cookie. The form of
+     * the domain name is set by RFC 2109.
+     *
+     * @return			a <code>String</code> containing the domain name
+     *
+     * @see #setDomain(String)
+     *
+     */
+
+    String getDomain();
+
+
+
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p>A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p>A negative value means
+     * that the cookie is not stored persistently and will be deleted
+     * when the Web browser exits. A zero value causes the cookie
+     * to be deleted.
+     *
+     * @param expiry		an integer specifying the maximum age of the
+     * 				cookie in seconds; if negative, means
+     *				the cookie is not stored; if zero, deletes
+     *				the cookie
+     *
+     *
+     * @see #getMaxAge()
+     *
+     */
+
+    void setMaxAge(int expiry);
+
+
+
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds,
+     * By default, <code>-1</code> indicating the cookie will persist
+     * until browser shutdown.
+     *
+     *
+     * @return			an integer specifying the maximum age of the
+     *				cookie in seconds; if negative, means
+     *				the cookie persists until browser shutdown
+     *
+     *
+     * @see #setMaxAge(int)
+     *
+     */
+
+    int getMaxAge();
+
+
+
+
+    /**
+     * Specifies a path for the cookie
+     * to which the client should return the cookie.
+     *
+     * <p>The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories.
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p>Consult RFC 2109 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     *
+     * @param uri		a <code>String</code> specifying a path
+     *
+     *
+     * @see #getPath()
+     *
+     */
+
+    void setPath(String uri);
+
+
+
+
+    /**
+     * Returns the path on the server
+     * to which the browser returns this cookie. The
+     * cookie is visible to all subpaths on the server.
+     *
+     *
+     * @return		a <code>String</code> specifying a path that contains
+     *			a servlet name, for example, <i>/catalog</i>
+     *
+     * @see #setPath(String)
+     *
+     */
+
+    String getPath();
+
+
+
+
+
+    /**
+     * Indicates to the browser whether the cookie should only be sent
+     * using a secure protocol, such as HTTPS or SSL.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @param flag	if <code>true</code>, sends the cookie from the browser
+     *			to the server using only when using a secure protocol;
+     *			if <code>false</code>, sent on any protocol
+     *
+     * @see #getSecure()
+     *
+     */
+
+    void setSecure(boolean flag);
+
+
+
+
+    /**
+     * Returns <code>true</code> if the browser is sending cookies
+     * only over a secure protocol, or <code>false</code> if the
+     * browser can send cookies using any protocol.
+     *
+     * @return		<code>true</code> if the browser can use
+     *			any standard protocol; otherwise, <code>false</code>
+     *
+     * @see #setSecure(boolean)
+     *
+     */
+
+    boolean getSecure();
+
+
+
+
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return		a <code>String</code> specifying the cookie's name
+     *
+     */
+
+    String getName();
+
+
+
+
+
+    /**
+     *
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p>With Version 0 cookies, values should not contain white
+     * space, brackets, parentheses, equals signs, commas,
+     * double quotes, slashes, question marks, at signs, colons,
+     * and semicolons. Empty values may not behave the same way
+     * on all browsers.
+     *
+     * @param newValue		a <code>String</code> specifying the new value
+     *
+     *
+     * @see #getValue()
+     * @see Cookie
+     *
+     */
+
+    void setValue(String newValue);
+
+
+
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return			a <code>String</code> containing the cookie's
+     *				present value
+     *
+     * @see #setValue(String)
+     * @see Cookie
+     *
+     */
+
+    String getValue();
+
+
+
+
+    /**
+     * Returns the version of the protocol this cookie complies
+     * with. Version 1 complies with RFC 2109,
+     * and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided
+     * by a browser use and identify the browser's cookie version.
+     *
+     *
+     * @return			0 if the cookie complies with the
+     *				original Netscape specification; 1
+     *				if the cookie complies with RFC 2109
+     *
+     * @see #setVersion(int)
+     *
+     */
+
+    int getVersion();
+
+
+
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2109.
+     *
+     * <p>Since RFC 2109 is still somewhat new, consider
+     * version 1 as experimental; do not use it yet on production sites.
+     *
+     *
+     * @param v			0 if the cookie should comply with
+     *				the original Netscape specification;
+     *				1 if the cookie should comply with RFC 2109
+     *
+     * @see #getVersion()
+     *
+     */
+
+    void setVersion(int v);
+
+
+
+}
+

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Environment.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Environment.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Environment.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/EnvironmentException.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/EnvironmentException.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,59 @@
+/*
+ * 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.butterfly.environment;
+
+
+/**
+ * Description of EnvironmentException.
+ * 
+ * @version CVS $Id$
+ */
+public class EnvironmentException extends RuntimeException {
+
+    /**
+     * 
+     */
+    public EnvironmentException() {
+        super();
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param arg0
+     */
+    public EnvironmentException(String arg0) {
+        super(arg0);
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param arg0
+     * @param arg1
+     */
+    public EnvironmentException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param arg0
+     */
+    public EnvironmentException(Throwable arg0) {
+        super(arg0);
+        // TODO Auto-generated constructor stub
+    }
+
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/ObjectModelHelper.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/ObjectModelHelper.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,84 @@
+/*
+ * 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.butterfly.environment;
+
+import java.util.Map;
+
+/**
+ * A set of constants and methods to access the content of the object model.
+ * <p>
+ * The object model is a <code>Map</code> used to pass information about the
+ * calling environment to the sitemap and its components (matchers, actions,
+ * transformers, etc).
+ * <p>
+ * This class provides accessors only for the objects in the object model that are
+ * common to every environment and which can thus be used safely. Some environments
+ * provide additional objects, but they are not described here and accessing them
+ * should be done in due cause since this ties the application to that particular
+ * environment.
+ *
+ * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @version CVS $Id: ObjectModelHelper.java,v 1.5 2004/03/05 13:02:54 bdelacretaz Exp $
+ */
+
+public final class ObjectModelHelper {
+
+    /** Key for the environment {@link Request} in the object model. */
+    public final static String REQUEST_OBJECT  = "request";
+
+    /** Key for the environment {@link Response} in the object model. */
+    public final static String RESPONSE_OBJECT = "response";
+
+    /** Key for the environment {@link Context} in the object model. */
+    public final static String CONTEXT_OBJECT  = "context";
+
+    /** Key for the expiration value (Long) in the object model. */
+    public final static String EXPIRES_OBJECT  = "expires";
+    
+    /** Key for the throwable object, only available within a &lt;map:handle-errors>. */
+    public final static String THROWABLE_OBJECT = "throwable";
+
+    /**
+     * Key for a {@link Map} containing information from
+     * a parent request provided to a sub-request (internal processing)
+     */
+    public final static String PARENT_CONTEXT = "parent-context";
+
+
+    private ObjectModelHelper() {
+        // Forbid instantiation
+    }
+
+    public static final Request getRequest(Map objectModel) {
+        return (Request)objectModel.get(REQUEST_OBJECT);
+    }
+
+    public static final Response getResponse(Map objectModel) {
+        return (Response)objectModel.get(RESPONSE_OBJECT);
+    }
+
+    public static final Context getContext(Map objectModel) {
+        return (Context)objectModel.get(CONTEXT_OBJECT);
+    }
+
+    public static final Long getExpires(Map objectModel) {
+        return (Long)objectModel.get(EXPIRES_OBJECT);
+    }
+    
+    public static final Throwable getThrowable(Map objectModel) {
+        return (Throwable)objectModel.get(THROWABLE_OBJECT);
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Request.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Request.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,918 @@
+/*
+ * 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.butterfly.environment;
+
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Defines an interface to provide client request information .
+ *
+ * A client can bind an object attribute into a <code>Request</code> by name.
+ * The <code>Request</code> interface defines two scopes for storing objects:
+ * <ul>
+ * <li><code>GLOBAL_SCOPE</code>
+ * <li><code>REQUEST_SCOPE</code>
+ * </ul>
+ * All objects stored in the request using the <code>GLOBAL_SCOPE</code> 
+ * are available to all sub requests and the main request associatiated
+ * Objects stored in the request using the <code>REQUEST_SCOPE</code> are
+ * only available for the current (sub) request.
+ * 
+ * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
+ * @version CVS $Id: Request.java,v 1.11 2004/07/12 13:27:57 cziegeler Exp $
+ *
+ */
+
+public interface Request {
+
+    /**
+     * This constant defines an request wide scope for the request attribute.
+     * @since 2.2
+     */
+    public static final int GLOBAL_SCOPE = 1;
+
+    /**
+     * This constant defines the scope of the request attribute to be
+     * private to the current (sub) request. 
+     * @since 2.2
+     */
+    public static final int REQUEST_SCOPE = 2;
+
+    /**
+     *
+     * Returns the value of the named parameter as an <code>Object</code>,
+     * or <code>null</code> if no parameter of the given name exists.
+     * Basically, this method is similar to {@link #getParameter(String)},
+     * but it returns an object instead. 
+     * This is useful when special processing has been made on these parameters,
+     * for example for file uploads. In this case you get an object 
+     * representing the uploaded file.
+     * If the parameters have not been processed, you either get a String
+     * object if the parameter has one value, or a Collection of Strings
+     * if the parameter has more than one value.
+     * 
+     * @param name        a <code>String</code> specifying the name of
+     *                        the parameter
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the parameter, or <code>null</code> if
+     *                        the parameter does not exist
+     *
+     */
+    Object get(String name);
+
+    /**
+     *
+     * Returns the value of the named attribute from the <code>GLOBAL_SCOPE</code>
+     * as an <code>Object</code>, or <code>null</code> if no attribute 
+     * of the given name exists.
+     *
+     * @param name        a <code>String</code> specifying the name of
+     *                        the attribute
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the attribute, or <code>null</code> if
+     *                        the attribute does not exist
+     *
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * names of the attributes available to this request in the  <code>GLOBAL_SCOPE</code>.
+     * This method returns an empty <code>Enumeration</code>
+     * if the request has no attributes available to it.
+     *
+     *
+     * @return                an <code>Enumeration</code> of strings
+     *                        containing the names
+     *                         of the request's attributes
+     *
+     */
+    Enumeration getAttributeNames();
+
+    /**
+     *
+     * Stores an attribute in this request in the <code>GLOBAL_SCOPE</code>.
+     * Attributes are reset between requests.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute
+     *
+     * @param o                                the <code>Object</code> to be stored
+     *
+     */
+    void setAttribute(String name, Object o);
+
+    /**
+     *
+     * Removes an attribute from this request in the <code>GLOBAL_SCOPE</code>.  
+     * This method is not
+     * generally needed as attributes only persist as long as the request
+     * is being handled.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute to remove
+     *
+     */
+    void removeAttribute(String name);
+
+    /**
+     * Returns the value of the named attribute from the scope
+     * as an <code>Object</code>, or <code>null</code> if no attribute 
+     * of the given name exists.
+     *
+     * @param name        a <code>String</code> specifying the name of
+     *                        the attribute
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the attribute, or <code>null</code> if
+     *                        the attribute does not exist
+     *
+     * @since 2.2
+     */
+    Object getAttribute(String name, int scope);
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * names of the attributes available to this request in the scope.
+     * This method returns an empty <code>Enumeration</code>
+     * if the request has no attributes available to it.
+     *
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @return                an <code>Enumeration</code> of strings
+     *                        containing the names
+     *                         of the request's attributes
+     *
+     * @since 2.2
+     */
+    Enumeration getAttributeNames(int scope);
+
+    /**
+     *
+     * Stores an attribute in this request in the scope.
+     * Attributes are reset between requests.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                    the name of the attribute    
+     * @param o                            the <code>Object</code> to be stored
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @since 2.2
+     */
+    void setAttribute(String name, Object o, int scope);
+
+    /**
+     * Removes an attribute from this request in the scope.  
+     * This method is not
+     * generally needed as attributes only persist as long as the request
+     * is being handled.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute to remove
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @since 2.2
+     */
+    void removeAttribute(String name, int scope);
+
+    /**
+     *
+     * Returns the name of the authentication scheme used to protect
+     * the servlet, for example, "BASIC" or "SSL," or null if the servlet was
+     * not protected
+     *
+     * @return                The name of the authentication scheme used to
+     *                        protect the servlet, or null if the servlet was
+     *                        not protected
+     */
+    String getAuthType();
+
+    /**
+     * Returns the name of the character encoding used in the body of this
+     * request. This method returns <code>null</code> if the request
+     * does not specify a character encoding
+     *
+     *
+     * @return                a <code>String</code> containing the name of
+     *                        the chararacter encoding, or <code>null</code>
+     *                        if the request does not specify a character encoding
+     *
+     */
+
+    String getCharacterEncoding();
+
+     /**
+     * Overrides the charactor encoding of parameters.
+     *
+     * @throws java.io.UnsupportedEncodingException if this is not a valid encoding.
+     */
+
+    void setCharacterEncoding(String enc) throws java.io.UnsupportedEncodingException;
+
+    /**
+     * Returns the length, in bytes, of the request body
+     *
+     * @return                an integer containing the length of the
+     *                         request body or -1 if the length is not known
+     *
+     */
+
+    int getContentLength();
+
+    /**
+     * Returns the MIME type of the body of the request
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the MIME type of
+     *                         the request, or -1 if the type is not known
+     *
+     */
+
+    String getContentType();
+
+    /**
+     * Returns the value of a request parameter as a <code>String</code>,
+     *
+     * @param name         a <code>String</code> specifying the
+     *                        name of the parameter
+     *
+     * @return                a <code>String</code> representing the
+     *                        single value of the parameter
+     *
+     * @see                 #getParameterValues(String)
+     *
+     */
+
+    String getParameter(String name);
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code>
+     * objects containing the names of the parameters contained
+     * in this request. If the request has
+     * no parameters, the method returns an
+     * empty <code>Enumeration</code>.
+     *
+     * @return                an <code>Enumeration</code> of <code>String</code>
+     *                        objects, each <code>String</code> containing
+     *                         the name of a request parameter; or an
+     *                        empty <code>Enumeration</code> if the
+     *                        request has no parameters
+     *
+     */
+
+    Enumeration getParameterNames();
+
+    /**
+     * Returns an array of <code>String</code> objects containing
+     * all of the values the given request parameter has, or
+     * <code>null</code> if the parameter does not exist.
+     *
+     * <p>If the parameter has a single value, the array has a length
+     * of 1.
+     *
+     * @param name        a <code>String</code> containing the name of
+     *                        the parameter whose value is requested
+     *
+     * @return                an array of <code>String</code> objects
+     *                        containing the parameter's values
+     *
+     * @see                #getParameter(String)
+     *
+     */
+
+    String[] getParameterValues(String name);
+
+
+    /**
+     * Returns the name and version of the protocol the request uses
+     * in the form <i>protocol/majorVersion.minorVersion</i>, for
+     * example, HTTP/1.1. For HTTP servlets, the value
+     * returned is the same as the value of the CGI variable
+     * <code>SERVER_PROTOCOL</code>.
+     *
+     * @return                a <code>String</code> containing the protocol
+     *                        name and version number
+     *
+     */
+
+    String getProtocol();
+
+    /**
+     * Returns the name of the scheme used to make this request,
+     * for example,
+     * <code>http</code>, <code>https</code>, or <code>ftp</code>.
+     * Different schemes have different rules for constructing URLs,
+     * as noted in RFC 1738.
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the scheme used to make this request
+     *
+     */
+
+    String getScheme();
+
+    /**
+     * Returns the host name of the server that received the request.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_NAME</code>.
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the server to which the request was sent
+     */
+
+    String getServerName();
+
+    /**
+     * Returns the port number on which this request was received.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_PORT</code>.
+     *
+     * @return                an integer specifying the port number
+     *
+     */
+
+    int getServerPort();
+
+    /**
+     * Returns the Internet Protocol (IP) address of the client
+     * that sent the request.  For HTTP servlets, same as the value of the
+     * CGI variable <code>REMOTE_ADDR</code>.
+     *
+     * @return                a <code>String</code> containing the
+     *                        IP address of the client that sent the request
+     *
+     */
+
+    String getRemoteAddr();
+
+    /**
+     * Returns the fully qualified name of the client that sent the
+     * request, or the IP address of the client if the name cannot be
+     * determined. For HTTP servlets, same as the value of the CGI variable
+     * <code>REMOTE_HOST</code>.
+     *
+     * @return                a <code>String</code> containing the fully qualified name
+     *                        of the client
+     *
+     */
+
+    String getRemoteHost();
+
+    /**
+     *
+     * Returns the preferred <code>Locale</code> that the client will
+     * accept content in, based on the Accept-Language header.
+     * If the client request doesn't provide an Accept-Language header,
+     * this method returns the default locale for the server.
+     *
+     *
+     * @return                the preferred <code>Locale</code> for the client
+     *
+     */
+
+    Locale getLocale();
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>Locale</code> objects
+     * indicating, in decreasing order starting with the preferred locale, the
+     * locales that are acceptable to the client based on the Accept-Language
+     * header.
+     * If the client request doesn't provide an Accept-Language header,
+     * this method returns an <code>Enumeration</code> containing one
+     * <code>Locale</code>, the default locale for the server.
+     *
+     *
+     * @return                an <code>Enumeration</code> of preferred
+     *                  <code>Locale</code> objects for the client
+     *
+     */
+
+    Enumeration getLocales();
+
+    /**
+     *
+     * Returns a boolean indicating whether this request was made using a
+     * secure channel, such as HTTPS.
+     *
+     *
+     * @return                a boolean indicating if the request was made using a
+     *                  secure channel
+     *
+     */
+
+    boolean isSecure();
+
+    /**
+     *
+     * Returns an array containing all of the <code>Cookie</code>
+     * objects the client sent with this request.
+     * This method returns <code>null</code> if no cookies were sent.
+     *
+     * @return                an array of all the <code>Cookies</code>
+     *                        included with this request, or <code>null</code>
+     *                        if the request has no cookies
+     *
+     *
+     */
+
+    Cookie[] getCookies();
+
+    /**
+     * Returns a map of the <code>Cookie</code> objects the client sent
+     * with this request, indexed by name. This method returns an empty
+     * map if no cookies were sent.
+     *
+     * @return a Map of <code>Cookie</code> objects
+     */
+    Map getCookieMap();
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>long</code> value that represents a
+     * <code>Date</code> object. Use this method with
+     * headers that contain dates, such as
+     * <code>If-Modified-Since</code>.
+     *
+     * <p>The date is returned as
+     * the number of milliseconds since January 1, 1970 GMT.
+     * The header name is case insensitive.
+     *
+     * <p>If the request did not have a header of the
+     * specified name, this method returns -1. If the header
+     * can't be converted to a date, the method throws
+     * an <code>IllegalArgumentException</code>.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                name of the header
+     *
+     * @return                        a <code>long</code> value
+     *                                representing the date specified
+     *                                in the header expressed as
+     *                                the number of milliseconds
+     *                                since January 1, 1970 GMT,
+     *                                or -1 if the named header
+     *                                was not included with the
+     *                                reqest
+     *
+     * @exception        IllegalArgumentException        If the header value
+     *                                                        can't be converted
+     *                                                        to a date
+     *
+     */
+
+    long getDateHeader(String name);
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>String</code>. If the request did not include a header
+     * of the specified name, this method returns <code>null</code>.
+     * The header name is case insensitive. You can use
+     * this method with any request header.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                header name
+     *
+     * @return                        a <code>String</code> containing the
+     *                                value of the requested
+     *                                header, or <code>null</code>
+     *                                if the request does not
+     *                                have a header of that name
+     *
+     */
+
+    String getHeader(String name);
+
+    /**
+     *
+     * Returns all the values of the specified request header
+     * as an <code>Enumeration</code> of <code>String</code> objects.
+     *
+     * <p>Some headers, such as <code>Accept-Language</code> can be sent
+     * by clients as several headers each with a different value rather than
+     * sending the header as a comma separated list.
+     *
+     * <p>If the request did not include any headers
+     * of the specified name, this method returns an empty
+     * <code>Enumeration</code>.
+     * The header name is case insensitive. You can use
+     * this method with any request header.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                header name
+     *
+     * @return                        a <code>Enumeration</code> containing the
+     *                                values of the requested
+     *                                header, or <code>null</code>
+     *                                if the request does not
+     *                                have any headers of that name
+     *
+     */
+
+    Enumeration getHeaders(String name);
+
+    /**
+     *
+     * Returns an enumeration of all the header names
+     * this request contains. If the request has no
+     * headers, this method returns an empty enumeration.
+     *
+     * <p>Some servlet containers do not allow do not allow
+     * servlets to access headers using this method, in
+     * which case this method returns <code>null</code>
+     *
+     * @return                        an enumeration of all the
+     *                                header names sent with this
+     *                                request; if the request has
+     *                                no headers, an empty enumeration;
+     *                                if the servlet container does not
+     *                                allow servlets to use this method,
+     *                                <code>null</code>
+     *
+     */
+
+    Enumeration getHeaderNames();
+
+    /**
+     *
+     * Returns the name of the HTTP method with which this
+     * request was made, for example, GET, POST, or PUT.
+     * Same as the value of the CGI variable REQUEST_METHOD.
+     *
+     * @return                        a <code>String</code>
+     *                                specifying the name
+     *                                of the method with which
+     *                                this request was made
+     *
+     */
+
+    String getMethod();
+
+    /**
+     *
+     * Returns any extra path information associated with
+     * the URL the client sent when it made this request.
+     * The extra path information follows the servlet path
+     * but precedes the query string.
+     * This method returns <code>null</code> if there
+     * was no extra path information.
+     *
+     * <p>Same as the value of the CGI variable PATH_INFO.
+     *
+     *
+     * @return                a <code>String</code> specifying
+     *                        extra path information that comes
+     *                        after the servlet path but before
+     *                        the query string in the request URL;
+     *                        or <code>null</code> if the URL does not have
+     *                        any extra path information
+     *
+     */
+
+    String getPathInfo();
+
+    /**
+     *
+     * Returns any extra path information after the servlet name
+     * but before the query string, and translates it to a real
+     * path. Same as the value of the CGI variable PATH_TRANSLATED.
+     *
+     * <p>If the URL does not have any extra path information,
+     * this method returns <code>null</code>.
+     *
+     *
+     * @return                a <code>String</code> specifying the
+     *                        real path, or <code>null</code> if
+     *                        the URL does not have any extra path
+     *                        information
+     *
+     *
+     */
+
+    String getPathTranslated();
+
+    /**
+     *
+     * Returns the portion of the request URI that indicates the context
+     * of the request.  The context path always comes first in a request
+     * URI.  The path starts with a "/" character but does not end with a "/"
+     * character.  For servlets in the default (root) context, this method
+     * returns "".
+     *
+     *
+     * @return                a <code>String</code> specifying the
+     *                        portion of the request URI that indicates the context
+     *                        of the request
+     *
+     *
+     */
+
+    String getContextPath();
+
+    /**
+     *
+     * Returns the query string that is contained in the request
+     * URL after the path. This method returns <code>null</code>
+     * if the URL does not have a query string. Same as the value
+     * of the CGI variable QUERY_STRING.
+     *
+     * @return                a <code>String</code> containing the query
+     *                        string or <code>null</code> if the URL
+     *                        contains no query string
+     *
+     */
+
+    String getQueryString();
+
+    /**
+     *
+     * Returns the login of the user making this request, if the
+     * user has been authenticated, or <code>null</code> if the user
+     * has not been authenticated.
+     * Whether the user name is sent with each subsequent request
+     * depends on the browser and type of authentication. Same as the
+     * value of the CGI variable REMOTE_USER.
+     *
+     * @return                a <code>String</code> specifying the login
+     *                        of the user making this request, or <code>null</code
+     *                        if the user login is not known
+     *
+     */
+
+    String getRemoteUser();
+
+    /**
+     *
+     * Returns the login of the user making this request, if the
+     * user has been authenticated, or <code>null</code> if the user
+     * has not been authenticated.
+     * Whether the user name is sent with each subsequent request
+     * depends on the browser and type of authentication. Same as the
+     * value of the CGI variable REMOTE_USER.
+     *
+     * @return                a <code>String</code> specifying the login
+     *                        of the user making this request, or <code>null</code
+     *                        if the user login is not known
+     *
+     */
+
+    Principal getUserPrincipal();
+
+    /**
+     *
+     * Checks whether the currently logged in user is in a specified role.
+     *
+     * @return                        <code>true</code> if the user is
+     *                                authenticated and in the role;
+     *                                otherwise, <code>false</code>
+     *
+     *
+     * @see                        #getRemoteUser()
+     *
+     */
+
+    boolean isUserInRole(String role);
+
+    /**
+     *
+     * Returns the session ID specified by the client. This may
+     * not be the same as the ID of the actual session in use.
+     * For example, if the request specified an old (expired)
+     * session ID and the server has started a new session, this
+     * method gets a new session with a new ID. If the request
+     * did not specify a session ID, this method returns
+     * <code>null</code>.
+     *
+     *
+     * @return                a <code>String</code> specifying the session
+     *                        ID, or <code>null</code> if the request did
+     *                        not specify a session ID
+     *
+     * @see                #isRequestedSessionIdValid()
+     *
+     */
+
+    String getRequestedSessionId();
+
+    /**
+     *
+     * Returns the part of this request's URL from the protocol
+     * name up to the query string in the first line of the HTTP request.
+     * For example:
+     *
+     * <blockquote>
+     * <table>
+     * <tr align=left><th>First line of HTTP request<th>
+     * <th>Returned Value
+     * <tr><td>POST /some/path.html HTTP/1.1<td><td>/some/path.html
+     * <tr><td>GET http://foo.bar/a.html HTTP/1.0
+     * <td><td>http://foo.bar/a.html
+     * <tr><td>HEAD /xyz?a=b HTTP/1.1<td><td>/xyz
+     * </table>
+     * </blockquote>
+     * 
+     * For internal requests, this method returns
+     * the information for the original/external request!
+     *
+     * @return                a <code>String</code> containing
+     *                        the part of the URL from the
+     *                        protocol name up to the query string
+     */
+    String getRequestURI();
+
+    /**
+     * <p>
+     * Returns the URI of the requested resource as interpreted by the sitemap.
+     * For example, if your webapp is mounted at "/webapp" and the HTTP request
+     * is for "/webapp/foo", this method returns "foo". Consequently, if the
+     * request is for "/webapp", this method returns an empty string.
+     * </p>
+     * <p>
+     * Note that if the request is mapped to a pipeline that contains
+     * aggregated content, and if this method is called in the context of
+     * one of the aggregated parts (e.g. a server page), this method will
+     * return the URI of the aggregated part, not the original requested URI.
+     * </p>
+     *
+     * @return a <code>String</code> containing the URL as mangled by the
+     *         sitemap
+     */
+    String getSitemapURI();
+
+    /**
+     * <p>
+     * Returns the path to the sitemap of the requested resource as interpreted 
+     * by the sitemap.
+     * For example, if your webapp is mounted at "webapp" and the HTTP request
+     * is for "webapp/foo", this method returns "webapp/". Consequently, if the
+     * request is for "foo", this method returns the empty string.
+     * </p>
+     *
+     * @return a <code>String</code> containing the path to the sitemap
+     * @since 2.2
+     */
+    String getSitemapPath();
+    
+    /**
+     *
+     * Returns the part of this request's URL that calls
+     * the servlet. This includes either the servlet name or
+     * a path to the servlet, but does not include any extra
+     * path information or a query string. Same as the value
+     * of the CGI variable SCRIPT_NAME.
+     *
+     *
+     * @return                a <code>String</code> containing
+     *                        the name or path of the servlet being
+     *                        called, as specified in the request URL
+     *
+     *
+     */
+
+    String getServletPath();
+
+    /**
+     *
+     * Returns the current <code>Session</code>
+     * associated with this request or, if if there is no
+     * current session and <code>create</code> is true, returns
+     * a new session.
+     *
+     * <p>If <code>create</code> is <code>false</code>
+     * and the request has no valid <code>Session</code>,
+     * this method returns <code>null</code>.
+     *
+     * <p>To make sure the session is properly maintained,
+     * you must call this method before
+     * the response is committed.
+     *
+     *
+     *
+     *
+     * @param create          <code>true</code> to create
+     *                        a new session for this request if necessary;
+     *                        <code>false</code> to return <code>null</code>
+     *                        if there's no current session
+     *
+     *
+     * @return                 the <code>Session</code> associated
+     *                        with this request or <code>null</code> if
+     *                         <code>create</code> is <code>false</code>
+     *                        and the request has no valid session
+     *
+     * @see        #getSession()
+     *
+     *
+     */
+
+    Session getSession(boolean create);
+
+    /**
+     *
+     * Returns the current session associated with this request,
+     * or if the request does not have a session, creates one.
+     *
+     * @return                the <code>Session</code> associated
+     *                        with this request
+     *
+     * @see        #getSession(boolean)
+     *
+     */
+
+     Session getSession();
+
+    /**
+     *
+     * Checks whether the requested session ID is still valid.
+     *
+     * @return                        <code>true</code> if this
+     *                                request has an id for a valid session
+     *                                in the current session context;
+     *                                <code>false</code> otherwise
+     *
+     * @see                        #getRequestedSessionId()
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdValid();
+
+    /**
+     *
+     * Checks whether the requested session ID came in as a cookie.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as a
+     *                                cookie; otherwise, <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdFromCookie();
+
+    /**
+     *
+     * Checks whether the requested session ID came in as part of the
+     * request URL.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as part of a URL; otherwise,
+     *                                <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdFromURL();
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Response.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Response.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,234 @@
+/*
+ * 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.butterfly.environment;
+
+import java.util.Locale;
+
+/**
+ * Defines an interface to provide client response information .
+ *
+ * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: Response.java,v 1.3 2004/03/05 13:02:54 bdelacretaz Exp $
+ *
+ */
+
+public interface Response {
+
+    /**
+     * Returns the name of the charset used for
+     * the MIME body sent in this response.
+     *
+     * <p>If no charset has been assigned, it is implicitly
+     * set to <code>ISO-8859-1</code> (<code>Latin-1</code>).
+     *
+     * <p>See RFC 2047 (http://ds.internic.net/rfc/rfc2045.txt)
+     * for more information about character encoding and MIME.
+     *
+     * @return                a <code>String</code> specifying the
+     *                        name of the charset, for
+     *                        example, <code>ISO-8859-1</code>
+     *
+     */
+
+    String getCharacterEncoding();
+
+    /**
+     * Sets the locale of the response, setting the headers (including the
+     * Content-Type's charset) as appropriate.  By default, the response locale
+     * is the default locale for the server.
+     *
+     * @param loc  the locale of the response
+     *
+     * @see                 #getLocale()
+     *
+     */
+
+    void setLocale(Locale loc);
+
+    /**
+     * Returns the locale assigned to the response.
+     *
+     *
+     * @see                 #setLocale(Locale)
+     *
+     */
+
+    Locale getLocale();
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p>The name must conform to RFC 2109. That means it can contain
+     * only ASCII alphanumeric characters and cannot contain commas,
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p>The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * <code>setValue</code> method.
+     *
+     * <p>By default, cookies are created according to the Netscape
+     * cookie specification. The version can be changed with the
+     * <code>setVersion</code> method.
+     *
+     *
+     * @param name                         a <code>String</code> specifying the name of the cookie
+     *
+     * @param value                        a <code>String</code> specifying the value of the cookie
+     *
+     * @throws IllegalArgumentException        if the cookie name contains illegal characters
+     *                                        (for example, a comma, space, or semicolon)
+     *                                        or it is one of the tokens reserved for use
+     *                                        by the cookie protocol
+     *
+     */
+    Cookie createCookie(String name, String value);
+
+    /**
+     * Adds the specified cookie to the response.  This method can be called
+     * multiple times to set more than one cookie.
+     *
+     * @param cookie the Cookie to return to the client
+     *
+     */
+
+    void addCookie(Cookie cookie);
+
+    /**
+     * Returns a boolean indicating whether the named response header
+     * has already been set.
+     *
+     * @param        name        the header name
+     * @return                <code>true</code> if the named response header
+     *                        has already been set;
+     *                         <code>false</code> otherwise
+     */
+
+    boolean containsHeader(String name);
+
+    /**
+     * Encodes the specified URL by including the session ID in it,
+     * or, if encoding is not needed, returns the URL unchanged.
+     * The implementation of this method includes the logic to
+     * determine whether the session ID needs to be encoded in the URL.
+     * For example, if the browser supports cookies, or session
+     * tracking is turned off, URL encoding is unnecessary.
+     *
+     * <p>For robust session tracking, all URLs emitted by a servlet
+     * should be run through this
+     * method.  Otherwise, URL rewriting cannot be used with browsers
+     * which do not support cookies.
+     *
+     * @param        url        the url to be encoded.
+     * @return                the encoded URL if encoding is needed;
+     *                         the unchanged URL otherwise.
+     */
+
+    String encodeURL(String url);
+
+    /**
+     *
+     * Sets a response header with the given name and
+     * date-value.  The date is specified in terms of
+     * milliseconds since the epoch.  If the header had already
+     * been set, the new value overwrites the previous one.  The
+     * <code>containsHeader</code> method can be used to test for the
+     * presence of a header before setting its value.
+     *
+     * @param        name        the name of the header to set
+     * @param        date        the assigned date value
+     *
+     * @see #containsHeader(String)
+     * @see #addDateHeader(String, long)
+     */
+
+    void setDateHeader(String name, long date);
+
+    /**
+     *
+     * Adds a response header with the given name and
+     * date-value.  The date is specified in terms of
+     * milliseconds since the epoch.  This method allows response headers
+     * to have multiple values.
+     *
+     * @param        name        the name of the header to set
+     * @param        date        the additional date value
+     *
+     * @see #setDateHeader(String, long)
+     */
+
+    void addDateHeader(String name, long date);
+
+    /**
+     *
+     * Sets a response header with the given name and value.
+     * If the header had already been set, the new value overwrites the
+     * previous one.  The <code>containsHeader</code> method can be
+     * used to test for the presence of a header before setting its
+     * value.
+     *
+     * @param        name        the name of the header
+     * @param        value        the header value
+     *
+     * @see #containsHeader(String)
+     * @see #addHeader(String, String)
+     */
+
+    void setHeader(String name, String value);
+
+    /**
+     * Adds a response header with the given name and value.
+     * This method allows response headers to have multiple values.
+     *
+     * @param        name        the name of the header
+     * @param        value        the additional header value
+     *
+     * @see #setHeader(String, String)
+     */
+
+    void addHeader(String name, String value);
+
+    /**
+     * Sets a response header with the given name and
+     * int value. If the header had already
+     * been set, the new value overwrites the previous one.  The
+     * <code>containsHeader</code> method can be used to test for the
+     * presence of a header before setting its value.
+     *
+     * @param        name        the name of the header to set
+     * @param        value       the assigned int value
+     *
+     * @see #containsHeader(String)
+     * @see #addIntHeader(String, int)
+     */
+
+    void setIntHeader(String name, int value);
+
+    /**
+     * Adds a response header with the given name and
+     * int value. This method allows response headers
+     * to have multiple values.
+     *
+     * @param        name        the name of the header to set
+     * @param        value       the additional int value
+     *
+     * @see #setIntHeader(String, int)
+     */
+
+    void addIntHeader(String name, int value);
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Session.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/Session.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,229 @@
+/*
+ * 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.butterfly.environment;
+
+import java.util.Enumeration;
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>Cocoon uses this interface to create a session
+ * between a client and the "cocoon server". The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows Cocoon to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ *     the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ *     across multiple user connections
+ * </ul>
+ *
+ * <p>Session information is scoped only to the current context
+ * (<code>Context</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: Session.java,v 1.3 2004/03/05 13:02:54 bdelacretaz Exp $
+ *
+ */
+
+public interface Session {
+
+    /**
+     *
+     * Returns the time when this session was created, measured
+     * in milliseconds since midnight January 1, 1970 GMT.
+     *
+     * @return                                a <code>long</code> specifying
+     *                                         when this session was created,
+     *                                        expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    long getCreationTime();
+
+    /**
+     *
+     * Returns a string containing the unique identifier assigned
+     * to this session. The identifier is assigned
+     * by the context container and is implementation dependent.
+     *
+     * @return                                a string specifying the identifier
+     *                                        assigned to this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    String getId();
+
+    /**
+     *
+     * Returns the last time the client sent a request associated with
+     * this session, as the number of milliseconds since midnight
+     * January 1, 1970 GMT.
+     *
+     * <p>Actions that your application takes, such as getting or setting
+     * a value associated with the session, do not affect the access
+     * time.
+     *
+     * @return                                a <code>long</code>
+     *                                        representing the last time
+     *                                        the client sent a request associated
+     *                                        with this session, expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+
+    long getLastAccessedTime();
+
+    /**
+     *
+     * Specifies the time, in seconds, between client requests before the
+     * contextcontainer will invalidate this session.  A negative time
+     * indicates the session should never timeout.
+     *
+     * @param interval                An integer specifying the number
+     *                                 of seconds
+     *
+     */
+    void setMaxInactiveInterval(int interval);
+
+   /**
+    * Returns the maximum time interval, in seconds, that
+    * the context container will keep this session open between
+    * client accesses. After this interval, the context container
+    * will invalidate the session.  The maximum time interval can be set
+    * with the <code>setMaxInactiveInterval</code> method.
+    * A negative time indicates the session should never timeout.
+    *
+    *
+    * @return                an integer specifying the number of
+    *                        seconds this session remains open
+    *                        between client requests
+    *
+    * @see                #setMaxInactiveInterval(int)
+    *
+    *
+    */
+    int getMaxInactiveInterval();
+
+    /**
+     *
+     * Returns the object bound with the specified name in this session, or
+     * <code>null</code> if no object is bound under the name.
+     *
+     * @param name                a string specifying the name of the object
+     *
+     * @return                        the object with the specified name
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    Object getAttribute(String name);
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code> objects
+     * containing the names of all the objects bound to this session.
+     *
+     * @return                        an <code>Enumeration</code> of
+     *                                <code>String</code> objects specifying the
+     *                                names of all the objects bound to
+     *                                this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    Enumeration getAttributeNames();
+
+    /**
+     * Binds an object to this session, using the name specified.
+     * If an object of the same name is already bound to the session,
+     * the object is replaced.
+     *
+     *
+     * @param name                        the name to which the object is bound;
+     *                                        cannot be null
+     *
+     * @param value                        the object to be bound; cannot be null
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     *
+     * Removes the object bound with the specified name from
+     * this session. If the session does not have an object
+     * bound with the specified name, this method does nothing.
+     *
+     *
+     * @param name                                the name of the object to
+     *                                                remove from this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     */
+    void removeAttribute(String name);
+
+    /**
+     *
+     * Invalidates this session
+     * to it.
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    void invalidate();
+
+    /**
+     *
+     * Returns <code>true</code> if the client does not yet know about the
+     * session or if the client chooses not to join the session.  For
+     * example, if the server used only cookie-based sessions, and
+     * the client had disabled the use of cookies, then a session would
+     * be new on each request.
+     *
+     * @return                                 <code>true</code> if the
+     *                                        server has created a session,
+     *                                        but the client has not yet joined
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    boolean isNew();
+
+}
+

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpContext.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpContext.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,146 @@
+/*
+ * 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.butterfly.environment.http;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+
+import org.apache.butterfly.environment.Context;
+
+/**
+ *
+ * Implements the {@link org.apache.cocoon.environment.Context} interface
+ * @author ?
+ * @version CVS $Id: HttpContext.java,v 1.3 2004/05/07 17:23:42 joerg Exp $
+ */
+
+public final class HttpContext implements Context {
+
+    /** The ServletContext */
+    private final ServletContext servletContext;
+
+    /**
+     * Constructs a HttpContext object from a ServletContext object
+     */
+    public HttpContext (ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
+
+    public Object getAttribute(String name) {
+        return servletContext.getAttribute(name);
+    }
+
+    public void setAttribute(String name, Object value) {
+        servletContext.setAttribute(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        servletContext.removeAttribute(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        return servletContext.getAttributeNames();
+    }
+
+    public URL getResource(String path)
+       throws MalformedURLException {
+       return servletContext.getResource(path);
+    }
+
+    public InputStream getResourceAsStream(String path) {
+    return servletContext.getResourceAsStream(path);
+    }
+
+    public String getRealPath(String path) {
+        if (path.equals("/")) {
+            String value = servletContext.getRealPath(path);
+            if (value == null) {
+                // Try to figure out the path of the root from that of WEB-INF
+                try {
+                value = this.servletContext.getResource("/WEB-INF").toString();
+                } catch (MalformedURLException mue) {
+                    throw new RuntimeException("Cannot determine the base URL for " + path, mue);
+                }
+                value = value.substring(0,value.length()-"WEB-INF".length());
+            }
+            return value;
+        }
+        return servletContext.getRealPath(path);
+    }
+
+    public String getMimeType(String file) {
+      return servletContext.getMimeType(file);
+    }
+
+    public String getInitParameter(String name) {
+        return servletContext.getInitParameter(name);
+    }
+
+    /*
+     * These methods are not in Cocoon's Context interface, but in the
+     * ServletContext. To use them you have to downcast Cocoon's Context
+     * to this HttpContext until we decide to add them to the Context
+     * interface too.
+     * 
+     * The following methods are deprecated since Servlet API 2.0 or 2.1
+     * and will not be implemented here:
+     * - public Servlet getServlet(String name)
+     * - public Enumeration getServletNames()
+     * - public Enumeration getServlets()
+     * - public void log(Exception exception, String msg)
+     */
+
+    public ServletContext getContext(String uripath) {
+        return this.servletContext.getContext(uripath);
+    }
+
+    public Enumeration getInitParameterNames() {
+        return this.servletContext.getInitParameterNames();
+    }
+
+    public int getMajorVersion() {
+        return this.servletContext.getMajorVersion();
+    }
+
+    public int getMinorVersion() {
+        return this.servletContext.getMinorVersion();
+    }
+
+    public RequestDispatcher getNamedDispatcher(String name) {
+        return this.servletContext.getNamedDispatcher(name);
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return this.servletContext.getRequestDispatcher(path);
+    }
+
+    public String getServerInfo() {
+        return this.servletContext.getServerInfo();
+    }
+
+    public void log(String msg) {
+        this.servletContext.log(msg);
+    }
+
+    public void log(String msg, Throwable throwable) {
+        this.servletContext.log(msg, throwable);
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpCookie.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpCookie.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,472 @@
+/*
+ * 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.butterfly.environment.http;
+
+import org.apache.butterfly.environment.Cookie;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link HttpResponse#addCookie(Cookie)} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link HttpRequest#getCookies()} method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: HttpCookie.java,v 1.4 2004/03/05 13:02:55 bdelacretaz Exp $
+ *
+ */
+
+public final class HttpCookie
+implements Cookie {
+
+    private javax.servlet.http.Cookie cookie;
+
+    public HttpCookie(String name, String value) {
+        this.cookie = new javax.servlet.http.Cookie(name, value);
+    }
+
+    public HttpCookie(javax.servlet.http.Cookie cookie) {
+        this.cookie = cookie;
+    }
+
+    public javax.servlet.http.Cookie getServletCookie() {
+        this.checkState();
+        return this.cookie;
+    }
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p>The name must conform to RFC 2109. That means it can contain
+     * only ASCII alphanumeric characters and cannot contain commas,
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p>The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * <code>setValue</code> method.
+     *
+     * <p>By default, cookies are created according to the Netscape
+     * cookie specification. The version can be changed with the
+     * <code>setVersion</code> method.
+     *
+     *
+     * @param name                         a <code>String</code> specifying the name of the cookie
+     *
+     * @param value                        a <code>String</code> specifying the value of the cookie
+     *
+     * @throws IllegalArgumentException        if the cookie name contains illegal characters
+     *                                        (for example, a comma, space, or semicolon)
+     *                                        or it is one of the tokens reserved for use
+     *                                        by the cookie protocol
+     * @see #setValue(String)
+     * @see #setVersion(int)
+     *
+     */
+
+    public void init(String name, String value) {
+        if (this.cookie == null) {
+            this.cookie = new javax.servlet.http.Cookie(name, value);
+        } else {
+            throw new IllegalStateException("Cookie is already initialised");
+        }
+    }
+
+
+    private void checkState() {
+        if (this.cookie == null) {
+            throw new IllegalStateException("Cookie is not initialised");
+        }
+    }
+
+    /**
+     *
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie
+     * to the user. Comments
+     * are not supported by Netscape Version 0 cookies.
+     *
+     * @param purpose                a <code>String</code> specifying the comment
+     *                                to display to the user
+     *
+     * @see #getComment()
+     *
+     */
+
+    public void setComment(String purpose) {
+        this.checkState();
+        this.cookie.setComment(purpose);
+    }
+
+
+
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * <code>null</code> if the cookie has no comment.
+     *
+     * @return                        a <code>String</code> containing the comment,
+     *                                or <code>null</code> if none
+     *
+     * @see #setComment(String)
+     *
+     */
+
+    public String getComment() {
+        this.checkState();
+        return this.cookie.getComment();
+    }
+
+
+
+
+    /**
+     *
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p>The form of the domain name is specified by RFC 2109. A domain
+     * name begins with a dot (<code>.foo.com</code>) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, <code>www.foo.com</code>, but not
+     * <code>a.b.foo.com</code>). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     *
+     * @param pattern                a <code>String</code> containing the domain name
+     *                                within which this cookie is visible;
+     *                                form is according to RFC 2109
+     *
+     * @see #getDomain()
+     *
+     */
+
+    public void setDomain(String pattern) {
+        this.checkState();
+        this.cookie.setDomain(pattern);
+    }
+
+
+
+
+
+    /**
+     * Returns the domain name set for this cookie. The form of
+     * the domain name is set by RFC 2109.
+     *
+     * @return                        a <code>String</code> containing the domain name
+     *
+     * @see #setDomain(String)
+     *
+     */
+
+    public String getDomain() {
+        this.checkState();
+        return this.cookie.getDomain();
+    }
+
+
+
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p>A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p>A negative value means
+     * that the cookie is not stored persistently and will be deleted
+     * when the Web browser exits. A zero value causes the cookie
+     * to be deleted.
+     *
+     * @param expiry                an integer specifying the maximum age of the
+     *                                 cookie in seconds; if negative, means
+     *                                the cookie is not stored; if zero, deletes
+     *                                the cookie
+     *
+     *
+     * @see #getMaxAge()
+     *
+     */
+
+    public void setMaxAge(int expiry) {
+        this.checkState();
+        this.cookie.setMaxAge(expiry);
+    }
+
+
+
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds,
+     * By default, <code>-1</code> indicating the cookie will persist
+     * until browser shutdown.
+     *
+     *
+     * @return                        an integer specifying the maximum age of the
+     *                                cookie in seconds; if negative, means
+     *                                the cookie persists until browser shutdown
+     *
+     *
+     * @see #setMaxAge(int)
+     *
+     */
+
+    public int getMaxAge() {
+        this.checkState();
+        return this.cookie.getMaxAge();
+    }
+
+
+
+
+    /**
+     * Specifies a path for the cookie
+     * to which the client should return the cookie.
+     *
+     * <p>The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories.
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p>Consult RFC 2109 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     *
+     * @param uri                a <code>String</code> specifying a path
+     *
+     *
+     * @see #getPath()
+     *
+     */
+
+    public void setPath(String uri) {
+        this.checkState();
+        this.cookie.setPath(uri);
+    }
+
+
+
+
+    /**
+     * Returns the path on the server
+     * to which the browser returns this cookie. The
+     * cookie is visible to all subpaths on the server.
+     *
+     *
+     * @return                a <code>String</code> specifying a path that contains
+     *                        a servlet name, for example, <i>/catalog</i>
+     *
+     * @see #setPath(String)
+     *
+     */
+
+    public String getPath() {
+        this.checkState();
+        return this.cookie.getPath();
+    }
+
+
+
+
+
+    /**
+     * Indicates to the browser whether the cookie should only be sent
+     * using a secure protocol, such as HTTPS or SSL.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @param flag        if <code>true</code>, sends the cookie from the browser
+     *                        to the server using only when using a secure protocol;
+     *                        if <code>false</code>, sent on any protocol
+     *
+     * @see #getSecure()
+     *
+     */
+
+    public void setSecure(boolean flag) {
+        this.checkState();
+        this.cookie.setSecure(flag);
+    }
+
+
+
+
+    /**
+     * Returns <code>true</code> if the browser is sending cookies
+     * only over a secure protocol, or <code>false</code> if the
+     * browser can send cookies using any protocol.
+     *
+     * @return                <code>true</code> if the browser can use
+     *                        any standard protocol; otherwise, <code>false</code>
+     *
+     * @see #setSecure(boolean)
+     *
+     */
+
+    public boolean getSecure() {
+        this.checkState();
+        return this.cookie.getSecure();
+    }
+
+
+
+
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return                a <code>String</code> specifying the cookie's name
+     *
+     */
+
+    public String getName() {
+        this.checkState();
+        return this.cookie.getName();
+    }
+
+
+
+
+
+    /**
+     *
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p>With Version 0 cookies, values should not contain white
+     * space, brackets, parentheses, equals signs, commas,
+     * double quotes, slashes, question marks, at signs, colons,
+     * and semicolons. Empty values may not behave the same way
+     * on all browsers.
+     *
+     * @param newValue                a <code>String</code> specifying the new value
+     *
+     *
+     * @see #getValue()
+     * @see Cookie
+     *
+     */
+
+    public void setValue(String newValue) {
+        this.checkState();
+        this.cookie.setValue(newValue);
+    }
+
+
+
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return                        a <code>String</code> containing the cookie's
+     *                                present value
+     *
+     * @see #setValue(String)
+     * @see Cookie
+     *
+     */
+
+    public String getValue() {
+        this.checkState();
+        return this.cookie.getValue();
+    }
+
+
+
+
+    /**
+     * Returns the version of the protocol this cookie complies
+     * with. Version 1 complies with RFC 2109,
+     * and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided
+     * by a browser use and identify the browser's cookie version.
+     *
+     *
+     * @return                        0 if the cookie complies with the
+     *                                original Netscape specification; 1
+     *                                if the cookie complies with RFC 2109
+     *
+     * @see #setVersion(int)
+     *
+     */
+
+    public int getVersion() {
+        this.checkState();
+        return this.cookie.getVersion();
+    }
+
+
+
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2109.
+     *
+     * <p>Since RFC 2109 is still somewhat new, consider
+     * version 1 as experimental; do not use it yet on production sites.
+     *
+     *
+     * @param v                        0 if the cookie should comply with
+     *                                the original Netscape specification;
+     *                                1 if the cookie should comply with RFC 2109
+     *
+     * @see #getVersion()
+     *
+     */
+
+    public void setVersion(int v) {
+        this.checkState();
+        this.cookie.setVersion(v);
+    }
+
+
+
+}
+

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpEnvironment.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpEnvironment.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,224 @@
+/*
+ * 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.butterfly.environment.http;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.butterfly.environment.AbstractEnvironment;
+import org.apache.butterfly.environment.ObjectModelHelper;
+import org.apache.butterfly.util.NetUtils;
+
+/**
+ * 
+ * @author <a herf="mailto:dev@cocoon.apache.org>Apache Cocoon Team</a>
+ * @version CVS $Id: HttpEnvironment.java,v 1.18 2004/07/05 07:42:50 cziegeler Exp $
+ */
+public class HttpEnvironment extends AbstractEnvironment {
+
+    public static final String HTTP_REQUEST_OBJECT = "httprequest";
+    public static final String HTTP_RESPONSE_OBJECT= "httpresponse";
+    public static final String HTTP_SERVLET_CONTEXT= "httpservletcontext";
+
+    /** The HttpRequest */
+    private HttpRequest request;
+
+    /** The HttpResponse */
+    private HttpResponse response;
+
+    /** The HttpContext */
+    private HttpContext webcontext;
+
+    /** Cache content type as there is no getContentType() in reponse object */
+    private String contentType;
+
+    /**
+     * Constructs a HttpEnvironment object from a HttpServletRequest
+     * and HttpServletResponse objects
+     */
+    public HttpEnvironment(String uri,
+                           String root,
+                           HttpServletRequest req,
+                           HttpServletResponse res,
+                           ServletContext servletContext,
+                           HttpContext context,
+                           String containerEncoding,
+                           String defaultFormEncoding)
+     throws MalformedURLException, IOException {
+        super(uri, null, null);
+
+        this.request = new HttpRequest(req, this);
+        this.request.setCharacterEncoding(defaultFormEncoding);
+        this.request.setContainerEncoding(containerEncoding);
+        this.response = new HttpResponse(res);
+        this.webcontext = context;
+        
+        setView(extractView(this.request));
+        setAction(extractAction(this.request));
+        
+        this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT, this.request);
+        this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT, this.response);
+        this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT, this.webcontext);
+        
+        // This is a kind of a hack for the components that need
+        // the real servlet objects to pass them along to other
+        // libraries.
+        this.objectModel.put(HTTP_REQUEST_OBJECT, req);
+        this.objectModel.put(HTTP_RESPONSE_OBJECT, res);
+        this.objectModel.put(HTTP_SERVLET_CONTEXT, servletContext);
+    }
+
+    /**
+     *  Redirect the client to new URL 
+     */
+    public void redirect(String newURL, 
+                         boolean global, 
+                         boolean permanent) 
+    throws IOException {
+        // redirect
+        String redirect = this.response.encodeRedirectURL(newURL);
+
+        // FIXME (VG): WebSphere 4.0/4.0.1 bug
+        if (!newURL.startsWith("/") && newURL.indexOf(':') == -1 && redirect.indexOf(':') != -1) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Redirect: WebSphere Bug Detected!");
+            }
+            String base = NetUtils.getPath(request.getRequestURI());
+            if (base.startsWith("/")) {
+                base = base.substring(1);
+            }
+            redirect = response.encodeRedirectURL(base + '/' + newURL);
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Sending redirect to '" + redirect + "'");
+        }
+
+        if (permanent) {
+            this.response.sendPermanentRedirect(redirect);
+        } else {
+            this.response.sendRedirect (redirect);
+        }
+    }
+
+    /**
+     * Set the StatusCode
+     */
+    public void setStatus(int statusCode) {
+        this.response.setStatus(statusCode);
+    }
+
+    /**
+     * Set the ContentType
+     */
+    public void setContentType(String contentType) {
+        this.response.setContentType(contentType);
+        this.contentType = contentType;
+    }
+
+    /**
+     * Get the ContentType
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+
+    /**
+     * Set the length of the generated content
+     */
+    public void setContentLength(int length) {
+        this.response.setContentLength(length);
+    }
+
+    /**
+     * Check if the response has been modified since the same
+     * "resource" was requested.
+     * The caller has to test if it is really the same "resource"
+     * which is requested.
+     * @return true if the response is modified or if the
+     *         environment is not able to test it
+     */
+    public boolean isResponseModified(long lastModified) {
+        if (lastModified != 0) {
+            long if_modified_since = this.request.getDateHeader("If-Modified-Since");
+            this.response.setDateHeader("Last-Modified", lastModified);
+            return (if_modified_since / 1000 < lastModified  / 1000);
+        }
+        return true;
+    }
+
+    /**
+     * Mark the response as not modified.
+     */
+    public void setResponseIsNotModified() {
+        this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+    }
+
+    /**
+     * Reset the response if possible. This allows error handlers to have
+     * a higher chance to produce clean output if the pipeline that raised
+     * the error has already output some data.
+     *
+     * @return true if the response was successfully reset
+     */
+    public boolean tryResetResponse()
+    throws IOException {
+        if (!super.tryResetResponse()) {
+            try {
+                if (!this.response.isCommitted()) {
+                    this.response.reset();
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Response successfully reset");
+                    }
+                    return true;
+                }
+            } catch (Exception e) {
+                // Log the error, but don't transmit it
+                logger.warn("Problem resetting response", e);
+            }
+            if (logger.isDebugEnabled()) {
+                logger.debug("Response wasn't reset");
+            }
+            return false;
+        }
+        return true;
+    }
+
+
+    /**
+     * Get the output stream where to write the generated resource.
+     * The returned stream is buffered by the environment. If the
+     * buffer size is -1 then the complete output is buffered.
+     * If the buffer size is 0, no buffering takes place.
+     */
+    public OutputStream getOutputStream(final int bufferSize) {
+        if ( this.outputStream == null) {
+            this.outputStream = this.response.getOutputStream();
+        }
+        return super.getOutputStream( bufferSize );
+    }
+    
+    /**
+     * Always return <code>true</code>.
+     */
+    public boolean isExternal() {
+        return true;
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpRequest.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpRequest.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,470 @@
+/*
+ * 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.butterfly.environment.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.butterfly.environment.Cookie;
+import org.apache.butterfly.environment.Request;
+import org.apache.butterfly.environment.Session;
+import org.apache.butterfly.servlet.multipart.MultipartHttpServletRequest;
+import org.apache.commons.collections.IteratorUtils;
+
+/**
+ * Implements the {@link org.apache.cocoon.environment.Request} interface
+ * to provide request information in the HTTP servlets environment.
+ *
+ * @author <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
+ * @version CVS $Id: HttpRequest.java,v 1.11 2004/07/12 13:27:57 cziegeler Exp $
+ */
+
+public final class HttpRequest implements Request {
+
+    /** The real HttpServletRequest object */
+    private final HttpServletRequest req;
+
+    /** The HttpEnvironment object */
+    private final HttpEnvironment env;
+
+    /** The character encoding of parameters */
+    private String form_encoding;
+
+    /** The default form encoding of the servlet container */
+    private String container_encoding;
+    
+    /** The current session */
+    private HttpSession session;
+    
+    private final Map attributes = new HashMap();
+    
+    /**
+     * Creates a HttpRequest based on a real HttpServletRequest object
+     */
+    protected HttpRequest(HttpServletRequest req, HttpEnvironment env) {
+        super();
+        this.req = req;
+        this.env = env;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#get(java.lang.String)
+     */
+    public Object get(String name) {
+        // if the request has been wrapped then access its method
+        if (req instanceof MultipartHttpServletRequest) {
+            return ((MultipartHttpServletRequest) req).get(name);
+        } else {
+            String[] values = req.getParameterValues(name);
+            if (values == null) {
+                return null;
+            }
+            if (values.length == 1) {
+                return values[0];
+            }
+            if (values.length > 1) {
+                Vector vect = new Vector(values.length);
+                for (int i = 0; i < values.length; i++) {
+                    vect.add(values[i]);
+                }
+                return vect;
+            }
+        }
+        return null;
+    }
+
+    /* The HttpServletRequest interface methods */
+
+    public String getAuthType() {
+        return this.req.getAuthType();
+    }
+
+    private Cookie[] wrappedCookies = null;
+    private Map wrappedCookieMap = null;
+
+    public Cookie[] getCookies() {
+        if (this.wrappedCookieMap == null) {
+            wrapCookies();
+        }
+        return this.wrappedCookies;
+    }
+
+    public Map getCookieMap() {
+        if (this.wrappedCookieMap == null) {
+            wrapCookies();
+        }
+        return this.wrappedCookieMap;
+    }
+
+    private synchronized void wrapCookies() {
+        this.wrappedCookieMap = new HashMap();
+        javax.servlet.http.Cookie[] cookies = this.req.getCookies();
+        if (cookies != null) {
+            this.wrappedCookies = new Cookie[cookies.length];
+            for(int i=0; i<cookies.length;i++) {
+                HttpCookie cookie = new HttpCookie(cookies[i]);
+                this.wrappedCookies[i] = cookie;
+                this.wrappedCookieMap.put(cookie.getName(),cookie);
+            }
+        }
+        this.wrappedCookieMap = Collections.unmodifiableMap(this.wrappedCookieMap);
+    }
+
+    public long getDateHeader(String name) {
+        return this.req.getDateHeader(name);
+    }
+
+    public String getHeader(String name) {
+        return this.req.getHeader(name);
+    }
+
+    public Enumeration getHeaders(String name) {
+        return this.req.getHeaders(name);
+    }
+
+    public Enumeration getHeaderNames() {
+        return this.req.getHeaderNames();
+    }
+
+    public int getIntHeader(String name) {
+        return this.req.getIntHeader(name);
+    }
+
+    public String getMethod() {
+        return this.req.getMethod();
+    }
+
+    public String getPathInfo() {
+        return this.req.getPathInfo();
+    }
+
+    public String getPathTranslated() {
+        return this.req.getPathTranslated();
+    }
+
+    public String getContextPath() {
+        return this.req.getContextPath();
+    }
+
+    public String getQueryString() {
+        return this.req.getQueryString();
+    }
+
+    public String getRemoteUser() {
+        return this.req.getRemoteUser();
+    }
+
+    public boolean isUserInRole(String role) {
+        return this.req.isUserInRole(role);
+    }
+
+    public java.security.Principal getUserPrincipal() {
+        return this.req.getUserPrincipal();
+    }
+
+    public String getRequestedSessionId() {
+        return this.req.getRequestedSessionId();
+    }
+
+    protected String reqURI;
+
+    public String getRequestURI() {
+        if (this.reqURI == null) {
+            this.reqURI = this.req.getRequestURI();
+            if ( this.reqURI.equals("/") ) {
+                String s = this.req.getServletPath();
+                final StringBuffer buffer = new StringBuffer();
+                if ( null != s ) buffer.append(s);
+                s = this.req.getPathInfo();
+                if ( null != s ) buffer.append(s);
+                this.reqURI = buffer.toString();
+            }
+        }
+        return this.reqURI;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapURI()
+     */
+    public String getSitemapURI() {
+        return this.env.getURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapPath()
+     */
+    public String getSitemapPath() {
+        return this.env.getURIPrefix();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getServletPath()
+     */
+    public String getServletPath() {
+        return this.req.getServletPath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSession(boolean)
+     */
+    public Session getSession(boolean create) {
+        javax.servlet.http.HttpSession serverSession = this.req.getSession(create);
+        if ( null != serverSession) {
+            if ( null != this.session ) {
+                if ( this.session.wrappedSession != serverSession ) {
+                    // update wrapper
+                    this.session.wrappedSession = serverSession;
+                }
+            } else {
+                // new wrapper
+                this.session = new HttpSession( serverSession );
+            }
+        } else {
+            // invalidate
+            this.session = null;
+        }
+        return this.session;
+    }
+
+    public Session getSession() {
+        return this.getSession(true);
+    }
+
+    public boolean isRequestedSessionIdValid() {
+        return this.req.isRequestedSessionIdValid();
+    }
+
+    public boolean isRequestedSessionIdFromCookie()  {
+        return this.req.isRequestedSessionIdFromCookie();
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+        return this.req.isRequestedSessionIdFromURL();
+    }
+
+    /**
+     * @deprecated As of Version 2.1 of the Java Servlet API, use
+     *             {@link #isRequestedSessionIdFromURL()} instead.
+     */
+    public boolean isRequestedSessionIdFromUrl() {
+        return this.req.isRequestedSessionIdFromURL();
+    }
+
+    /* The ServletRequest interface methods */
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.getAttribute(name, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.getAttributeNames(Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.setAttribute(name, value, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.removeAttribute(name, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return this.attributes.get(name);
+        } else {
+            return this.req.getAttribute(name);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return IteratorUtils.asEnumeration(this.attributes.keySet().iterator());
+        } else {
+            return this.req.getAttributeNames();
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object value, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.put(name, value);
+        } else {
+            this.req.setAttribute(name, value);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.remove(name);
+        } else {
+            this.req.removeAttribute(name);
+        }
+    }
+
+    public String getCharacterEncoding() {
+        if (this.form_encoding == null) {
+            return this.req.getCharacterEncoding();
+        } else {
+            return this.form_encoding;
+        }
+    }
+
+    public void setCharacterEncoding(String form_encoding)
+    throws java.io.UnsupportedEncodingException {
+        this.form_encoding = form_encoding;
+    }
+
+    /**
+     * Sets the default encoding of the servlet container.
+     */
+    public void setContainerEncoding(String container_encoding) {
+        this.container_encoding = container_encoding;
+    }
+
+    public int getContentLength() {
+        return this.req.getContentLength();
+    }
+
+    public String getContentType() {
+        return this.req.getContentType();
+    }
+
+    public ServletInputStream getInputStream() throws IOException {
+        return this.req.getInputStream();
+    }
+
+    public String getParameter(String name) {
+        String value = this.req.getParameter(name);
+        if (this.form_encoding == null || value == null) {
+            return value;
+        }
+        return decode(value);
+    }
+
+    private String decode(String str) {
+        if (str == null) return null;
+        try {
+            if (this.container_encoding == null)
+                this.container_encoding = "ISO-8859-1";
+            byte[] bytes = str.getBytes(this.container_encoding);
+            return new String(bytes, form_encoding);
+        } catch (java.io.UnsupportedEncodingException uee) {
+            throw new RuntimeException("Unsupported Encoding Exception", uee);
+        }
+    }
+
+    public Enumeration getParameterNames() {
+        return this.req.getParameterNames();
+    }
+
+    public String[] getParameterValues(String name) {
+        String[] values = this.req.getParameterValues(name);
+        if (values == null) return null;
+        if (this.form_encoding == null) {
+            return values;
+        }
+        String[] decoded_values = new String[values.length];
+        for (int i = 0; i < values.length; ++i) {
+            decoded_values[i] = decode(values[i]);
+        }
+        return decoded_values;
+    }
+
+    public String getProtocol() {
+        return this.req.getProtocol();
+    }
+
+    public String getScheme() {
+        return this.req.getScheme();
+    }
+
+    public String getServerName() {
+        return this.req.getServerName();
+    }
+
+    public int getServerPort() {
+        return this.req.getServerPort();
+    }
+
+    public BufferedReader getReader() throws IOException {
+        return this.req.getReader();
+    }
+
+    public String getRemoteAddr() {
+        return this.req.getRemoteAddr();
+    }
+
+    public String getRemoteHost() {
+        return this.req.getRemoteHost();
+    }
+
+    public Locale getLocale() {
+        return this.req.getLocale();
+    }
+
+    public Enumeration getLocales() {
+        return this.req.getLocales();
+    }
+
+    public boolean isSecure() {
+        return this.req.isSecure();
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return this.req.getRequestDispatcher(path);
+    }
+
+    /**
+     * @deprecated As of Version 2.1 of the Java Servlet API, use
+     * {@link javax.servlet.ServletContext#getRealPath(java.lang.String)}instead.
+     */
+    public String getRealPath(String path) {
+        return this.req.getRealPath(path);
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpResponse.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpResponse.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,215 @@
+/*
+ * 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.butterfly.environment.http;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.butterfly.environment.Cookie;
+import org.apache.butterfly.environment.EnvironmentException;
+import org.apache.butterfly.environment.Response;
+
+/**
+ * Implements the {@link org.apache.cocoon.environment.Response} interface
+ * to provide response functionality in the HTTP servlets environment.
+ * 
+ * @author <a href="mailto:dev@cocoon.apache.org">Apache Cocoon Team</a>
+ * @version CVS $Id: HttpResponse.java,v 1.4 2004/03/05 13:02:55 bdelacretaz Exp $
+ */
+
+public final class HttpResponse implements Response {
+
+    /** The real HttpServletResponse object */
+    private final HttpServletResponse res;
+
+    /**
+     * Creates a HttpServletResponse based on a real HttpServletResponse object
+     */
+    protected HttpResponse (HttpServletResponse res) {
+        this.res = res;
+    }
+
+    /**
+     * Create a new cookie which is not added to the response
+     */
+    public Cookie createCookie(String name, String value) {
+        return new HttpCookie(name, value);
+    }
+
+    public void addCookie(Cookie cookie) {
+        if (cookie instanceof HttpCookie) {
+            this.res.addCookie(((HttpCookie)cookie).getServletCookie());
+        } else {
+            javax.servlet.http.Cookie newCookie;
+            newCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
+            newCookie.setComment(cookie.getComment());
+            newCookie.setDomain(cookie.getDomain());
+            newCookie.setMaxAge(cookie.getMaxAge());
+            newCookie.setPath(cookie.getPath());
+            newCookie.setSecure(cookie.getSecure());
+            newCookie.setVersion(cookie.getVersion());
+            this.res.addCookie(newCookie);
+        }
+    }
+
+    public boolean containsHeader(String name) {
+        return this.res.containsHeader(name);
+    }
+
+    public String encodeURL(String url) {
+        if (url != null && url.indexOf(";jsessionid=") != -1)
+            return url;
+        return this.res.encodeURL(url);
+    }
+
+    public String encodeRedirectURL(String url) {
+        if (url != null && url.indexOf(";jsessionid=") != -1) {
+            return url;
+        }
+
+        return this.res.encodeRedirectURL(url);
+    }
+
+    public void sendError(int sc, String msg) throws IOException {
+        this.res.sendError(sc, msg);
+    }
+
+    public void sendError(int sc) throws IOException {
+        this.res.sendError(sc);
+    }
+
+    public void sendRedirect(String location) throws IOException {
+        this.res.sendRedirect(location);
+    }
+
+    public void sendPermanentRedirect(String location) throws IOException {
+        this.res.setHeader("location", location);
+        this.res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
+    }
+    
+    public void setDateHeader(String name, long date) {
+        this.res.setDateHeader(name, date);
+    }
+
+    public void addDateHeader(String name, long date) {
+        this.res.addDateHeader(name, date);
+    }
+
+    public void setHeader(String name, String value) {
+        this.res.setHeader(name, value);
+    }
+
+    public void addHeader(String name, String value) {
+        this.res.addHeader(name, value);
+    }
+
+    public void setIntHeader(String name, int value) {
+        this.res.setIntHeader(name, value);
+    }
+
+    public void addIntHeader(String name, int value) {
+        this.res.addIntHeader(name, value);
+    }
+
+    public void setStatus(int sc) {
+        this.res.setStatus(sc);
+    }
+
+    /**
+     * @deprecated        As of version 2.1, use encodeURL(String url) instead
+     */
+    public String encodeUrl(String url) {
+        return this.res.encodeUrl(url);
+    }
+
+    /**
+     * @deprecated        As of version 2.1, use
+     *              encodeRedirectURL(String url) instead
+     */
+    public String encodeRedirectUrl(String url) {
+        return this.res.encodeRedirectUrl(url);
+    }
+
+    /**
+     * @deprecated As of version 2.1, due to ambiguous meaning of the
+     * message parameter. To set a status code
+     * use <code>setStatus(int)</code>, to send an error with a description
+     * use <code>sendError(int, String)</code>.
+     */
+    public void setStatus(int sc, String sm) {
+        this.res.setStatus(sc, sm);
+    }
+
+    /* The ServletResponse interface methods */
+
+    public String getCharacterEncoding() {
+        return this.res.getCharacterEncoding();
+    }
+
+    public ServletOutputStream getOutputStream() {
+        try {
+            return this.res.getOutputStream();
+        } catch (IOException e) {
+            throw new EnvironmentException("Cannot get output stream.", e);
+        }
+    }
+
+    public PrintWriter getWriter() throws IOException {
+        //throw new IllegalStateException ("you are not a serializer or reader");
+        return this.res.getWriter();
+    }
+
+    public void setContentLength(int len) {
+        this.res.setContentLength(len);
+    }
+
+    public void setContentType(String type) {
+        this.res.setContentType(type);
+    }
+
+    public void setBufferSize(int size) {
+        this.res.setBufferSize(size);
+    }
+
+    public int getBufferSize() {
+        return this.res.getBufferSize();
+    }
+
+    public void flushBuffer() throws IOException {
+        this.res.flushBuffer();
+    }
+
+    public boolean isCommitted() {
+        return this.res.isCommitted();
+    }
+
+    public void reset() {
+        this.res.reset();
+    }
+
+    public void setLocale(Locale loc) {
+        this.res.setLocale(loc);
+    }
+
+    public Locale getLocale() {
+        return this.res.getLocale();
+    }
+}
+

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpSession.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/environment/http/HttpSession.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,264 @@
+/*
+ * 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.butterfly.environment.http;
+
+import org.apache.butterfly.environment.Session;
+
+import java.util.Enumeration;
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>Cocoon uses this interface to create a session
+ * between a client and the "cocoon server". The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows Cocoon to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ *     the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ *     across multiple user connections
+ * </ul>
+ *
+ * <p>Session information is scoped only to the current context
+ * (<code>Context</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: HttpSession.java,v 1.3 2004/03/05 13:02:55 bdelacretaz Exp $
+ *
+ */
+
+public final class HttpSession
+implements Session {
+
+    javax.servlet.http.HttpSession wrappedSession;
+
+    /**
+     * Construct a new session from an HttpSession
+     */
+    public HttpSession(javax.servlet.http.HttpSession session) {
+        this.wrappedSession = session;
+    }
+
+    /**
+     *
+     * Returns the time when this session was created, measured
+     * in milliseconds since midnight January 1, 1970 GMT.
+     *
+     * @return                                a <code>long</code> specifying
+     *                                         when this session was created,
+     *                                        expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public long getCreationTime() {
+        return this.wrappedSession.getCreationTime();
+    }
+
+    /**
+     *
+     * Returns a string containing the unique identifier assigned
+     * to this session. The identifier is assigned
+     * by the context container and is implementation dependent.
+     *
+     * @return                                a string specifying the identifier
+     *                                        assigned to this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public String getId() {
+        return this.wrappedSession.getId();
+    }
+
+    /**
+     *
+     * Returns the last time the client sent a request associated with
+     * this session, as the number of milliseconds since midnight
+     * January 1, 1970 GMT.
+     *
+     * <p>Actions that your application takes, such as getting or setting
+     * a value associated with the session, do not affect the access
+     * time.
+     *
+     * @return                                a <code>long</code>
+     *                                        representing the last time
+     *                                        the client sent a request associated
+     *                                        with this session, expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+
+    public long getLastAccessedTime() {
+        return this.wrappedSession.getLastAccessedTime();
+    }
+
+    /**
+     *
+     * Specifies the time, in seconds, between client requests before the
+     * contextcontainer will invalidate this session.  A negative time
+     * indicates the session should never timeout.
+     *
+     * @param interval                An integer specifying the number
+     *                                 of seconds
+     *
+     */
+    public void setMaxInactiveInterval(int interval) {
+        this.wrappedSession.setMaxInactiveInterval(interval);
+    }
+
+   /**
+    * Returns the maximum time interval, in seconds, that
+    * the context container will keep this session open between
+    * client accesses. After this interval, the context container
+    * will invalidate the session.  The maximum time interval can be set
+    * with the <code>setMaxInactiveInterval</code> method.
+    * A negative time indicates the session should never timeout.
+    *
+    *
+    * @return                an integer specifying the number of
+    *                        seconds this session remains open
+    *                        between client requests
+    *
+    * @see                #setMaxInactiveInterval(int)
+    *
+    *
+    */
+    public int getMaxInactiveInterval() {
+        return this.wrappedSession.getMaxInactiveInterval();
+    }
+
+    /**
+     *
+     * Returns the object bound with the specified name in this session, or
+     * <code>null</code> if no object is bound under the name.
+     *
+     * @param name                a string specifying the name of the object
+     *
+     * @return                        the object with the specified name
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public Object getAttribute(String name) {
+        return this.wrappedSession.getAttribute(name);
+    }
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code> objects
+     * containing the names of all the objects bound to this session.
+     *
+     * @return                        an <code>Enumeration</code> of
+     *                                <code>String</code> objects specifying the
+     *                                names of all the objects bound to
+     *                                this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public Enumeration getAttributeNames() {
+        return this.wrappedSession.getAttributeNames();
+    }
+
+    /**
+     * Binds an object to this session, using the name specified.
+     * If an object of the same name is already bound to the session,
+     * the object is replaced.
+     *
+     *
+     * @param name                        the name to which the object is bound;
+     *                                        cannot be null
+     *
+     * @param value                        the object to be bound; cannot be null
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public void setAttribute(String name, Object value) {
+        this.wrappedSession.setAttribute(name, value);
+    }
+
+    /**
+     *
+     * Removes the object bound with the specified name from
+     * this session. If the session does not have an object
+     * bound with the specified name, this method does nothing.
+     *
+     *
+     * @param name                                the name of the object to
+     *                                                remove from this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     */
+    public void removeAttribute(String name) {
+        this.wrappedSession.removeAttribute(name);
+    }
+
+    /**
+     *
+     * Invalidates this session
+     * to it.
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    public void invalidate() {
+        this.wrappedSession.invalidate();
+    }
+
+    /**
+     *
+     * Returns <code>true</code> if the client does not yet know about the
+     * session or if the client chooses not to join the session.  For
+     * example, if the server used only cookie-based sessions, and
+     * the client had disabled the use of cookies, then a session would
+     * be new on each request.
+     *
+     * @return                                 <code>true</code> if the
+     *                                        server has created a session,
+     *                                        but the client has not yet joined
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    public boolean isNew() {
+        return this.wrappedSession.isNew();
+    }
+
+}
+

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/FileGenerator.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/FileGenerator.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/FileGenerator.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/Generator.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/Generator.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/generation/Generator.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/reading/Reader.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/reading/Reader.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/reading/Reader.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/Serializer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/Serializer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/Serializer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/XMLSerializer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/XMLSerializer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/serialization/XMLSerializer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,6 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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 

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartException.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartException.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,42 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+/**
+ * Exception thrown when on a parse error such as
+ * a malformed stream.
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: MultipartException.java,v 1.2 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public class MultipartException extends Exception {
+
+    /**
+     * Constructor MultipartException
+     */
+    public MultipartException() {
+        super();
+    }
+
+    /**
+     * Constructor MultipartException
+     *
+     * @param text
+     */
+    public MultipartException(String text) {
+        super(text);
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartHttpServletRequest.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartHttpServletRequest.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,577 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Servlet request wrapper for multipart parser.
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @author Stefano Mazzocchi
+ * @version CVS $Id: MultipartHttpServletRequest.java,v 1.7 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public class MultipartHttpServletRequest implements HttpServletRequest {
+
+    /** The wrapped request */
+    private HttpServletRequest request = null;
+
+    /** The submitted parts */
+    private Hashtable values = null;
+
+    /**
+     * Create this wrapper around the given request and including the given
+     * parts.
+     */
+    public MultipartHttpServletRequest(HttpServletRequest request, Hashtable values) {
+        this.request = request;
+        this.values = values;
+    }
+
+    /**
+     * Cleanup eventually uploaded parts that were saved on disk
+     */
+    public void cleanup() throws IOException {
+        Enumeration e = getParameterNames();
+        while (e.hasMoreElements()) {
+            Object o = get( (String)e.nextElement() );
+            if (o instanceof Part) {
+                Part part = (Part)o;
+                if (part.disposeWithRequest()) {
+                    part.dispose();
+                }
+            }
+        }
+    }
+
+    /**
+     * Method get
+     *
+     * @param name
+     *
+     */
+    public Object get(String name) {
+        Object result = null;
+
+        if (values != null) {
+            result = values.get(name);
+
+            if (result instanceof Vector) {
+                if (((Vector) result).size() == 1) {
+                    return ((Vector) result).elementAt(0);
+                } else {
+                    return result;
+                }
+            }
+        } else {
+            String[] array = request.getParameterValues(name);
+            Vector vec = new Vector();
+
+            if (array != null) {
+                for (int i = 0; i < array.length; i++) {
+                    vec.addElement(array[i]);
+                }
+
+                if (vec.size() == 1) {
+                    result = vec.elementAt(0);
+                } else {
+                    result = vec;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Method getParameterNames
+     *
+     */
+    public Enumeration getParameterNames() {
+        if (values != null) {
+            return values.keys();
+        } else {
+            return request.getParameterNames();
+        }
+    }
+
+    /**
+     * Method getParameter
+     *
+     * @param name
+     *
+     */
+    public String getParameter(String name) {
+        Object value = get(name);
+        String result = null;
+
+        if (value != null) {
+            if (value instanceof Vector) {
+                value = ((Vector) value).elementAt(0);
+            }
+
+            result = value.toString();
+        }
+
+        return result;
+    }
+
+    /**
+     * Method getParameterValues
+     *
+     * @param name
+     *
+     */
+    public String[] getParameterValues(String name) {
+        if (values != null) {
+            Object value = get(name);
+
+            if (value != null) {
+                if (value instanceof Vector) {
+                    String[] results = new String[((Vector)value).size()];
+                    for (int i=0;i<((Vector)value).size();i++) {
+                        results[i] = ((Vector)value).elementAt(i).toString();
+                    }
+                    return results;
+
+                } else {
+                    return new String[]{value.toString()};
+                }
+            }
+
+            return null;
+        } else {
+            return request.getParameterValues(name);
+        }
+    }
+
+    /**
+     * Method getAttribute
+     *
+     * @param name
+     *
+     */
+    public Object getAttribute(String name) {
+        return request.getAttribute(name);
+    }
+
+    /**
+     * Method getAttributeNames
+     *
+     */
+    public Enumeration getAttributeNames() {
+        return request.getAttributeNames();
+    }
+
+    /**
+     * Method getCharacterEncoding
+     *
+     */
+    public String getCharacterEncoding() {
+        return request.getCharacterEncoding();
+    }
+
+    /**
+     * Method getContentLength
+     *
+     */
+    public int getContentLength() {
+        return request.getContentLength();
+    }
+
+    /**
+     * Method getContentType
+     *
+     */
+    public String getContentType() {
+        return request.getContentType();
+    }
+
+    /**
+     * Method getInputStream
+     *
+     *
+     * @throws IOException
+     */
+    public ServletInputStream getInputStream() throws IOException {
+        return request.getInputStream();
+    }
+
+    /**
+     * Method getProtocol
+     *
+     */
+    public String getProtocol() {
+        return request.getProtocol();
+    }
+
+    /**
+     * Method getScheme
+     *
+     */
+    public String getScheme() {
+        return request.getScheme();
+    }
+
+    /**
+     * Method getServerName
+     *
+     */
+    public String getServerName() {
+        return request.getServerName();
+    }
+
+    /**
+     * Method getServerPort
+     *
+     */
+    public int getServerPort() {
+        return request.getServerPort();
+    }
+
+    /**
+     * Method getReader
+     *
+     *
+     * @throws IOException
+     */
+    public BufferedReader getReader() throws IOException {
+        return request.getReader();
+    }
+
+    /**
+     * Method getRemoteAddr
+     *
+     */
+    public String getRemoteAddr() {
+        return request.getRemoteAddr();
+    }
+
+    /**
+     * Method getRemoteHost
+     *
+     */
+    public String getRemoteHost() {
+        return request.getRemoteHost();
+    }
+
+    /**
+     * Method setAttribute
+     *
+     * @param name
+     * @param o
+     */
+    public void setAttribute(String name, Object o) {
+        request.setAttribute(name, o);
+    }
+
+    /**
+     * Method removeAttribute
+     *
+     * @param name
+     */
+    public void removeAttribute(String name) {
+        request.removeAttribute(name);
+    }
+
+    /**
+     * Method getLocale
+     *
+     */
+    public Locale getLocale() {
+        return request.getLocale();
+    }
+
+    /**
+     * Method getLocales
+     *
+     */
+    public Enumeration getLocales() {
+        return request.getLocales();
+    }
+
+    /**
+     * Method isSecure
+     *
+     */
+    public boolean isSecure() {
+        return request.isSecure();
+    }
+
+    /**
+     * Method getRequestDispatcher
+     *
+     * @param path
+     *
+     */
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return request.getRequestDispatcher(path);
+    }
+
+    /**
+     * Method getRealPath
+     *
+     * @param path
+     *
+     */
+    public String getRealPath(String path) {
+        return request.getRealPath(path);
+    }
+
+    /**
+     * Method getAuthType
+     *
+     */
+    public String getAuthType() {
+        return request.getAuthType();
+    }
+
+    /**
+     * Method getCookies
+     *
+     */
+    public Cookie[] getCookies() {
+        return request.getCookies();
+    }
+
+    /**
+     * Method getDateHeader
+     *
+     * @param name
+     *
+     */
+    public long getDateHeader(String name) {
+        return request.getDateHeader(name);
+    }
+
+    /**
+     * Method getHeader
+     *
+     * @param name
+     *
+     */
+    public String getHeader(String name) {
+        return request.getHeader(name);
+    }
+
+    /**
+     * Method getHeaders
+     *
+     * @param name
+     *
+     */
+    public Enumeration getHeaders(String name) {
+        return request.getHeaders(name);
+    }
+
+    /**
+     * Method getHeaderNames
+     *
+     */
+    public Enumeration getHeaderNames() {
+        return request.getHeaderNames();
+    }
+
+    /**
+     * Method getIntHeader
+     *
+     * @param name
+     *
+     */
+    public int getIntHeader(String name) {
+        return request.getIntHeader(name);
+    }
+
+    /**
+     * Method getMethod
+     *
+     */
+    public String getMethod() {
+        return request.getMethod();
+    }
+
+    /**
+     * Method getPathInfo
+     *
+     */
+    public String getPathInfo() {
+        return request.getPathInfo();
+    }
+
+    /**
+     * Method getPathTranslated
+     *
+     */
+    public String getPathTranslated() {
+        return request.getPathTranslated();
+    }
+
+    /**
+     * Method getContextPath
+     *
+     */
+    public String getContextPath() {
+        return request.getContextPath();
+    }
+
+    /**
+     * Method getQueryString
+     *
+     */
+    public String getQueryString() {
+        return request.getQueryString();
+    }
+
+    /**
+     * Method getRemoteUser
+     *
+     */
+    public String getRemoteUser() {
+        return request.getRemoteUser();
+    }
+
+    /**
+     * Method isUserInRole
+     *
+     * @param role
+     *
+     */
+    public boolean isUserInRole(String role) {
+        return request.isUserInRole(role);
+    }
+
+    /**
+     * Method getUserPrincipal
+     *
+     */
+    public Principal getUserPrincipal() {
+        return request.getUserPrincipal();
+    }
+
+    /**
+     * Method getRequestedSessionId
+     *
+     */
+    public String getRequestedSessionId() {
+        return request.getRequestedSessionId();
+    }
+
+    /**
+     * Method getRequestURI
+     *
+     */
+    public String getRequestURI() {
+        return request.getRequestURI();
+    }
+
+    /**
+     * Method getServletPath
+     *
+     */
+    public String getServletPath() {
+        return request.getServletPath();
+    }
+
+    /**
+     * Method getSession
+     *
+     * @param create
+     *
+     */
+    public HttpSession getSession(boolean create) {
+        return request.getSession(create);
+    }
+
+    /**
+     * Method getSession
+     *
+     */
+    public HttpSession getSession() {
+        return request.getSession();
+    }
+
+    /**
+     * Method isRequestedSessionIdValid
+     *
+     */
+    public boolean isRequestedSessionIdValid() {
+        return request.isRequestedSessionIdValid();
+    }
+
+    /**
+     * Method isRequestedSessionIdFromCookie
+     *
+     */
+    public boolean isRequestedSessionIdFromCookie() {
+        return request.isRequestedSessionIdFromCookie();
+    }
+
+    /**
+     * Method isRequestedSessionIdFromURL
+     *
+     */
+    public boolean isRequestedSessionIdFromURL() {
+        return request.isRequestedSessionIdFromURL();
+    }
+
+    /**
+     * Method isRequestedSessionIdFromUrl
+     * @deprecated use {@link #isRequestedSessionIdFromURL()} instead
+     */
+    public boolean isRequestedSessionIdFromUrl() {
+        return request.isRequestedSessionIdFromURL();
+    }
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.http.HttpServletRequest#getRequestURL()
+	 */
+	public StringBuffer getRequestURL() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#getParameterMap()
+	 */
+	public Map getParameterMap() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+	 */
+	public void setCharacterEncoding(String arg0)
+		throws UnsupportedEncodingException {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartParser.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/MultipartParser.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,351 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * This class is used to implement a multipart request wrapper.
+ * It will parse the http post stream and and fill it's hashtable with values.
+ *
+ * The hashtable will contain:
+ * Vector: inline part values
+ * FilePart: file part
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: MultipartParser.java,v 1.8 2004/03/11 18:21:48 joerg Exp $
+ */
+public class MultipartParser {
+
+    private final static int FILE_BUFFER_SIZE = 4096;
+
+    private static final int MAX_BOUNDARY_SIZE = 128;
+
+    private boolean saveUploadedFilesToDisk;
+
+    private File uploadDirectory = null;
+
+    private boolean allowOverwrite;
+
+    private boolean silentlyRename;
+    
+    private int maxUploadSize;
+
+    private String characterEncoding;
+    
+    private Hashtable parts;
+    
+    /**
+     * Constructor, parses given request
+     *
+     * @param saveUploadedFilesToDisk Write fileparts to the uploadDirectory. If true the corresponding object
+     *              in the hashtable will contain a FilePartFile, if false a FilePartArray
+     * @param uploadDirectory The directory to write to if saveUploadedFilesToDisk is true.
+     * @param allowOverwrite Allow existing files to be overwritten.
+     * @param silentlyRename If file exists rename file (using filename+number).
+     * @param maxUploadSize The maximum content length accepted.
+     * @param characterEncoding The character encoding to be used.
+     */
+    public MultipartParser(boolean saveUploadedFilesToDisk,
+                           File uploadDirectory,
+                           boolean allowOverwrite,
+                           boolean silentlyRename,
+                           int maxUploadSize,
+                           String characterEncoding)
+    {
+        this.saveUploadedFilesToDisk = saveUploadedFilesToDisk;
+        this.uploadDirectory = uploadDirectory;
+        this.allowOverwrite = allowOverwrite;
+        this.silentlyRename = silentlyRename;
+        this.maxUploadSize = maxUploadSize;
+        this.characterEncoding = characterEncoding;
+    }
+
+    public Hashtable getParts(int contentLength, String contentType, InputStream requestStream)
+    throws IOException, MultipartException {
+        if (contentLength > this.maxUploadSize) {
+            throw new IOException("Content length exceeds maximum upload size");
+        }
+
+        this.parts = new Hashtable();
+        BufferedInputStream bufferedStream = new BufferedInputStream(requestStream);
+        PushbackInputStream pushbackStream = new PushbackInputStream(bufferedStream, MAX_BOUNDARY_SIZE);
+        TokenStream stream = new TokenStream(pushbackStream);
+
+        parseMultiPart(stream, getBoundary(contentType));
+
+        return this.parts;    
+    }
+    
+    public Hashtable getParts(HttpServletRequest request) throws IOException, MultipartException {
+        return getParts(request.getContentLength(), request.getContentType(), request.getInputStream());    
+    }
+    
+    /**
+     * Parse a multipart block
+     *
+     * @param ts
+     * @param boundary
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parseMultiPart(TokenStream ts, String boundary)
+            throws IOException, MultipartException {
+
+        ts.setBoundary(boundary.getBytes());
+        ts.read();    // read first boundary away
+        ts.setBoundary(("\r\n" + boundary).getBytes());
+
+        while (ts.getState() == TokenStream.STATE_NEXTPART) {
+            ts.nextPart();
+            parsePart(ts);
+        }
+
+        if (ts.getState() != TokenStream.STATE_ENDMULTIPART) {    // sanity check
+            throw new MultipartException("Malformed stream");
+        }
+    }
+
+    /**
+     * Parse a single part
+     *
+     * @param ts
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parsePart(TokenStream ts)
+            throws IOException, MultipartException {
+
+        Hashtable headers = new Hashtable();
+        headers = readHeaders(ts);
+        try {
+            if (headers.containsKey("filename")) {
+		        if (!"".equals(headers.get("filename"))) {
+                	parseFilePart(ts, headers);
+		        } else {
+        			// IE6 sends an empty part with filename="" for
+        			// empty upload fields. Just parse away the part
+        			byte[] buf = new byte[32];
+        			while(ts.getState() == TokenStream.STATE_READING)
+        				ts.read(buf);  
+        		}
+            } else if (((String) headers.get("content-disposition"))
+                    .toLowerCase().equals("form-data")) {
+                parseInlinePart(ts, headers);
+            }
+
+            // FIXME: multipart/mixed parts are untested.
+            else if (((String) headers.get("content-disposition")).toLowerCase()
+                    .indexOf("multipart") > -1) {
+                parseMultiPart(new TokenStream(ts, MAX_BOUNDARY_SIZE),
+                        "--" + (String) headers.get("boundary"));
+                ts.read();    // read past boundary
+            } else {
+                throw new MultipartException("Unknown part type");
+            }
+        } catch (IOException e) {
+            throw new MultipartException("Malformed stream: " + e.getMessage());
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            throw new MultipartException("Malformed header");
+        }
+    }
+
+    /**
+     * Parse a file part
+     *
+     * @param in
+     * @param headers
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parseFilePart(TokenStream in, Hashtable headers)
+            throws IOException, MultipartException {
+
+        byte[] buf = new byte[FILE_BUFFER_SIZE];
+        OutputStream out = null;
+        File file = null;
+
+        if (!saveUploadedFilesToDisk) {
+            out = new ByteArrayOutputStream();
+        } else {
+            String fileName = (String) headers.get("filename");
+            if(File.separatorChar == '\\')
+                fileName = fileName.replace('/','\\');
+            else
+                fileName = fileName.replace('\\','/');
+
+            String filePath = uploadDirectory.getPath() + File.separator;
+            fileName = new File(fileName).getName();
+            file = new File(filePath + fileName);
+
+            if (!allowOverwrite && !file.createNewFile()) {
+                if (silentlyRename) {
+                    int c = 0;
+
+                    do {
+                        file = new File(filePath + c++ + "_" + fileName);
+                    } while (!file.createNewFile());
+                } else {
+                    throw new MultipartException("Duplicate file "
+                            + file.getName() + ".");
+                }
+            }
+
+            out = new FileOutputStream(file);
+        }
+
+        int read = 0;
+        while (in.getState() == TokenStream.STATE_READING) {    // read data
+            read = in.read(buf);
+            out.write(buf, 0, read);
+        }
+
+        out.close();
+        if (file == null) {
+            byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
+
+            this.parts.put(headers.get("name"),
+                    new PartInMemory(headers, new ByteArrayInputStream(bytes),bytes.length));
+        } else {
+            this.parts.put(headers.get("name"), new PartOnDisk(headers, file));
+        }
+    }
+
+    /**
+     * Parse an inline part
+     *
+     * @param in
+     * @param headers
+     *
+     * @throws IOException
+     */
+    private void parseInlinePart(TokenStream in, Hashtable headers)
+            throws IOException {
+
+		// Buffer incoming bytes for proper string decoding (there can be multibyte chars)
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        while (in.getState() == TokenStream.STATE_READING) {
+        	int c = in.read();
+        	if (c != -1) bos.write(c);
+        }
+        
+        String field = (String) headers.get("name");
+        Vector v = (Vector) this.parts.get(field);
+
+        if (v == null) {
+            v = new Vector();
+            this.parts.put(field, v);
+        }
+
+        v.add(new String(bos.toByteArray(), this.characterEncoding));
+    }
+
+    /**
+     * Read part headers
+     *
+     * @param in
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    private Hashtable readHeaders(TokenStream in) throws IOException {
+
+        Hashtable headers = new Hashtable();
+        String hdrline = readln(in);
+
+        while (!"".equals(hdrline)) {
+            StringTokenizer tokenizer = new StringTokenizer(hdrline);
+
+            headers.put(tokenizer.nextToken(" :").toLowerCase(),
+                    tokenizer.nextToken(" :;"));
+
+	        // The extra tokenizer.hasMoreTokens() in headers.put
+	        // handles the filename="" case IE6 submits for an empty
+	        // upload field.
+            while (tokenizer.hasMoreTokens()) {
+                headers.put(tokenizer.nextToken(" ;=\""),
+                        tokenizer.hasMoreTokens()?tokenizer.nextToken("=\""):"");
+            }
+
+            hdrline = readln(in);
+        }
+
+        return headers;
+    }
+
+    /**
+     * Get boundary from contentheader
+     *
+     * @param hdr
+     *
+     * @return
+     */
+    private String getBoundary(String hdr) {
+
+        int start = hdr.toLowerCase().indexOf("boundary=");
+        if (start > -1) {
+            return "--" + hdr.substring(start + 9);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Read string until newline or end of stream
+     *
+     * @param in
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    private String readln(TokenStream in) throws IOException {
+    	
+    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    	
+        int b = in.read();
+
+        while ((b != -1) && (b != '\r')) {
+            bos.write(b);
+            b = in.read();
+        }
+
+        if (b == '\r') {
+            in.read();    // read '\n'
+        }
+
+        return new String(bos.toByteArray(), this.characterEncoding);
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/Part.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/Part.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,99 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.InputStream;
+import java.util.Map;
+
+
+/**
+ * This (abstract) class represents a file part parsed from a http post stream.
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: Part.java,v 1.4 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public abstract class Part {
+
+    private boolean disposeWithRequest = true;
+
+    /** Field headers */
+    protected Map headers;
+
+    protected Part(Map headers) {
+	    this.headers = headers;
+    }
+
+    /**
+     * Returns the part headers
+     */
+    public Map getHeaders() {
+        return headers;
+    }
+
+    /**
+     * Returns the filename
+     */
+    public abstract String getFileName();
+    
+    /**
+     * Returns the original filename
+     */
+    public String getUploadName(){
+        return (String) headers.get("filename");
+    }
+    
+    /**
+     * Returns the length of the file content
+     */
+    public abstract int getSize();
+
+    /**
+     * Returns the mime type (or null if unknown)
+     */
+    public String getMimeType() {
+        return (String) headers.get("content-type");
+    }
+    
+    /**
+     * Do we want any temporary resource held by this part to be cleaned up when processing of
+     * the request that created it is finished? Default is <code>true</code>.
+     * 
+     * @return <code>true</code> if the part should be disposed with the request.
+     */
+    public boolean disposeWithRequest() {
+        return this.disposeWithRequest;
+    }
+    
+    /**
+     * Set the value of the <code>disposeWithRequest</code> flag (default is <code>true</code>).
+     * 
+     * @param dispose <code>true</code> if the part should be disposed after request processing
+     */
+    public void setDisposeWithRequest(boolean dispose) {
+        this.disposeWithRequest = dispose;
+    }
+    
+    /**
+     * Dispose this part.
+     */
+    public abstract void dispose();
+    
+    /**
+     * Returns an InputStream containing the file data
+     * @throws Exception
+     */
+    public abstract InputStream getInputStream() throws Exception;
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartInMemory.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartInMemory.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,79 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * This class represents a file part parsed from a http post stream.
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: PartInMemory.java,v 1.5 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public class PartInMemory extends Part {
+
+    private InputStream in;
+
+    private int size;
+
+    /**
+     * Constructor PartInMemory
+     *
+     * @param headers
+     * @param in
+     * @param size
+     */
+    protected PartInMemory(Map headers, InputStream in, int size) {
+        super(headers);
+        this.in = in;
+        this.size = size;
+    }
+
+    /**
+     * Returns the filename
+     */
+    public String getFileName() {
+        return (String) headers.get("filename");
+    }
+
+    /**
+     * Returns the filesize in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Returns a (ByteArray)InputStream containing the file data
+     *
+     * @throws Exception
+     */
+    public InputStream getInputStream() throws Exception {
+        if (this.in != null) {
+            return this.in;
+        } else {
+            throw new IllegalStateException("This part has already been disposed.");
+        }
+    }
+    
+    /**
+     * Clean the byte array content buffer holding part data
+     */
+    public void dispose() {
+        this.in = null;
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartOnDisk.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/PartOnDisk.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,105 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * This class represents a file part parsed from a http post stream.
+ *
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: PartOnDisk.java,v 1.4 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public class PartOnDisk extends Part {
+
+    /** Field file           */
+    private File file = null;
+    private int size;
+
+    /**
+     * Constructor PartOnDisk
+     *
+     * @param headers
+     * @param file
+     */
+    protected PartOnDisk(Map headers, File file) {
+        super(headers);
+        this.file = file;
+        
+        // Ensure the file will be deleted when we exit the JVM
+        this.file.deleteOnExit();
+        
+        this.size = (int) file.length();
+    }
+
+    /**
+     * Returns the file name
+     */
+    public String getFileName() {
+        return file.getName();
+    }
+
+    /**
+     * Returns the file size in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Returns the file
+     */
+    public File getFile() {
+        return file;
+    }
+
+    /**
+     * Returns a (ByteArray)InputStream containing the file data
+     *
+     * @throws Exception
+     */
+    public InputStream getInputStream() throws Exception {
+        if (this.file != null) {
+            return new FileInputStream(file);
+        } else {
+            throw new IllegalStateException("This part has already been disposed.");
+        }
+    }
+
+    /**
+     * Returns the filename
+     */
+    public String toString() {
+        return file.getPath();
+    }
+    
+    public void dispose() {
+        if (this.file != null) {
+            this.file.delete();
+            this.file = null;
+        }
+    }
+    
+    public void finalize() throws Throwable {
+        // Ensure the file has been deleted
+        dispose();
+        
+        super.finalize();
+    }
+}

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/RequestFactory.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/RequestFactory.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,102 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * This is the interface of Request Wrapper in Cocoon.
+ *
+ * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
+ * @version CVS $Id: RequestFactory.java,v 1.3 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+public class RequestFactory {
+
+    private boolean saveUploadedFilesToDisk;
+
+    private File uploadDirectory;
+
+    private boolean allowOverwrite;
+
+    private boolean silentlyRename;
+
+    private String defaultCharEncoding;
+    
+    private int maxUploadSize;
+    
+    public RequestFactory (boolean saveUploadedFilesToDisk, 
+                           File uploadDirectory, 
+                           boolean allowOverwrite, 
+                           boolean silentlyRename, 
+                           int maxUploadSize,
+                           String defaultCharEncoding) {
+       this.saveUploadedFilesToDisk = saveUploadedFilesToDisk;
+       this.uploadDirectory = uploadDirectory;
+       this.allowOverwrite = allowOverwrite;
+       this.silentlyRename = silentlyRename;
+       this.maxUploadSize = maxUploadSize;
+       this.defaultCharEncoding = defaultCharEncoding;
+       
+       if (saveUploadedFilesToDisk) {
+           // Empty the contents of the upload directory
+           File[] files = uploadDirectory.listFiles();
+           for (int i = 0; i < files.length; i++) {
+               files[i].delete();
+           }
+       }
+    }
+
+    /**
+     * If the request includes a "multipart/form-data", then wrap it with
+     * methods that allow easier connection to those objects since the servlet
+     * API doesn't provide those methods directly.
+     */
+    public HttpServletRequest getServletRequest(HttpServletRequest request) throws IOException, MultipartException {
+        HttpServletRequest req = request;
+        String contentType = request.getContentType();
+        
+        if ((contentType != null) && (contentType.toLowerCase().indexOf("multipart/form-data") > -1)) {
+            if (request.getContentLength() > maxUploadSize) {
+                throw new IOException("Content length exceeds maximum upload size.");
+            }
+ 
+            String charEncoding = request.getCharacterEncoding();
+            if (charEncoding == null || charEncoding.equals("")) {
+                charEncoding = this.defaultCharEncoding;
+            }
+            
+            MultipartParser parser = new MultipartParser(
+                    this.saveUploadedFilesToDisk, 
+                    this.uploadDirectory, 
+                    this.allowOverwrite, 
+                    this.silentlyRename, 
+                    this.maxUploadSize,
+                    charEncoding);
+                    
+            Hashtable parts = parser.getParts(request);
+            
+            req = new MultipartHttpServletRequest(request,parts);
+        }
+
+        return req;
+    }
+    
+}
\ No newline at end of file

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/TokenStream.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/servlet/multipart/TokenStream.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,259 @@
+/*
+ * 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.butterfly.servlet.multipart;
+
+import java.io.IOException;
+import java.io.PushbackInputStream;
+
+/**
+ * Utility class for MultipartParser. Divides the inputstream into parts
+ * separated by a given boundary.
+ *
+ * A newline is espected after each boundary and is parsed away.
+ * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
+ * @version CVS $Id: TokenStream.java,v 1.4 2004/03/05 13:02:58 bdelacretaz Exp $
+ */
+class TokenStream extends PushbackInputStream {
+
+    /**
+     * Initial state, no boundary has been set.
+     */
+    public static final int STATE_NOBOUNDARY = -1;
+
+    /**
+     * Fully read a part, now at the beginning of a new part
+     */
+    public static final int STATE_NEXTPART = -2;
+
+    /**
+     * Read last boundary, end of multipart block
+     */
+    public static final int STATE_ENDMULTIPART = -3;
+
+    /**
+     * End of stream, this should not happen
+     */
+    public static final int STATE_ENDOFSTREAM = -4;
+
+    /**
+     * Currently reading a part
+     */
+    public static final int STATE_READING = -5;
+
+    /** Field in           */
+    private PushbackInputStream in = null;
+
+    /** Field boundary           */
+    private byte[] boundary = null;
+
+    /** Field state           */
+    private int state = STATE_NOBOUNDARY;
+
+    /**
+     * Creates a new pushback token stream from in.
+     *
+     * @param in The input stream
+     */
+    public TokenStream(PushbackInputStream in) {
+        this(in,1);
+    }
+    
+    /**
+     * Creates a new pushback token stream from in.
+     *
+     * @param in The input stream
+     * @param size Size (in bytes) of the pushback buffer
+     */
+    public TokenStream(PushbackInputStream in, int size) {
+        super(in,size);
+        this.in = in;
+    }
+
+    /**
+     * Sets the boundary to scan for
+     *
+     * @param boundary A byte array containg the boundary
+     *
+     * @throws MultipartException
+     */
+    public void setBoundary(byte[] boundary) throws MultipartException {
+        this.boundary = boundary;
+        if (state == STATE_NOBOUNDARY) {
+            state = STATE_READING;
+        }
+    }
+
+    /**
+     * Start reading the next part in the stream. This method may only be called
+     * if state is STATE_NEXTPART. It will throw a MultipartException if not.
+     *
+     * @throws MultipartException
+     */
+    public void nextPart() throws MultipartException {
+        if (state != STATE_NEXTPART) {
+            throw new MultipartException("Illegal state");
+        }
+        state = STATE_READING;
+    }
+
+    /**
+     * Return the stream state
+     *
+     * @return
+     */
+    public int getState() {
+        return state;
+    }
+
+    /**
+     * Fill the ouput buffer until either it's full, the boundary has been reached or
+     * the end of the inputstream has been reached.
+     * When a boundary is reached it is entirely read away including trailing \r's and \n's.
+     * It will not be written to the output buffer.
+     * The stream state is updated after each call.
+     *
+     * @param out The output buffer
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    private int readToBoundary(byte[] out) throws IOException {
+        if (state != STATE_READING) {
+            return 0;
+        }
+        int boundaryIndex = 0;
+        int written = 0;
+        int b = in.read();
+
+        while (true) {
+            while ((byte) b != boundary[0]) {
+                if (b == -1) {
+                    state = STATE_ENDOFSTREAM;
+                    return written;
+                }
+                out[written++] = (byte) b;
+
+                if (written == out.length) {
+                    return written;
+                }
+                b = in.read();
+            }
+            boundaryIndex = 0;                         // we know the first byte matched
+            // check for boundary
+            while ((boundaryIndex < boundary.length)
+                    && ((byte) b == boundary[boundaryIndex])) {
+                b = in.read();
+                boundaryIndex++;
+            }
+
+            if (boundaryIndex == boundary.length) {    // matched boundary
+                if (b != -1) {
+                    if (b == '\r') {                   // newline, another part follows
+                        state = STATE_NEXTPART;
+                        in.read();
+                    } else if (b == '-') {             // hyphen, end of multipart
+                        state = STATE_ENDMULTIPART;
+                        in.read();                     // read next hyphen
+                        in.read();                     // read \r
+                        in.read();                     // read \n
+                    } else {                           // something else, error
+                        throw new IOException(
+                                "Unexpected character after boundary");
+                    }
+                } else {    // nothing after boundary, this shouldn't happen either
+                    state = STATE_ENDOFSTREAM;
+                }
+                return written;
+            } else {                                   // did not match boundary
+                // bytes skipped, write first skipped byte, push back the rest
+                if (b != -1) {                         // b may be -1
+                    in.unread(b);                      // the non-matching byte
+                }
+                in.unread(boundary, 1,
+                        boundaryIndex - 1);          // unread skipped boundary data
+                out[written++] = boundary[0];
+                if (written == out.length) {
+                    return written;
+                }
+            }
+            b = in.read();
+        }
+    }
+
+    /**
+     * @see java.io.InputStream#read(byte[])
+     *
+     * @param out
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public int read(byte[] out) throws IOException {
+        if (state != STATE_READING) {
+            return 0;
+        }
+        return readToBoundary(out);
+    }
+
+    /**
+     * @see java.io.InputStream#read(byte[],int,int)
+     *
+     * @param out
+     * @param off
+     * @param len
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public int read(byte[] out, int off, int len) throws IOException {
+        if ((off < 0) || (off >= out.length)) {
+            throw new IOException("Buffer offset outside buffer");
+        }
+        if (off + len >= out.length) {
+            throw new IOException("Buffer end outside buffer");
+        }
+        if (len < 0) {
+            throw new IOException("Length must be a positive integer");
+        }
+        byte[] buf = new byte[len];
+        int read = read(buf);
+        if (read > 0) {
+            System.arraycopy(buf, 0, out, off, read);
+        }
+        return read;
+    }
+
+    /**
+     * @see java.io.InputStream#read()
+     *
+     * @return
+     *
+     * @throws IOException
+     */
+    public int read() throws IOException {
+        byte[] buf = new byte[1];
+        int read = read(buf);
+
+        if (read == 0) {
+            return -1;
+        } else {
+            return buf[0];
+        }
+    }
+}

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/sitemap/SitemapOutputComponent.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/sitemap/SitemapOutputComponent.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/sitemap/SitemapOutputComponent.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/Source.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/Source.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/Source.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceException.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceFactory.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceFactory.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceFactory.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceNotFoundException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceNotFoundException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceNotFoundException.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceResolver.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceResolver.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceResolver.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceUtil.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceUtil.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceUtil.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceValidity.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceValidity.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/SourceValidity.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/URIAbsolutizer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/URIAbsolutizer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/URIAbsolutizer.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSource.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSource.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSource.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSourceFactory.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSourceFactory.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/FileSourceFactory.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSource.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSource.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSource.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSourceFactory.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSourceFactory.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/URLSourceFactory.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/validity/FileTimeStampValidity.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/validity/FileTimeStampValidity.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/source/impl/validity/FileTimeStampValidity.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/Transformer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/Transformer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/Transformer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/TraxTransformer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/TraxTransformer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/transformation/TraxTransformer.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/util/BufferedOutputStream.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/util/BufferedOutputStream.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,160 @@
+/*
+ * 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.butterfly.util;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This class is like the {@link java.io.BufferedOutputStream} but it
+ * extends it with a logic to count the number of bytes written to
+ * the output stream.
+ * 
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: BufferedOutputStream.java,v 1.4 2004/06/24 07:14:44 cziegeler Exp $
+ * @since   2.1
+ */
+public final class BufferedOutputStream extends FilterOutputStream {
+    
+    protected byte buf[];
+
+    protected int count;
+    
+    /**
+     * Creates a new buffered output stream to write data to the 
+     * specified underlying output stream with a default 8192-byte
+     * buffer size.
+     *
+     * @param   out   the underlying output stream.
+     */
+    public BufferedOutputStream(OutputStream out) {
+        this(out, 8192);
+    }
+
+    /**
+     * Creates a new buffered output stream to write data to the 
+     * specified underlying output stream with the specified buffer 
+     * size. 
+     *
+     * @param   out    the underlying output stream.
+     * @param   size   the buffer size.
+     * @exception IllegalArgumentException if size <= 0.
+     */
+    public BufferedOutputStream(OutputStream out, int size) {
+        super(out);
+        if (size <= 0) {
+            throw new IllegalArgumentException("Buffer size <= 0");
+        }
+        this.buf = new byte[size];
+    }
+
+    /**
+     * Writes the specified byte to this buffered output stream. 
+     *
+     * @param      b   the byte to be written.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void write(int b) throws IOException {
+        if (this.count >= this.buf.length) {
+            this.incBuffer();
+        }
+        this.buf[count++] = (byte)b;
+    }
+
+    /**
+     * Writes <code>len</code> bytes from the specified byte array 
+     * starting at offset <code>off</code> to this buffered output stream.
+     *
+     * <p> Ordinarily this method stores bytes from the given array into this
+     * stream's buffer, flushing the buffer to the underlying output stream as
+     * needed.  If the requested length is at least as large as this stream's
+     * buffer, however, then this method will flush the buffer and write the
+     * bytes directly to the underlying output stream.  Thus redundant
+     * <code>BufferedOutputStream</code>s will not copy data unnecessarily.
+     *
+     * @param      b     the data.
+     * @param      off   the start offset in the data.
+     * @param      len   the number of bytes to write.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void write(byte b[], int off, int len) throws IOException {
+        while (len > buf.length - count) {
+            this.incBuffer();
+        }
+        System.arraycopy(b, off, buf, count, len);
+        count += len;
+    }
+
+    /**
+     * Flushes this buffered output stream. 
+     * We don't flush here. 
+     *
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void flush() throws IOException {
+    }
+
+    /**
+     * Closes this buffered output stream.
+     * Flush before closing.
+     *
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void close() throws IOException {
+        realFlush();
+        super.close ();
+    }
+
+    /**
+     * Flushes this buffered output stream. 
+     * We don't flush here. 
+     */
+    public void realFlush() throws IOException {
+        this.writeBuffer();
+        this.out.flush();
+    }
+    
+    /**
+     * Write the buffer
+     */
+    private void writeBuffer() 
+    throws IOException {
+        if (this.count > 0) {
+            this.out.write(this.buf, 0, this.count);
+        }
+    }
+
+    /**
+     * Increment the buffer
+     */
+    private void incBuffer() {
+        // currently we double the buffer size
+        // this is not so fast but is a very simple logic
+        byte[] newBuf = new byte[this.buf.length * 2];
+        System.arraycopy(this.buf, 0, newBuf, 0, this.buf.length);
+        this.buf = newBuf;
+    }
+    
+    /**
+     * Clear/reset the buffer
+     */
+    public void clearBuffer() {
+        this.count = 0;
+    }
+    
+}
+

Added: cocoon/branches/butterfly/src/java/org/apache/butterfly/util/NetUtils.java
==============================================================================
--- (empty file)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/util/NetUtils.java	Sat Jul 31 09:06:07 2004
@@ -0,0 +1,544 @@
+/*
+ * 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.butterfly.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.BitSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * A collection of <code>File</code>, <code>URL</code> and filename
+ * utility methods
+ *
+ * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
+ * @version CVS $Id: NetUtils.java,v 1.17 2004/07/11 17:18:37 antonio Exp $
+ */
+public class NetUtils {
+
+    /**
+     * Array containing the safe characters set as defined by RFC 1738
+     */
+    private static BitSet safeCharacters;
+
+    private static final char[] hexadecimal =
+            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+             'A', 'B', 'C', 'D', 'E', 'F'};
+
+    static {
+        safeCharacters = new BitSet(256);
+        int i;
+        // 'lowalpha' rule
+        for (i = 'a'; i <= 'z'; i++) {
+            safeCharacters.set(i);
+        }
+        // 'hialpha' rule
+        for (i = 'A'; i <= 'Z'; i++) {
+            safeCharacters.set(i);
+        }
+        // 'digit' rule
+        for (i = '0'; i <= '9'; i++) {
+            safeCharacters.set(i);
+        }
+
+        // 'safe' rule
+        safeCharacters.set('$');
+        safeCharacters.set('-');
+        safeCharacters.set('_');
+        safeCharacters.set('.');
+        safeCharacters.set('+');
+
+        // 'extra' rule
+        safeCharacters.set('!');
+        safeCharacters.set('*');
+        safeCharacters.set('\'');
+        safeCharacters.set('(');
+        safeCharacters.set(')');
+        safeCharacters.set(',');
+
+        // special characters common to http: file: and ftp: URLs ('fsegment' and 'hsegment' rules)
+        safeCharacters.set('/');
+        safeCharacters.set(':');
+        safeCharacters.set('@');
+        safeCharacters.set('&');
+        safeCharacters.set('=');
+    }
+
+    /**
+     * Decode a path.
+     *
+     * <p>Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded bytes.
+     * <p>The validity of the input path is not checked (i.e. characters that were not encoded will
+     * not be reported as errors).
+     * <p>This method differs from URLDecoder.decode in that it always uses UTF-8 (while URLDecoder
+     * uses the platform default encoding, often ISO-8859-1), and doesn't translate + characters to spaces.
+     *
+     * @param path the path to decode
+     * @return the decoded path
+     */
+    public static String decodePath(String path) {
+        StringBuffer translatedPath = new StringBuffer(path.length());
+        byte[] encodedchars = new byte[path.length() / 3];
+        int i = 0;
+        int length = path.length();
+        int encodedcharsLength = 0;
+        while (i < length) {
+            if (path.charAt(i) == '%') {
+                // we must process all consecutive %-encoded characters in one go, because they represent
+                // an UTF-8 encoded string, and in UTF-8 one character can be encoded as multiple bytes
+                while (i < length && path.charAt(i) == '%') {
+                    if (i + 2 < length) {
+                        try {
+                            byte x = (byte)Integer.parseInt(path.substring(i + 1, i + 3), 16);
+                            encodedchars[encodedcharsLength] = x;
+                        } catch (NumberFormatException e) {
+                            throw new IllegalArgumentException("NetUtils.decodePath: " +
+                                                               "Illegal hex characters in pattern %" + path.substring(i + 1, i + 3));
+                        }
+                        encodedcharsLength++;
+                        i += 3;
+                    } else {
+                        throw new IllegalArgumentException("NetUtils.decodePath: " +
+                                                           "% character should be followed by 2 hexadecimal characters.");
+                    }
+                }
+                try {
+                    String translatedPart = new String(encodedchars, 0, encodedcharsLength, "UTF-8");
+                    translatedPath.append(translatedPart);
+                } catch (UnsupportedEncodingException e) {
+                    // the situation that UTF-8 is not supported is quite theoretical, so throw a runtime exception
+                    throw new RuntimeException("Problem in decodePath: UTF-8 encoding not supported.");
+                }
+                encodedcharsLength = 0;
+            } else {
+                // a normal character
+                translatedPath.append(path.charAt(i));
+                i++;
+            }
+        }
+        return translatedPath.toString();
+    }
+
+    /**
+     * Encode a path as required by the URL specificatin (<a href="http://www.ietf.org/rfc/rfc1738.txt">
+     * RFC 1738</a>). This differs from <code>java.net.URLEncoder.encode()</code> which encodes according
+     * to the <code>x-www-form-urlencoded</code> MIME format.
+     *
+     * @param path the path to encode
+     * @return the encoded path
+     */
+    public static String encodePath(String path) {
+       // stolen from org.apache.catalina.servlets.DefaultServlet ;)
+
+        /**
+         * Note: This code portion is very similar to URLEncoder.encode.
+         * Unfortunately, there is no way to specify to the URLEncoder which
+         * characters should be encoded. Here, ' ' should be encoded as "%20"
+         * and '/' shouldn't be encoded.
+         */
+
+        int maxBytesPerChar = 10;
+        StringBuffer rewrittenPath = new StringBuffer(path.length());
+        ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
+        OutputStreamWriter writer = null;
+        try {
+            writer = new OutputStreamWriter(buf, "UTF8");
+        } catch (Exception e) {
+            e.printStackTrace();
+            writer = new OutputStreamWriter(buf);
+        }
+
+        for (int i = 0; i < path.length(); i++) {
+            int c = path.charAt(i);
+            if (safeCharacters.get(c)) {
+                rewrittenPath.append((char)c);
+            } else {
+                // convert to external encoding before hex conversion
+                try {
+                    writer.write(c);
+                    writer.flush();
+                } catch(IOException e) {
+                    buf.reset();
+                    continue;
+                }
+                byte[] ba = buf.toByteArray();
+                for (int j = 0; j < ba.length; j++) {
+                    // Converting each byte in the buffer
+                    byte toEncode = ba[j];
+                    rewrittenPath.append('%');
+                    int low = (toEncode & 0x0f);
+                    int high = ((toEncode & 0xf0) >> 4);
+                    rewrittenPath.append(hexadecimal[high]);
+                    rewrittenPath.append(hexadecimal[low]);
+                }
+                buf.reset();
+            }
+        }
+        return rewrittenPath.toString();
+    }
+
+    /**
+     * Returns the path of the given resource.
+     *
+     * @param uri The URI of the resource
+     * @return the resource path
+     */
+    public static String getPath(String uri) {
+        int i = uri.lastIndexOf('/');
+        if (i > -1) {
+            return uri.substring(0, i);
+        }
+        i = uri.indexOf(':');
+        return (i > -1) ? uri.substring(i + 1, uri.length()) : "";
+    }
+
+    /**
+     * Remove path and file information from a filename returning only its
+     * extension  component
+     *
+     * @param uri The filename
+     * @return The filename extension (with starting dot!)
+     */
+    public static String getExtension(String uri) {
+        int dot = uri.lastIndexOf('.');
+        if (dot > -1) {
+            uri = uri.substring(dot);
+            int slash = uri.lastIndexOf('/');
+            if (slash > -1) {
+                return null;
+            } else {
+                int sharp = uri.lastIndexOf('#');
+                if (sharp > -1) {
+                    // uri starts with dot already
+                    return uri.substring(0, sharp);
+                } else {
+                    int mark = uri.lastIndexOf('?');
+                    if (mark > -1) {
+                        // uri starts with dot already
+                        return uri.substring(0, mark);
+                    } else {
+                        return uri;
+                    }
+                }
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Absolutize a relative resource path on the given absolute base path.
+     *
+     * @param path The absolute base path
+     * @param resource The relative resource path
+     * @return The absolutized resource path
+     */
+    public static String absolutize(String path, String resource) {
+        if (StringUtils.isEmpty(path)) {
+            return resource;
+        } else if (StringUtils.isEmpty(resource)) {
+            return path;
+        } else if (resource.charAt(0) == '/') {
+            // Resource path is already absolute
+            return resource;
+        }
+
+        boolean slash = (path.charAt(path.length() - 1) == '/');
+
+        StringBuffer b = new StringBuffer();
+        b.append(path);
+        if (!slash) {
+            b.append('/');
+        }
+        b.append(resource);
+        return b.toString();
+    }
+
+    /**
+     * Relativize an absolute resource on a given absolute path.
+     *
+     * @param path The absolute path
+     * @param absoluteResource The absolute resource
+     * @return the resource relative to the given path
+     */
+    public static String relativize(String path, String absoluteResource) {
+        if (StringUtils.isEmpty(path)) {
+            return absoluteResource;
+        }
+
+        if (path.charAt(path.length() - 1) != '/') {
+            path += "/";
+        }
+
+        if (absoluteResource.startsWith(path)) {
+            // resource is direct descentant
+            return absoluteResource.substring(path.length());
+        } else {
+            // resource is not direct descendant
+            int index = StringUtils.indexOfDifference(path, absoluteResource);
+            if (index > 0 && path.charAt(index-1) != '/') {
+                index = path.substring(0, index).lastIndexOf('/');
+                index++;
+            }
+            String pathDiff = path.substring(index);
+            String resource = absoluteResource.substring(index);
+            int levels = StringUtils.countMatches(pathDiff, "/");
+            StringBuffer b = new StringBuffer();
+            for (int i = 0; i < levels; i++) {
+                b.append("../");
+            }
+            b.append(resource);
+            return b.toString();
+        }
+    }
+
+    /**
+     * Normalize a uri containing ../ and ./ paths.
+     *
+     * @param uri The uri path to normalize
+     * @return The normalized uri
+     */
+    public static String normalize(String uri) {
+        if ("".equals(uri)) {
+            return uri;
+        }
+        int leadingSlashes = 0;
+        for (leadingSlashes = 0 ; leadingSlashes < uri.length()
+                && uri.charAt(leadingSlashes) == '/' ; ++leadingSlashes) {}
+        boolean isDir = (uri.charAt(uri.length() - 1) == '/');
+        StringTokenizer st = new StringTokenizer(uri, "/");
+        LinkedList clean = new LinkedList();
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if ("..".equals(token)) {
+                if (! clean.isEmpty() && ! "..".equals(clean.getLast())) {
+                    clean.removeLast();
+                    if (! st.hasMoreTokens()) {
+                        isDir = true;
+                    }
+                } else {
+                    clean.add("..");
+                }
+            } else if (! ".".equals(token) && ! "".equals(token)) {
+                clean.add(token);
+            }
+        }
+        StringBuffer sb = new StringBuffer();
+        while (leadingSlashes-- > 0) {
+            sb.append('/');
+        }
+        for (Iterator it = clean.iterator() ; it.hasNext() ; ) {
+            sb.append(it.next());
+            if (it.hasNext()) {
+                sb.append('/');
+            }
+        }
+        if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') {
+            sb.append('/');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Remove parameters from a uri.
+     * Resulting Map will have either String for single value attributes,
+     * or String arrays for multivalue attributes.
+     *
+     * @param uri The uri path to deparameterize.
+     * @param parameters The map that collects parameters.
+     * @return The cleaned uri
+     */
+    public static String deparameterize(String uri, Map parameters) {
+        int i = uri.lastIndexOf('?');
+        if (i == -1) {
+            return uri;
+        }
+
+        String[] params = StringUtils.split(uri.substring(i + 1), '&');
+        for (int j = 0; j < params.length; j++) {
+            String p = params[j];
+            int k = p.indexOf('=');
+            if (k == -1) {
+                break;
+            }
+            String name = p.substring(0, k);
+            String value = p.substring(k + 1);
+            Object values = parameters.get(name);
+            if (values == null) {
+                parameters.put(name, value);
+            } else if (values.getClass().isArray()) {
+                String[] v1 = (String[])values;
+                String[] v2 = new String[v1.length + 1];
+                System.arraycopy(v1, 0, v2, 0, v1.length);
+                v2[v1.length] = value;
+                parameters.put(name, v2);
+            } else {
+                parameters.put(name, new String[]{values.toString(), value});
+            }
+        }
+        return uri.substring(0, i);
+    }
+
+    /**
+     * Add parameters stored in the Map to the uri string.
+     * Map can contain Object values which will be converted to the string,
+     * or Object arrays, which will be treated as multivalue attributes.
+     *
+     * @param uri The uri to add parameters into
+     * @param parameters The map containing parameters to be added
+     * @return The uri with added parameters
+     */
+    public static String parameterize(String uri, Map parameters) {
+        if (parameters.size() == 0) {
+            return uri;
+        }
+
+        StringBuffer buffer = new StringBuffer(uri);
+        if (uri.indexOf('?') == -1) {
+            buffer.append('?');
+        } else {
+            buffer.append('&');
+        }
+
+        for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry)i.next();
+            if (entry.getValue().getClass().isArray()) {
+                Object[] value = (Object[])entry.getValue();
+                for (int j = 0; j < value.length; j++) {
+                    if (j > 0) {
+                        buffer.append('&');
+                    }
+                    buffer.append(entry.getKey());
+                    buffer.append('=');
+                    buffer.append(value[j]);
+                }
+            } else {
+                buffer.append(entry.getKey());
+                buffer.append('=');
+                buffer.append(entry.getValue());
+            }
+            if (i.hasNext()) {
+                buffer.append('&');
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Create new <code>SourceParameters</code> with the same
+     * parameters as the current request
+    public static SourceParameters createParameters(Request request) {
+        final SourceParameters pars = new SourceParameters();
+
+        if (null != request) {
+            final Enumeration names = request.getParameterNames();
+            while (names.hasMoreElements()) {
+                final String current = (String)names.nextElement();
+                final String[] values = request.getParameterValues(current);
+                if (null != values) {
+                    for(int i=0; i < values.length; i++) {
+                        pars.setParameter(current, values[i]);
+                    }
+                }
+            }
+        }
+
+        return pars;
+    }
+     */
+
+    /**
+     * Remove any authorisation details from a URI
+     */
+    public static String removeAuthorisation(String uri) {
+        if (uri.indexOf("@") != -1 && (uri.startsWith("ftp://") || uri.startsWith("http://"))) {
+            return uri.substring(0, uri.indexOf(":") + 2) + uri.substring(uri.indexOf("@") + 1);
+        }
+        return uri;
+    }
+
+    // FIXME Remove when JDK1.3 support is removed.
+    private static Method urlEncode;
+    private static Method urlDecode;
+
+    static {
+        if (SystemUtils.isJavaVersionAtLeast(140)) {
+            try {
+	            urlEncode = URLEncoder.class.getMethod("encode", new Class[]{String.class, String.class});
+	            urlDecode = URLDecoder.class.getMethod("decode", new Class[]{String.class, String.class});
+            } catch (NoSuchMethodException e) {
+            	// EMPTY
+            }
+        } else {
+            urlEncode = null;
+            urlDecode = null;    
+        }
+    }
+
+    /**
+     * Pass through to the {@link java.net.URLEncoder}. If running under JDK &lt; 1.4,
+     * default encoding will always be used.
+     */
+    public static String encode(String s, String enc) throws UnsupportedEncodingException {
+        if (urlEncode != null) {
+            try {
+                return (String)urlEncode.invoke(s, new Object[]{ s, enc } );
+            } catch (IllegalAccessException e) {
+                // EMPTY
+            } catch (InvocationTargetException e) {
+                if (e.getTargetException() instanceof UnsupportedEncodingException) {
+                    throw (UnsupportedEncodingException)e.getTargetException();
+                } else if (e.getTargetException() instanceof RuntimeException) {
+                    throw (RuntimeException)e.getTargetException();
+                }
+            }
+        }
+        return URLEncoder.encode(s);
+    }
+
+    /**
+     * Pass through to the {@link java.net.URLDecoder}. If running under JDK &lt; 1.4,
+     * default encoding will always be used.
+     */
+    public static String decode(String s, String enc) throws UnsupportedEncodingException {
+        if (urlDecode != null) {
+            try {
+                return (String)urlDecode.invoke(s, new Object[]{ s, enc } );
+            } catch (IllegalAccessException e) {
+                // EMPTY
+            } catch (InvocationTargetException e) {
+                if (e.getTargetException() instanceof UnsupportedEncodingException) {
+                    throw (UnsupportedEncodingException)e.getTargetException();
+                } else if (e.getTargetException() instanceof RuntimeException) {
+                    throw (RuntimeException)e.getTargetException();
+                }
+            }
+        }
+        return URLDecoder.decode(s);
+    }
+}

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLPipe.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLPipe.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLPipe.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLProducer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLProducer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/AbstractXMLProducer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/EmbeddedXMLPipe.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/EmbeddedXMLPipe.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/EmbeddedXMLPipe.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/Parser.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/Parser.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/Parser.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/WhitespaceFilter.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/WhitespaceFilter.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/WhitespaceFilter.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLConsumer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLConsumer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLConsumer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLException.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLProducer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLProducer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/XMLProducer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMBuilder.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMBuilder.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMBuilder.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMStreamer.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMStreamer.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/dom/DOMStreamer.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxException.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxException.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxException.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxTransformerFactory.java
==============================================================================
--- cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxTransformerFactory.java	(original)
+++ cocoon/branches/butterfly/src/java/org/apache/butterfly/xml/xslt/TraxTransformerFactory.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/test/beans.xml
==============================================================================
--- cocoon/branches/butterfly/src/test/beans.xml	(original)
+++ cocoon/branches/butterfly/src/test/beans.xml	Sat Jul 31 09:06:07 2004
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!--
-  Copyright 2004, Ugo Cei
+  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.

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/GroovySitemapTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/GroovySitemapTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/GroovySitemapTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,18 +1,5 @@
-package org.apache.butterfly.components.pipeline.impl;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyObject;
-
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.xml.XmlBeanFactory;
-import org.springframework.core.io.ClassPathResource;
-
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.
@@ -26,6 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.butterfly.components.pipeline.impl;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanFactory;
+import org.springframework.core.io.ClassPathResource;
 
 /**
  * Description of GroovySitemapTestCase.

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/MyPipeline.groovy
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/MyPipeline.groovy	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/MyPipeline.groovy	Sat Jul 31 09:06:07 2004
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
 class MyPipeline extends Pipeline {
   
     void define(String requestPath) {

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipelineTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipelineTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/NonCachingProcessingPipelineTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, Ugo Cei.
+ * 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.

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/Pipeline.groovy
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/Pipeline.groovy	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/components/pipeline/impl/Pipeline.groovy	Sat Jul 31 09:06:07 2004
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 import org.apache.butterfly.xml.dom.DOMBuilder
 import org.apache.butterfly.components.pipeline.impl.NonCachingProcessingPipeline
 

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/generation/FileGeneratorTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/generation/FileGeneratorTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/generation/FileGeneratorTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/serialization/XMLSerializerTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/serialization/XMLSerializerTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/serialization/XMLSerializerTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/source/SourceResolverTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/source/SourceResolverTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/source/SourceResolverTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/test/SitemapComponentTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/test/SitemapComponentTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/test/SitemapComponentTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/src/test/org/apache/butterfly/transformation/TraxTransformerTestCase.java
==============================================================================
--- cocoon/branches/butterfly/src/test/org/apache/butterfly/transformation/TraxTransformerTestCase.java	(original)
+++ cocoon/branches/butterfly/src/test/org/apache/butterfly/transformation/TraxTransformerTestCase.java	Sat Jul 31 09:06:07 2004
@@ -1,16 +1,15 @@
 /*
- * Copyright 2004, Ugo Cei.
- * 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 
+ * Copyright 1999-2004 The Apache Software Foundation.
  * 
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  * 
- * 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.
+ *      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.
  */

Modified: cocoon/branches/butterfly/testdata/test1.xml
==============================================================================
--- cocoon/branches/butterfly/testdata/test1.xml	(original)
+++ cocoon/branches/butterfly/testdata/test1.xml	Sat Jul 31 09:06:07 2004
@@ -1,5 +1,19 @@
 <?xml version="1.0"?>
-<!-- A comment -->
+<!--
+  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.
+-->
 <root attribute="1">
   <child id="X">Text</child>
   Mixed content

Mime
View raw message