You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2002/09/27 11:05:19 UTC

cvs commit: xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication AuthenticationConstants.java

cziegeler    2002/09/27 02:05:18

  Modified:    src/java/org/apache/cocoon/transformation
                        SourceWritingTransformer.java
               .        properties.xml module.xml
               tools/src blocks-build.xsl
               src/java/org/apache/cocoon/xml/dom DOMUtil.java
  Added:       src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/components
                        PortalManager.java Coplet.java CopletThread.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/acting
                        LogoutAction.java LoginAction.java
                        LoggedInAction.java AuthAction.java
               src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal
                        PortalConstants.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/components
                        Handler.java ApplicationHandler.java
                        HandlerManager.java AuthenticationManager.java
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/xml
                        NodeListImpl.java XMLUtil.java
               src/blocks/session-fw/conf session-tran.xmap
                        session-act.xmap session.xconf session.xroles
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector
                        XMLSaver.java ResourceConnector.java
                        ResourceConnectorImpl.java XMLLoader.java
                        Resource.java
               src/blocks/portal-fw/conf portal.xroles portal.xconf
                        portal-gen.xmap portal-act.xmap
               src/blocks/authentication-fw/conf authentication.xroles
                        authentication-sel.xmap authentication.xconf
                        authentication-gen.xmap authentication-act.xmap
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context
                        SimpleSessionContext.java
                        RequestSessionContext.java
                        StandardSessionContextProvider.java
                        SessionContextProvider.java SessionContext.java
                        ResponseSessionContext.java
               src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/generation
                        PortalGenerator.java ConfigurationGenerator.java
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation
                        SessionPostTransformer.java
                        SessionPreTransformer.java SessionTransformer.java
                        AbstractSessionTransformer.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/selection
                        MediaSelector.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/context
                        SessionContextProviderImpl.java
                        SessionContextImpl.java
               src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/context
                        SessionContextProviderImpl.java
                        SessionContextImpl.java
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/components
                        AbstractSessionComponent.java SessionManager.java
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session
                        SessionConstants.java
               src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/acting
                        AuthAction.java
               src/blocks/session-fw/java/org/apache/cocoon/webapps/session/acting
                        SessionAction.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/generation
                        ConfigurationGenerator.java
               src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication
                        AuthenticationConstants.java
  Log:
  Moving webapps stuff into own blocks and "fixing" inter block dependency compilation.
  
  Revision  Changes    Path
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/components/PortalManager.java
  
  Index: PortalManager.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.components;
  
  import java.io.*;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.sax.XMLDeserializer;
  import org.apache.excalibur.store.Store;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  import org.apache.cocoon.webapps.portal.PortalConstants;
  import org.apache.cocoon.webapps.portal.context.SessionContextProviderImpl;
  import org.apache.cocoon.webapps.session.components.AbstractSessionComponent;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.context.SessionContextProvider;
  import org.apache.cocoon.webapps.session.xml.XMLUtil;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.XMLUtils;
  import org.apache.cocoon.xml.dom.DOMBuilder;
  import org.apache.cocoon.xml.dom.DOMUtil;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.helpers.AttributesImpl;
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.Text;
  import org.w3c.dom.traversal.NodeIterator;
  
  
  /**
   *  This is the basis portal component
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: PortalManager.java,v 1.7 2002/09/23 11:33:19 cziegeler Exp $
  */
  public final class PortalManager
  extends AbstractSessionComponent {
  
      /** The avalon role */
      public static final String ROLE  = PortalManager.class.getName();
  
  
      /** Values for the buildprofile type element */
      public static final String BUILDTYPE_VALUE_BASIC  = "basic";
      public static final String BUILDTYPE_VALUE_GLOBAL = "global";
      public static final String BUILDTYPE_VALUE_ROLE   = "role";
      public static final String BUILDTYPE_VALUE_ID     = "user";
  
      /**
       * The request parameters for customizing coplets
       * The request parameter is <code>REQ_PARAMETER_CMD</code> and the
       * the value is one from <code>REQ_CMD_</code> followed by
       * '_<copletID>_<copletNR>'.
       */
      public static final String REQ_PARAMETER_CMD = "portalcmd";
  
          public static final String REQ_CMD_MAXIMIZE = "maximize";
          public static final String REQ_CMD_MINIMIZE = "minimize";
          public static final String REQ_CMD_CLOSE    = "close";
          public static final String REQ_CMD_OPEN    = "open";
          public static final String REQ_CMD_HIDE    = "hide"; // synonym to close
          public static final String REQ_CMD_SHOW    = "show"; // synonym to open
          public static final String REQ_CMD_CUSTOMIZE= "customize";
          public static final String REQ_CMD_UPDATE   = "update";
          public static final String REQ_CMD_DELETE   = "delete";
          public static final String REQ_CMD_MOVE     = "move";
          public static final String REQ_CMD_NEW      = "new";
          public static final String REQ_CMD_MOVEROW  = "row";   // 1.1
          public static final String REQ_CMD_SAVEPROFILE = "save";
  
      /** This parameter is used for changing of profile value */
      public static final String REQ_PARAMETER_CONF = "portalconf";
  
      /** This parameter denotes the profile to be used */
      public static final String REQ_PARAMETER_PROFILE = "portalprofile";
  
      /** These parameter characterize the role and id */
      public static final String REQ_PARAMETER_ROLE = "portalrole";
      public static final String REQ_PARAMETER_ID   = "portalid";
      public static final String REQ_PARAMETER_STATE= "portaladmin";
      public static final String REQ_PARAMETER_COPLET= "portalcoplet";
      public static final String REQ_PARAMETER_ADMIN_COPLETS = "portaladmin_coplets";
  
      /** This is the current role/id which is set in the context */
      public static final String ATTRIBUTE_PORTAL_ROLE = "role";
      public static final String ATTRIBUTE_PORTAL_ID   = "ID";
  
      /** Some states for the admin configuration */
      public static final String ATTRIBUTE_ADMIN_STATE = "adminstate";
      public static final String ATTRIBUTE_ADMIN_ROLE  = "adminrole";
      public static final String ATTRIBUTE_ADMIN_ID    = "adminid";
      public static final String ATTRIBUTE_ADMIN_COPLETS = "admincoplets";
  
  
      /** The cache (store) for the profiles */
      private Store   profileStore;
  
      /** The authenticationManager */
      private AuthenticationManager authenticationManager;
  
      /** Init the class,
       *  add the provider for the portal context
       */
      static {
          // add the provider for the portal context
          SessionContextProvider provider = new SessionContextProviderImpl();
          try {
              SessionManager.addSessionContextProvider(provider, PortalConstants.SESSION_CONTEXT_NAME);
          } catch (ProcessingException local) {
              throw new RuntimeException("Unable to register provider for portal context.");
          }
      }
  
      /**
       * Avalon Recyclable Interface
       */
      public void recycle() {
          if (this.manager != null) {
              this.manager.release(this.profileStore);
              this.manager.release(this.authenticationManager);
              this.profileStore = null;
              this.authenticationManager = null;
          }
          super.recycle();
      }
  
      /**
       * Get the profile store
       */
      public Store getProfileStore()
      throws ProcessingException {
          if (this.profileStore == null) {
              try {
                  this.profileStore = (Store)this.manager.lookup(Store.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of store component.", ce);
              }
          }
          return this.profileStore;
      }
  
      /**
       * Get the profile store
       */
      public AuthenticationManager getAuthenticationManager()
      throws ProcessingException {
          if (this.authenticationManager == null) {
              try {
                  this.authenticationManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of AuthenticationManager.", ce);
              }
          }
          return this.authenticationManager;
      }
  
      /**
       * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
       * used to process the request.
       *  This method is automatically called for each request. Do not invoke
       *  this method by hand.
       */
      public void setup(SourceResolver resolver, Map objectModel)
      throws ProcessingException, SAXException, IOException {
          // synchronized per se
          super.setup(resolver, objectModel);
  
          final Map map = this.getConfiguration();
  
          this.changeProfile();
      }
  
      /**
       * Configure portal and check if it is allowed to see this coplet (if it is one).
       * This is only a public wrapper for the getConfiguration method.
       */
      public void configurationTest()
      throws ProcessingException, IOException, SAXException {
          // no sync required
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN configurationTest");
          }
          Map map = this.getConfiguration();
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END configurationTest");
          }
      }
  
      /**
       * Get the portal context of the current application
       */
      public SessionContext getContext(boolean create)
      throws ProcessingException, IOException, SAXException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getContext create="+create);
          }
          SessionContext context = null;
  
          final Session session = this.getSessionManager().getSession(false);
          if (session != null) {
              synchronized(session) {
                  String appName = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME);
                  String attrName = PortalConstants.PRIVATE_SESSION_CONTEXT_NAME;
                  if (appName != null) {
                      attrName = attrName + ':' + appName;
                  }
                  context = this.getSessionManager().getContext(attrName);
                  if (context == null && create == true) {
  
                      // create new context
                      context = this.getAuthenticationManager().createHandlerContext(attrName, null, null);
  
                  }
              } // end synchronized
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getContext context="+context);
          }
          return context;
      }
  
      /**
       * Include Portal URI into stream
       */
      public void streamConfiguration(XMLConsumer consumer,
                                      String      requestURI,
                                      String      profileID,
                                      String      media,
                                      String      contextID)
      throws IOException, SAXException, ProcessingException {
          // synchronized not req.
          this.sendStartElementEvent(consumer, PortalConstants.ELEMENT_CONFIGURATION);
  
          // set the portal-page uri:
          StringBuffer buffer = new StringBuffer(requestURI);
          buffer.append((requestURI.indexOf('?') == -1 ? '?' : '&'))
              .append(PortalManager.REQ_PARAMETER_PROFILE)
              .append('=')
              .append(profileID);
          String uri = this.response.encodeURL(buffer.toString());
          this.sendStartElementEvent(consumer, "uri");
          this.sendTextEvent(consumer, uri);
          this.sendEndElementEvent(consumer, "uri");
  
          Map config = this.getConfiguration();
          String portalURI = this.response.encodeURL((String)config.get(PortalConstants.CONF_PORTAL_URI));
  
          this.sendStartElementEvent(consumer, "portal");
          this.sendTextEvent(consumer, portalURI);
          this.sendEndElementEvent(consumer, "portal");
  
          this.sendStartElementEvent(consumer, PortalConstants.ELEMENT_PROFILE);
          this.sendTextEvent(consumer, profileID);
          this.sendEndElementEvent(consumer, PortalConstants.ELEMENT_PROFILE);
  
          if (media != null) {
              this.sendStartElementEvent(consumer, "media");
              this.sendTextEvent(consumer, media);
              this.sendEndElementEvent(consumer, "media");
          }
  
          if (contextID != null) {
              this.sendStartElementEvent(consumer, "context");
              this.sendTextEvent(consumer, contextID);
              this.sendEndElementEvent(consumer, "context");
          }
  
          this.sendEndElementEvent(consumer, PortalConstants.ELEMENT_CONFIGURATION);
      }
  
      /**
       * Show the admin configuration page.
       */
      public void showAdminConf(XMLConsumer consumer)
      throws SAXException, ProcessingException, IOException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN showAdminConf consumer=" + consumer);
          }
          try {
              String profileID = "global";
              String copletID = this.request.getParameter(PortalManager.REQ_PARAMETER_COPLET);
  
              SessionContext context = this.getContext(true);
  
              Map configuration = this.getConfiguration();
  
              DocumentFragment copletsFragment = (DocumentFragment)context.getAttribute(ATTRIBUTE_ADMIN_COPLETS);
              String command = this.request.getParameter(PortalManager.REQ_PARAMETER_ADMIN_COPLETS);
              if (command != null && copletsFragment != null) {
                  try {
                      this.getSessionManager().startWritingTransaction(context);
                      // save : save coplets base
                      // new  : new coplet
                      // delete : use id to delete coplet
                      // change : change the coplet
                      //        cache : cleans the cache
                      if (command.equals("delete") == true && copletID != null) {
                          Node coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']");
                          if (coplet != null) {
                              coplet.getParentNode().removeChild(coplet);
                          }
                      } else if (command.equals("change") == true && copletID != null) {
                          Node coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']");
                          if (coplet != null) {
                              // now get the information
                              String value;
  
                              value = this.request.getParameter("portaladmin_title");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "title"), value);
  
                              value = this.request.getParameter("portaladmin_mand");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/mandatory"), value);
  
                              value = this.request.getParameter("portaladmin_sizable");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/sizable"), value);
  
                              value = this.request.getParameter("portaladmin_active");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/active"), value);
  
                              value = this.request.getParameter("portaladmin_handsize");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable"), value);
  
                              value = this.request.getParameter("portaladmin_handpar");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters"), value);
  
                              value = this.request.getParameter("portaladmin_timeout");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/timeout"), value);
  
                              value = this.request.getParameter("portaladmin_customizable");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/customizable"), value);
  
                              value = this.request.getParameter("portaladmin_persistent");
                              if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/persistent"), value);
  
                              String resource = this.request.getParameter("portaladmin_resource");
                              if (resource != null) {
                                  Element resourceNode = (Element)DOMUtil.getSingleNode(coplet, "resource");
                                  resourceNode.getParentNode().removeChild(resourceNode);
                                  resourceNode = coplet.getOwnerDocument().createElementNS(null, "resource");
                                  resourceNode.setAttributeNS(null, "uri", resource);
                                  coplet.appendChild(resourceNode);
                              }
                              resource = this.request.getParameter("portaladmin_cust");
                              boolean isCustom = DOMUtil.getValueAsBooleanOf(coplet, "configuration/customizable", false);
                              if (resource != null && isCustom == true) {
                                  Element resourceNode = (Element)DOMUtil.getSingleNode(coplet, "customization");
                                  if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode);
                                  resourceNode = coplet.getOwnerDocument().createElementNS(null, "customization");
                                  resourceNode.setAttributeNS(null, "uri", resource);
                                  coplet.appendChild(resourceNode);
                              }
                              if (isCustom == false) {
                                  Element resourceNode = (Element)DOMUtil.getSingleNode(coplet, "customization");
                                  if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode);
                              }
  
                              // transformations
                              value = this.request.getParameter("portaladmin_newxsl");
                              if (value != null) {
                                  Element tNode = (Element)DOMUtil.selectSingleNode(coplet, "transformation");
                                  Element sNode = tNode.getOwnerDocument().createElementNS(null, "stylesheet");
                                  tNode.appendChild(sNode);
                                  sNode.appendChild(sNode.getOwnerDocument().createTextNode(value));
                              }
  
                              // now get all transformation stylesheets, mark
                              // all stylesheets which should be deleted with
                              // an attribute delete
                              Enumeration keys = this.request.getParameterNames();
                              int pos;
                              Element sNode;
                              String key;
                              while (keys.hasMoreElements() == true) {
                                  key = (String)keys.nextElement();
                                  if (key.startsWith("portaladmin_xsl_") == true) {
                                      value = key.substring(key.lastIndexOf('_')+ 1);
                                      sNode = (Element)DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]");
                                      if (sNode != null) {
                                          String xslName = this.request.getParameter(key);
                                          if (xslName.equals("true") == true) xslName = "**STYLESHEET**";
                                          DOMUtil.setValueOfNode(sNode, xslName);
                                      }
                                  } else if (key.startsWith("portaladmin_delxsl_") == true) {
                                      value = key.substring(key.lastIndexOf('_')+ 1);
                                      sNode = (Element)DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]");
                                      if (sNode != null) {
                                          sNode.setAttributeNS(null, "delete", "true");
                                      }
                                  }
                              }
                              NodeList delete = DOMUtil.selectNodeList(coplet, "transformation/stylesheet[@delete]");
                              if (delete != null) {
                                  for(int i=0; i < delete.getLength(); i++) {
                                      delete.item(i).getParentNode().removeChild(delete.item(i));
                                  }
                              }
                          }
                      } else if (command.equals("new") == true) {
                          // first we have to invent a new coplet id!
                          int index = 0;
                          boolean found = false;
                          Element coplet;
                          Element subNode;
  
                          while (found == false) {
                              copletID = "S"+index;
                              coplet = (Element)DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']");
                              if (coplet == null) {
                                  found = true;
                              } else {
                                  index++;
                              }
                          }
                          coplet = copletsFragment.getOwnerDocument().createElementNS(null, "coplet");
                          coplet.setAttributeNS(null, "id", copletID);
                          subNode = coplet.getOwnerDocument().createElementNS(null, "resource");
                          coplet.appendChild(subNode);
                          subNode.setAttributeNS(null, "uri", "uri_in_sitemap");
  
                          String title = this.request.getParameter("portaladmin_title");
                          if (title == null || title.trim().length() == 0) title = "**NEW COPLET**";
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/mandatory"), "false");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/sizable"), "true");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/active"), "false");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters"), "true");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable"), "false");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "title"), title);
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/visible"), "true");
                          DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/size"), "max");
                          DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets").appendChild(coplet);
                      } else if (command.equals("save") == true) {
  
                          SourceParameters pars = new SourceParameters();
                          pars.setSingleParameterValue("profile", "coplet-base");
                          pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
                          pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
  
                          Resource saveResource = (Resource)configuration.get(PortalConstants.CONF_COPLETBASE_SAVE_RESOURCE);
  
                          if (saveResource == null) {
                              throw new ProcessingException("portal: No save resource defined for type coplet-base.");
                          } else {
  
                              this.getResourceConnector().saveXML(saveResource.getResourceType(),null,
                                   saveResource.getResourceIdentifier(),pars,
                                   copletsFragment);
  
                              // now the hardest part, clean up the whole cache
                              this.cleanUpCache(null, null, configuration);
                          }
                      }
                  } finally {
                      this.getSessionManager().stopWritingTransaction(context);
                  }
              }
  
              // general commands
              if (command != null && command.equals("cleancache") == true) {
                  this.cleanUpCache(null, null, configuration);
              }
  
              String state = this.request.getParameter(PortalManager.REQ_PARAMETER_STATE);
              if (state == null) {
                  state = (String)context.getAttribute(ATTRIBUTE_ADMIN_STATE, PortalConstants.STATE_MAIN);
              }
  
              // now start producing xml:
              AttributesImpl attr = new AttributesImpl();
              consumer.startElement("", PortalConstants.ELEMENT_ADMINCONF, PortalConstants.ELEMENT_ADMINCONF, attr);
  
              context.setAttribute(ATTRIBUTE_ADMIN_STATE, state);
              consumer.startElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE, attr);
              consumer.characters(state.toCharArray(), 0, state.length());
              consumer.endElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE);
  
              if (state.equals(PortalConstants.STATE_MAIN) == true) {
  
                  DocumentFragment rolesDF = this.getAuthenticationManager().getRoles();
                  Node             roles   = null;
                  if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles");
                  IncludeXMLConsumer.includeNode(roles, consumer, consumer);
              }
  
              if (state.equals(PortalConstants.STATE_MAIN_ROLE) == true) {
  
                  DocumentFragment rolesDF = this.getAuthenticationManager().getRoles();
                  Node             roles   = null;
                  if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles");
                  IncludeXMLConsumer.includeNode(roles, consumer, consumer);
  
                  String role = this.request.getParameter(PortalManager.REQ_PARAMETER_ROLE);
                  if (role == null) {
                      role = (String)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
                  }
                  context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
                  if (role != null) {
                      this.sendStartElementEvent(consumer, "roleusers");
                      this.sendStartElementEvent(consumer, "name");
                      this.sendTextEvent(consumer, role);
                      this.sendEndElementEvent(consumer, "name");
                      DocumentFragment userDF = this.getAuthenticationManager().getUsers(role, null);
                      Node             users = null;
                      if (userDF != null) users = DOMUtil.getSingleNode(userDF, "users");
                      IncludeXMLConsumer.includeNode(users, consumer, consumer);
                      this.sendEndElementEvent(consumer, "roleusers");
                  }
              }
  
              if (state.equals(PortalConstants.STATE_GLOBAL) == true) {
                  profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, true);
                  Map profile = this.retrieveProfile(profileID);
                  if (profile == null) {
                      this.createProfile(context, PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, true);
                      profile = this.retrieveProfile(profileID);
                  }
                  this.showPortal(consumer, true, context, profile, profileID);
              }
  
              if (state.equals(PortalConstants.STATE_ROLE) == true) {
                  String role = this.request.getParameter(PortalManager.REQ_PARAMETER_ROLE);
                  if (role == null) {
                      role = (String)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
                  }
                  context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
                  if (role != null) {
                      consumer.startElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE, attr);
                      consumer.characters(role.toCharArray(), 0, role.length());
                      consumer.endElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE);
                      profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ROLE, role, null, true);
                      Map profile = this.retrieveProfile(profileID);
                      if (profile == null) {
                          this.createProfile(context, PortalManager.BUILDTYPE_VALUE_ROLE, role, null, true);
                          profile = this.retrieveProfile(profileID);
                      }
                      this.showPortal(consumer, true, context, profile, profileID);
                  }
              }
              if (state.equals(PortalConstants.STATE_USER) == true) {
                  String role = this.request.getParameter(PortalManager.REQ_PARAMETER_ROLE);
                  String id   = this.request.getParameter(PortalManager.REQ_PARAMETER_ID);
                  if (role == null) {
                      role = (String)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
                  }
                  if (id == null) {
                      id = (String)context.getAttribute(ATTRIBUTE_ADMIN_ID);
                  }
                  context.setAttribute(ATTRIBUTE_ADMIN_ID, id);
                  context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
                  if (role != null && id != null) {
                      consumer.startElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE, attr);
                      consumer.characters(role.toCharArray(), 0, role.length());
                      consumer.endElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE);
                      consumer.startElement("", PortalConstants.ELEMENT_ID, PortalConstants.ELEMENT_ID, attr);
                      consumer.characters(id.toCharArray(), 0, id.length());
                      consumer.endElement("", PortalConstants.ELEMENT_ID, PortalConstants.ELEMENT_ID);
  
                      profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID, role, id, true);
                      Map profile = this.retrieveProfile(profileID);
                      if (profile == null) {
                          this.createProfile(context, PortalManager.BUILDTYPE_VALUE_ID, role, id, true);
                          profile = this.retrieveProfile(profileID);
                      }
                      this.showPortal(consumer, true, context, profile, profileID);
                  }
              }
              // one coplet
              if (state.equals(PortalConstants.STATE_COPLET) == true) {
                  if (copletsFragment != null && copletID != null) {
                      Node coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']");
                      if (coplet != null) {
                          IncludeXMLConsumer.includeNode(coplet, consumer, consumer);
                      }
                  } else {
                      state = PortalConstants.STATE_COPLETS;
                  }
              }
              if (state.equals(PortalConstants.STATE_COPLETS) == true) {
                  consumer.startElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS, attr);
  
                  // load the base coplets profile
                  if (copletsFragment == null) {
                      SourceParameters pars = new SourceParameters();
                      pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
                      Resource res = (Resource)configuration.get(PortalConstants.CONF_COPLETBASE_RESOURCE);
                      if (res == null) {
                          throw new ProcessingException("No configuration for portal-coplet base profile found.");
                      }
                      copletsFragment = this.loadXML(res.getResourceType(), null,
                                                     res.getResourceIdentifier(), pars,
                                                     "Error during loading of coplet base.");
                      context.setAttribute(ATTRIBUTE_ADMIN_COPLETS, copletsFragment);
                  }
                  IncludeXMLConsumer.includeNode(DOMUtil.selectSingleNode(copletsFragment,
                                     "coplets-profile"), consumer, consumer);
                  consumer.endElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS);
              }
  
              // configuration
              this.streamConfiguration(consumer, this.request.getRequestURI(), profileID, null, null);
  
              consumer.endElement("", PortalConstants.ELEMENT_ADMINCONF, PortalConstants.ELEMENT_ADMINCONF);
          } catch (javax.xml.transform.TransformerException local) {
              throw new ProcessingException("TransformerException: " + local, local);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END showAdminConf");
          }
      }
  
      /**
       * Get the status profile
       */
      public Element getStatusProfile()
      throws SAXException, IOException, ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getStatusProfile");
          }
          SessionContext context = this.getContext(true);
          String profileID = null;
          Map storedProfile = null;
          Element statusProfile = null;
  
          if (context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE) != null) {
              profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID,
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE),
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ID), false);
              storedProfile = this.retrieveProfile(profileID);
          }
  
          if (storedProfile != null) {
              DocumentFragment profile = (DocumentFragment)storedProfile.get(PortalConstants.PROFILE_PROFILE);
              try {
                  statusProfile = (Element)DOMUtil.getSingleNode(profile, "profile/status-profile");
              } catch (javax.xml.transform.TransformerException ignore) {
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getStatusProfile statusProfile="+(statusProfile == null ? "null" : XMLUtils.serializeNodeToXML(statusProfile)));
          }
          return statusProfile;
      }
  
      /**
       * Show the portal.
       * The portal is included in the current stream.
       */
      public void showPortal(XMLConsumer consumer,
                             boolean configMode,
                             boolean adminProfile)
      throws SAXException, ProcessingException, IOException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN showPortal consumer=" + consumer+", configMode="+
                               configMode+", adminProfile="+adminProfile);
          }
          SessionContext context = this.getContext(true);
          String profileID = null;
          Map storedProfile = null;
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("start portal generation");
          }
          if (context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE) != null) {
              profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID,
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE),
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ID), adminProfile);
              storedProfile = this.retrieveProfile(profileID);
          }
          if (storedProfile == null) {
  
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("start building profile");
              }
              this.createProfile(context, PortalManager.BUILDTYPE_VALUE_ID, null, null, adminProfile);
              // get the profileID
              profileID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID,
                      (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE),
                      (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ID), adminProfile);
              storedProfile = this.retrieveProfile(profileID);
              if (storedProfile == null) {
                  throw new ProcessingException("portal: No portal profile found.");
              }
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("end building profile");
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("start showing profile");
          }
          this.showPortal(consumer,
                          configMode,
                          context,
                          storedProfile,
                          profileID);
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("end showing profile");
              this.getLogger().debug("end portal generation");
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END showPortal");
          }
      }
  
      /**
       * Stream all layout information for the current portal
       * to the consumer.
       * The resulting XML:
       * <layout>
       *     <portal>
       *         ...
       *     </portal>
       *     <coplets>
       *         ...
       *     </coplets>
       * </layout>
       */
      public static void streamLayoutProfile(XMLConsumer consumer,
                                             Map         portalLayouts,
                                             Map         copletLayouts,
                                             String      mediaType)
      throws SAXException {
          Element  element;
          NodeList childs;
          Attributes attr = new AttributesImpl();
  
          consumer.startElement("", PortalConstants.ELEMENT_LAYOUT, PortalConstants.ELEMENT_LAYOUT, attr);
  
          // first: layout of portal
          consumer.startElement("", PortalConstants.ELEMENT_PORTAL, PortalConstants.ELEMENT_PORTAL, attr);
  
          element = (Element)portalLayouts.get(mediaType);
          childs = element.getChildNodes();
          for(int ci = 0; ci < childs.getLength(); ci++) {
              IncludeXMLConsumer.includeNode(childs.item(ci),
                                        consumer,
                                        consumer);
          }
          consumer.endElement("", PortalConstants.ELEMENT_PORTAL, PortalConstants.ELEMENT_PORTAL);
  
          // second: layout of coplets
          consumer.startElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS, attr);
          element = (Element)copletLayouts.get(mediaType);
          childs = element.getChildNodes();
          for(int ci = 0; ci < childs.getLength(); ci++) {
              IncludeXMLConsumer.includeNode(childs.item(ci),
                                        consumer,
                                        consumer);
          }
          consumer.endElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS);
  
          consumer.endElement("", PortalConstants.ELEMENT_LAYOUT, PortalConstants.ELEMENT_LAYOUT);
      }
  
      /**
       * Show the portal.
       * The portal is included in the current stream.
       */
      private void showPortal(XMLConsumer consumer,
                             boolean      configMode,
                             SessionContext context,
                             Map          storedProfile,
                             String       profileID)
      throws SAXException, ProcessingException, IOException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN showPortal consumer=" + consumer+", configMode="+configMode+", context="+context+
                  ", profile="+storedProfile);
          }
          try {
              this.getSessionManager().startReadingTransaction(context);
  
              DocumentFragment profile;
              Map              defaultCoplets;
              Map              mediaCoplets;
              Map              portalLayouts;
              Map              copleyLayouts;
              Node[]           miscNodes;
              String           mediaType = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE);
  
              profile = (DocumentFragment)storedProfile.get(PortalConstants.PROFILE_PROFILE);
              portalLayouts = (Map)storedProfile.get(PortalConstants.PROFILE_PORTAL_LAYOUTS);
              copleyLayouts = (Map)storedProfile.get(PortalConstants.PROFILE_COPLET_LAYOUTS);
              miscNodes = (Node[])storedProfile.get(PortalConstants.PROFILE_MISC_POINTER);
              defaultCoplets = (Map)storedProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS);
              mediaCoplets = (Map)storedProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS);
              if (profile == null ||
                  defaultCoplets == null ||
                  mediaCoplets == null ||
                  portalLayouts == null ||
                  copleyLayouts == null ||
                  miscNodes == null) {
                  throw new ProcessingException("portal: No portal profile found.");
              }
  
              // get the configuration
              Map config = this.getConfiguration();
              if (config == null) {
                  throw new ProcessingException("No configuration for portal found.");
              }
              boolean processCopletsParallel = false;
              long    defaultCopletTimeout   = 600000;
  
              Boolean boolValue = (Boolean)config.get(PortalConstants.CONF_PARALLEL_COPLETS);
              if (boolValue != null) processCopletsParallel = boolValue.booleanValue();
              Long longValue = (Long)config.get(PortalConstants.CONF_COPLET_TIMEOUT);
              if (longValue != null) defaultCopletTimeout = longValue.longValue();
  
              Element element;
  
              // now start producing xml:
              AttributesImpl attr = new AttributesImpl();
              if (configMode == true) {
                  this.sendStartElementEvent(consumer, PortalConstants.ELEMENT_PORTALCONF);
              } else {
                  this.sendStartElementEvent(consumer, PortalConstants.ELEMENT_PORTAL);
              }
  
              // configuration
              this.streamConfiguration(consumer, this.request.getRequestURI(), profileID, mediaType, null);
  
              // LAYOUT:
              if (configMode == true) {
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","layout-profile"}, false),
                       consumer, consumer);
                  // copletsConfiguration (only for configMode)
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","coplets-profile"}, false),
                       consumer, consumer);
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","type-profile","typedefs"}, false),
                       consumer, consumer);
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","portal-profile"}, false),
                       consumer, consumer);
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","personal-profile"}, false),
                       consumer, consumer);
                  IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","status-profile"}, false),
                       consumer, consumer);
              } else {
                  PortalManager.streamLayoutProfile(consumer, portalLayouts, copleyLayouts, mediaType);
              }
              // END LAYOUT
  
              if (configMode == false) {
                  Element statusProfile = (Element)DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","status-profile"}, false);
  
                  String copletNotAvailableMessage = "The coplet is currently not available.";
                  Node messages = miscNodes[PortalConstants.PROFILE_MISC_MESSAGES_NODE];
                  if (messages != null) {
                      messages = DOMUtil.getFirstNodeFromPath(messages, new String[] {"coplet_not_available"}, false);
                      if (messages != null) copletNotAvailableMessage = DOMUtil.getValueOfNode(messages,
                           copletNotAvailableMessage);
                  }
  
                  // LOAD COPLETS
                  List[] copletContents;
  
                  copletContents = (List[])context.getAttribute(PortalConstants.ATTRIBUTE_COPLET_REPOSITORY);
                  if (copletContents == null) {
                      copletContents = new List[PortalConstants.MAX_COLUMNS+2];
                      context.setAttribute(PortalConstants.ATTRIBUTE_COPLET_REPOSITORY, copletContents);
                  }
                  if (copletContents[0] == null) {
                      copletContents[0] = new ArrayList(1);
                  } else {
                      copletContents[0].clear();
                  }
                  if (copletContents[1] == null) {
                      copletContents[1] = new ArrayList(1);
                  } else {
                      copletContents[1].clear();
                  }
  
                  // test for header
                  String value;
                  value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_HEADER_NODE]);
                  if (value != null && new Boolean(value).booleanValue() == true) {
                      element = (Element)miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE];
                      if (element != null) {
                          this.loadCoplets(element,
                                           defaultCoplets,
                                           mediaCoplets,
                                           copletContents[0],
                                           processCopletsParallel,
                                           defaultCopletTimeout,
                                           statusProfile);
                      }
                  }
  
                  // content
                  value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]);
  
                  // for a simpler XSL-Stylesheet: The columns must be inserted in the
                  // correct order!!!
                  if (value != null && new Integer(value).intValue() > 0) {
  
                      Element columnElement;
                      int columns = new Integer(value).intValue();
                      if (columns > PortalConstants.MAX_COLUMNS) {
                          throw new ProcessingException("portal: Maximum number of columns supported is: "+PortalConstants.MAX_COLUMNS);
                      }
  
                      for(int colindex = 1; colindex <= columns; colindex++) {
                          if (copletContents[colindex+1] == null) {
                              copletContents[colindex+1] = new ArrayList(10);
                          } else {
                              copletContents[colindex+1].clear();
                          }
                          columnElement = (Element)miscNodes[7 + colindex];
                          element = (Element)DOMUtil.getFirstNodeFromPath(columnElement, new String[] {"coplets"}, false);
                          if (element != null) {
                              this.loadCoplets(element,
                                               defaultCoplets,
                                               mediaCoplets,
                                               copletContents[colindex+1],
                                               processCopletsParallel,
                                               defaultCopletTimeout,
                                               statusProfile);
                          }
  
                      }
                      for(int colindex = columns+2; colindex <= PortalConstants.MAX_COLUMNS+1; colindex++) {
                          if (copletContents[colindex] != null) {
                              copletContents[colindex] = null;
                          }
                      }
  
                  } else {
                      for(int colindex = 1; colindex <= PortalConstants.MAX_COLUMNS; colindex++) {
                          if (copletContents[colindex+1] != null) {
                              copletContents[colindex+1] = null;
                          }
                      }
                  }
  
                  // test for footer
                  value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_FOOTER_NODE]);
                  if (value != null && new Boolean(value).booleanValue() == true) {
                      element = (Element)miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE];
                      if (element != null) {
                          this.loadCoplets(element,
                                           defaultCoplets,
                                           mediaCoplets,
                                           copletContents[1],
                                           processCopletsParallel,
                                           defaultCopletTimeout,
                                           statusProfile);
                      }
                  }
                  // END LOAD COPLETS
  
                  // DESIGN
                  // test for header
                  if (copletContents[0].size() > 0) {
                      consumer.startElement("", "header", "header", attr);
                      this.processCopletList(copletContents[0], consumer, copletNotAvailableMessage, defaultCopletTimeout);
                      consumer.endElement("", "header", "header");
                  }
  
                  // content
                  value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]);
  
                  // for a simpler XSL-Stylesheet: The columns must be inserted in the
                  // correct order!!!
                  if (value != null && new Integer(value).intValue() > 0) {
                      attr.addAttribute("", "number", "number", "CDATA", value);
                      this.sendStartElementEvent(consumer, "columns", attr);
                      attr.clear();
  
                      int columns = new Integer(value).intValue();
                      if (columns > PortalConstants.MAX_COLUMNS) {
                          throw new ProcessingException("portal: Maximum number of columns supported is: "+PortalConstants.MAX_COLUMNS);
                      }
  
                      // determine the width of the columns
                      String[] width = new String[columns];
                      int normalWidth = 100 / columns;
                      Element columnElement;
  
                      for(int colindex = 1; colindex <= columns; colindex++) {
                          columnElement = (Element)miscNodes[7 + colindex];
                          value = DOMUtil.getValueOf(columnElement, "width");
                          if (value == null) {
                              width[colindex-1] = "" + normalWidth + "%";
                          } else {
                              width[colindex-1] = value;
                          }
                      }
  
                      List copletsOfColumn;
  
                      for(int colindex = 1; colindex <= columns; colindex++) {
                          attr.addAttribute("", "position", "position", "CDATA", "" + colindex);
                          attr.addAttribute("", "width", "width", "CDATA", width[colindex-1]);
                          this.sendStartElementEvent(consumer, "column", attr);
                          attr.clear();
  
                          this.processCopletList(copletContents[colindex+1], consumer, copletNotAvailableMessage, defaultCopletTimeout);
  
                          this.sendEndElementEvent(consumer, "column");
                      }
                      this.sendEndElementEvent(consumer, "columns");
                  } else {
                      attr.addAttribute("", "number", "number", "CDATA", "0");
                      this.sendStartElementEvent(consumer, "columns", attr);
                      this.sendEndElementEvent(consumer, "columns");
                      attr.clear();
                  }
  
                  // test for footer
                  if (copletContents[1].size() > 0) {
                      this.sendStartElementEvent(consumer, "footer");
                      this.processCopletList(copletContents[1], consumer, copletNotAvailableMessage, defaultCopletTimeout);
                      this.sendEndElementEvent(consumer, "footer");
                  }
                  // END DESIGN
  
                  for(int i=0; i<copletContents.length;i++) {
                      if (copletContents[i]!=null) copletContents[i].clear();
                  }
  
                  // Personal information and status information
                  this.sendEvents(consumer, DOMUtil.getFirstNodeFromPath(profile, new String[] {"profile","personal-profile"}, false));
                  this.sendEvents(consumer, statusProfile);
              }
  
              if (configMode == true) {
                  this.sendEndElementEvent(consumer, PortalConstants.ELEMENT_PORTALCONF);
              } else {
                  this.sendEndElementEvent(consumer, PortalConstants.ELEMENT_PORTAL);
              }
  
          } catch (javax.xml.transform.TransformerException local) { // end synchronized
              throw new ProcessingException("TransformerException: " + local, local);
          } finally {
              this.getSessionManager().stopReadingTransaction(context);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END showPortal");
          }
      }
  
  
      /**
       * Building the profile.
       * This includes several steps which are declared in detail inside this method...
       */
      public void buildProfile(String type,
                               String role,
                               String id,
                               boolean adminProfile)
      throws ProcessingException, IOException, SAXException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildProfile type=" + objectModel + ", role=" + role + ", id=" +id+", adminProfile="+adminProfile);
          }
          try {
              // check parameter
              if (type == null) {
                  throw new IllegalArgumentException("buildProfile: Type is required");
              }
              if (type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true ||
                  type.equals(PortalManager.BUILDTYPE_VALUE_BASIC) == true) {
                  // nothing to do here
              } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ROLE) == true) {
                  if (role == null) {
                      throw new IllegalArgumentException("buildProfile: Role is required");
                  }
              } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                  if (role == null) {
                      throw new IllegalArgumentException("buildProfile: Role is required");
                  }
                  if (id == null) {
                      throw new IllegalArgumentException("buildProfile: ID is required");
                  }
              } else {
                  throw new IllegalArgumentException("buildProfile: Type unknown: " + type);
              }
  
              SessionContext context = this.getContext(true);
              try {
                  this.getSessionManager().startWritingTransaction(context);
  
                  String profileID = this.getProfileID(type, role, id, adminProfile);
                  Map theProfile = null;
  
                  // get the configuration
                  Map config = this.getConfiguration();
                  if (config == null) {
                      throw new ProcessingException("No configuration for portal found.");
                  }
  
                  // is the ID profile cached?
                  if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                      theProfile = this.getCachedProfile(profileID, config);
                  }
  
                  if (theProfile == null) {
  
                      boolean doBase = false;
                      boolean doGlobal = false;
                      boolean doRole = false;
                      boolean doID = false;
                      String previousID;
  
                      if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                          doID = true;
                          previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ROLE, role, null, adminProfile);
                          theProfile = this.getCachedProfile(previousID, config);
                          if (theProfile == null) {
                              doRole = true;
                              previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile);
                              theProfile = this.getCachedProfile(previousID, config);
                              if (theProfile == null) {
                                  doGlobal = true;
                                  previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
                                  theProfile = this.getCachedProfile(previousID, config);
                              }
                          }
                      } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ROLE) == true) {
                          theProfile = this.getCachedProfile(profileID, config);
                          if (theProfile == null) {
                              doRole = true;
                              previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile);
                              theProfile = this.getCachedProfile(previousID, config);
                              if (theProfile == null) {
                                  doGlobal = true;
                                  previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
                                  theProfile = this.getCachedProfile(previousID, config);
                              }
                          }
                      } else if (type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true) {
                          theProfile = this.getCachedProfile(profileID, config);
                          if (theProfile == null) {
                              doGlobal = true;
                              previousID = this.getProfileID(PortalManager.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
                              theProfile = this.getCachedProfile(previousID, config);
                          }
                      } else { // basic profile
                          theProfile = this.getCachedProfile(profileID, config);
                      }
  
                      // build the profile
                      if (theProfile == null) {
                          theProfile = new HashMap(8,2);
                          doBase = true;
                      }
  
                      Element          profileRoot;
                      DocumentFragment profile;
  
                      if (doBase == true) {
                          // build the base level
                          profile = this.buildBaseProfile(config, adminProfile);
                          profileRoot = (Element)profile.getFirstChild();
                          theProfile.put(PortalConstants.PROFILE_PROFILE, profile);
                          this.cacheProfile(this.getProfileID(PortalManager.BUILDTYPE_VALUE_BASIC, null, null, adminProfile), theProfile, config);
                      } else {
                          profile = (DocumentFragment)theProfile.get(PortalConstants.PROFILE_PROFILE);
                          profileRoot = (Element)profile.getFirstChild();
                      }
  
                      // load the global delta if type is global, role or user (but not basic!)
                      if (doGlobal == true) {
                          this.buildGlobalProfile(profileRoot, config, adminProfile);
                          this.cacheProfile(this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile), theProfile, config);
                      }
  
                      // load the role delta if type is role or user
                      if (doRole == true) {
                          this.buildRoleProfile(profileRoot, config, role, adminProfile);
                          this.cacheProfile(this.getProfileID(PortalManager.BUILDTYPE_VALUE_ROLE, role, null, adminProfile), theProfile, config);
                      }
  
                      // load the user delta if type is user
                      if (doID == true) {
                          this.buildUserProfile(profileRoot, config, role, id, adminProfile);
                      }
  
                      // load the status profile when type is user
                      if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                          this.buildUserStatusProfile(profileRoot, config, role, id, adminProfile);
                      }
  
                      if (type.equals(PortalManager.BUILDTYPE_VALUE_BASIC) == false) {
                          this.buildRunProfile(theProfile, context, profile);
  
                          theProfile.put(PortalConstants.PROFILE_PORTAL_LAYOUTS,
                                 this.buildPortalLayouts(context, profile));
                          theProfile.put(PortalConstants.PROFILE_COPLET_LAYOUTS,
                                 this.buildcopleyLayouts(context, profile));
  
                          this.buildTypeProfile(theProfile, context, profile);
                      }
  
                      // cache the profile, if user
                      if (doID == true) {
                          this.cacheProfile(profileID, theProfile, config);
                      }
                  } else {
                      // load the status profile when type is user
                      if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                          DocumentFragment profile = (DocumentFragment)theProfile.get(PortalConstants.PROFILE_PROFILE);
                          Element profileRoot = (Element)profile.getFirstChild();
                          this.buildUserStatusProfile(profileRoot, config, role, id, adminProfile);
                      }
                  }
  
                  // store the whole profile
                  this.storeProfile(profileID, theProfile);
  
                  // now put role and id into the context if type is ID
                  if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true
                      && adminProfile == false) {
                      context.setAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE, role);
                      context.setAttribute(PortalManager.ATTRIBUTE_PORTAL_ID, id);
                  }
              } finally {
                  this.getSessionManager().stopWritingTransaction(context);
              }// end synchronized
          } catch (javax.xml.transform.TransformerException local) {
              throw new ProcessingException("TransformerException: " + local, local);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildProfile");
          }
      }
  
      /**
       * Build the profile delta
       */
      private DocumentFragment buildProfileDelta(String type,
                                                 String role,
                                                 String id,
                                                 boolean adminProfile)
      throws SAXException, ProcessingException, IOException, javax.xml.transform.TransformerException {
          // calling method must be synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildProfileDeltaN type="+type+", role="+role+", id="+id);
          }
  
          Map    originalProfile;
          Map    baseProfile;
          String baseType, baseRole, baseID, rootElementName;
          DocumentFragment originalFragment;
          DocumentFragment delta;
          SessionContext context = this.getContext(true);
  
          originalProfile = this.retrieveProfile(this.getProfileID(type, role, id, adminProfile));
          if (originalProfile == null) {
              throw new ProcessingException("buildProfileDelta: no profile found for " +
                     type + " - " + role + " - " + id + ".");
          }
  
          if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
              baseType = PortalManager.BUILDTYPE_VALUE_ROLE;
              baseRole = role;
              baseID   = null;
              rootElementName = "user-delta";
          } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ROLE) == true) {
              baseType = PortalManager.BUILDTYPE_VALUE_GLOBAL;
              baseRole = null;
              baseID   = null;
              rootElementName = "role-delta";
          } else if (type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true) {
              baseType = PortalManager.BUILDTYPE_VALUE_BASIC;
              baseRole = null;
              baseID   = null;
              rootElementName = "global-delta";
          } else {
              throw new ProcessingException("buildProfileDelta: type '"+type+"' not allowed.");
          }
  
          // the profile is created as we dont want to use any memory representation!
          this.createProfile(context, baseType, baseRole, baseID, adminProfile);
          baseProfile = this.retrieveProfile(this.getProfileID(baseType, baseRole, baseID, adminProfile));
          if (baseProfile == null) {
              throw new ProcessingException("buildProfileDelta: no baseProfile found.");
          }
  
          originalFragment = (DocumentFragment)originalProfile.get(PortalConstants.PROFILE_PROFILE);
          delta = originalFragment.getOwnerDocument().createDocumentFragment();
          delta.appendChild(delta.getOwnerDocument().createElementNS(null, rootElementName));
  
          // Copy portal content
          Node profileDelta = DOMUtil.getFirstNodeFromPath(originalFragment, new String[] {"profile","portal-profile"}, false).cloneNode(true);
          delta.getFirstChild().appendChild(profileDelta);
  
          // Diff layout profile, coplet profile, personal profile but not status profile!
          this.diff(originalFragment,
                   (DocumentFragment)baseProfile.get(PortalConstants.PROFILE_PROFILE),
                    "profile/layout-profile",
                    (Element)delta.getFirstChild());
          this.diff(originalFragment,
                    (DocumentFragment)baseProfile.get(PortalConstants.PROFILE_PROFILE),
                    "profile/coplets-profile",
                    (Element)delta.getFirstChild());
          if (type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true) {
              profileDelta = DOMUtil.getFirstNodeFromPath(originalFragment, new String[] {"profile","personal-profile"}, false).cloneNode(true);
              delta.getFirstChild().appendChild(profileDelta);
          } else {
              this.diff(originalFragment,
                    (DocumentFragment)baseProfile.get(PortalConstants.PROFILE_PROFILE),
                    "profile/personal-profile",
                    (Element)delta.getFirstChild());
          }
  
          // check for the highes coplet number
          Node[] miscNodes = (Node[])originalProfile.get(PortalConstants.PROFILE_MISC_POINTER);
          Element lastCoplet = (Element)miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE];
          if (lastCoplet != null) {
              String lastNumber = ((Element)lastCoplet).getAttributeNS(null, "number");
              if (lastNumber != null) {
                  int value = new Integer(lastNumber).intValue();
                  if (value > 1000000) {
                      NodeList coplets = DOMUtil.selectNodeList(delta, "profile/portal-profile/descendant::coplet[@id and @number]");
                      if (coplets != null) {
                          Element copletNode;
                          String oldNumber;
                          String copletId;
                          Element statusNode;
                          boolean copletsChanged = false;
                          for(int i=0; i <coplets.getLength(); i++) {
                              copletNode = (Element)coplets.item(i);
                              oldNumber = copletNode.getAttributeNS(null, "number");
                              copletId = copletNode.getAttributeNS(null, "id");
                              statusNode = (Element)DOMUtil.getSingleNode(delta, "status-profile/customization/coplet[@id='"+copletId+"' and @number='"+oldNumber+"']");
                              copletNode.setAttributeNS(null, "number", ""+(i+1));
                              if (statusNode != null) {
                                  statusNode.setAttributeNS(null, "number", ""+(i+1));
                                  copletsChanged = true;
                              }
                          }
                          if (copletsChanged == true) {
                              this.saveUserStatusProfile(originalProfile,
                                     this.getConfiguration(), role, id, adminProfile);
                          }
                      }
                  }
              }
          }
  
          // Last part: strip type information
          NodeList typeElements = DOMUtil.selectNodeList(delta, "descendant::*[@formpath and @formdescription and @formtype]");
          if (typeElements != null) {
              for(int i = 0; i < typeElements.getLength(); i++) {
                  ((Element)typeElements.item(i)).removeAttributeNS(null, "formpath");
                  ((Element)typeElements.item(i)).removeAttributeNS(null, "formdescription");
                  ((Element)typeElements.item(i)).removeAttributeNS(null, "formtype");
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildProfileDelta delta="+delta);
          }
          return delta;
      }
  
      /**
       * Make the difference :-)
       */
      private void diff(DocumentFragment original,
                        DocumentFragment base,
                        String           path,
                        Element          deltaElement)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is already synchronized
          Element originalRoot = (Element)DOMUtil.getSingleNode(original, path);
          Element baseRoot = (Element)DOMUtil.getSingleNode(base, path);
          if (originalRoot != null && baseRoot != null) {
              List nodeStack = new ArrayList();
              String name = baseRoot.getNodeName();
              name = name.substring(0, name.indexOf("-profile")) + "-delta";
              nodeStack.add(originalRoot.getOwnerDocument().createElementNS(null, name));
  
              this.diffNode(baseRoot, originalRoot, nodeStack, deltaElement);
          }
      }
  
      /**
       * Diff one node
       */
      private void diffNode(Element baseNode,
                            Element originalNode,
                            List nodeStack,
                            Element deltaElement)
      throws SAXException, javax.xml.transform.TransformerException {
          // calling method is already synchronized
          NodeList baseChilds;
          NodeList originalChilds;
          int      i, len;
          int      m, l;
          boolean  found;
          Node     currentOrigNode = null;
          Node     currentBaseNode = null;
  
          originalChilds = originalNode.getChildNodes();
          len = originalChilds.getLength();
          baseChilds = baseNode.getChildNodes();
          l = baseChilds.getLength();
  
          for(i = 0; i < len; i++) {
              currentOrigNode = originalChilds.item(i);
              if (currentOrigNode.getNodeType() == Node.ELEMENT_NODE) {
  
                  // search the delta node in the profile
                  m = 0;
                  found = false;
                  while (found == false && m < l) {
                      currentBaseNode = baseChilds.item(m);
                      if (currentBaseNode.getNodeType() == Node.ELEMENT_NODE
                          && currentBaseNode.getNodeName().equals(currentOrigNode.getNodeName()) == true) {
  
                          // now we have found a node with the same name
                          // next: the attributes must match also
                          found = this.compareAttributes(currentBaseNode, currentOrigNode);
                      }
                      if (found == false) m++;
                  }
  
                  if (found == true) {
                      // do we have elements as children or text?
                      currentOrigNode.normalize();
                      if (currentOrigNode.hasChildNodes() == true) {
  
                          // do a recursive call for sub elements
                          nodeStack.add(currentOrigNode);
                          this.diffNode((Element)currentBaseNode,
                                        (Element)currentOrigNode,
                                        nodeStack,
                                        deltaElement);
  
                          // and now compare the text nodes
                          String baseString = DOMUtil.getValueOfNode(currentBaseNode, "").trim();
                          String originalString = DOMUtil.getValueOfNode(currentOrigNode, "").trim();
  
                          if (baseString.equals(originalString) == false) {
                              // this is the tricky part:
                              // we have to process all nodes on the stack
                              // and insert them in the deltaElement
                              Element currentElement;
                              Element contextElement = deltaElement;
                              NodeList possibleChilds;
                              boolean  foundChild;
                              int      cIndex;
  
                              for(int p = 0; p < nodeStack.size(); p++) {
                                  currentElement = (Element)nodeStack.get(p);
                                  possibleChilds = DOMUtil.getNodeListFromPath(contextElement, new String[] {currentElement.getNodeName()});
                                  foundChild = false;
                                  cIndex = 0;
                                  if (possibleChilds != null) {
                                      while (foundChild == false && cIndex < possibleChilds.getLength()) {
                                          foundChild = this.compareAttributes(currentElement, possibleChilds.item(cIndex));
                                          if (foundChild == false) cIndex++;
                                      }
                                  }
                                  if (foundChild == true) {
                                      contextElement = (Element)possibleChilds.item(cIndex);
                                  } else {
                                      currentElement = (Element)currentElement.cloneNode(false);
                                      contextElement.appendChild(currentElement);
                                      contextElement = currentElement;
                                  }
                              }
                              // now add the text
                              contextElement.appendChild(contextElement.getOwnerDocument().createTextNode(originalString));
                          }
  
                          nodeStack.remove(nodeStack.size()-1);
                      }
                  }
              }
  
          }
  
      }
  
      /**
       * Builds the key for caching
       */
      public String getProfileID(String type,
                                  String role,
                                  String id,
                                  boolean adminProfile) {
          // No sync required
          StringBuffer key = new StringBuffer((adminProfile == true ? "aprofile:" : "uprofile:"));
          key.append((String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME))
             .append('|')
             .append((String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME))
             .append(':')
             .append(type);
  
          if (type.equals(PortalManager.BUILDTYPE_VALUE_ROLE) == true
              || type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
              role = XMLUtil.encode(role);
              key.append('_').append(role.length()).append('_').append(role);
          }
          if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
              id = XMLUtil.encode(id);
              key.append('_').append(id);
          }
          return key.toString();
      }
  
      /**
       * Get the profile role from the key
       */
      private boolean getIsAdminProfile(String profileID) {
          // No sync required
          return profileID.startsWith("a");
      }
  
      /**
       * Get the profile role from the key
       */
      private String getRole(String profileID) {
          // No sync required
          profileID = XMLUtil.decode(profileID);
          int pos = profileID.indexOf('_');
          if (pos == -1) {
              return null;
          } else {
              String lastPart = profileID.substring(pos+1);
              pos = lastPart.indexOf('_');
              if (pos == -1) return null;
              int len = new Integer(lastPart.substring(0, pos)).intValue();
              lastPart = lastPart.substring(pos+1, pos+1+len);
              return lastPart;
          }
      }
  
      /**
       * Get the profile ID from the key
       */
      private String getID(String profileID) {
          // No sync required
          profileID = XMLUtil.decode(profileID);
          int pos = profileID.indexOf('_');
          if (pos == -1) {
              return null;
          } else {
              String lastPart = profileID.substring(pos+1);
              pos = lastPart.indexOf('_');
              if (pos == -1) {
                  return null;
              } else {
                  lastPart = lastPart.substring(pos+1);
                  pos = lastPart.indexOf('_');
                  if (pos == -1) {
                      return null;
                  } else {
                      return lastPart.substring(pos+1);
                  }
              }
          }
      }
  
      /**
       * Get the profile type from the key
       */
      private String getType(String profileID) {
          // No sync required
          profileID = XMLUtil.decode(profileID);
          int endPos = profileID.indexOf('_');
          if (endPos == -1) {
              int startPos = profileID.lastIndexOf(':');
              return profileID.substring(startPos+1);
          } else {
              int startPos = profileID.lastIndexOf(':', endPos);
              return profileID.substring(startPos+1, endPos);
          }
      }
  
      /**
       * Store the profil
       */
      private void storeProfile(String profileID,
                                Map profile)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN storeProfile id="+profileID+", profile="+profile);
          }
  
          Session session = this.getSessionManager().getSession(true);
          synchronized(session) {
              session.setAttribute(profileID, profile);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END storeProfile");
          }
      }
  
      /**
       * Retrieve the profil
       */
      public Map retrieveProfile(String profileID)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN retrieveProfile id="+profileID);
          }
          Session session = this.getSessionManager().getSession(true);
          Map result;
          synchronized(session) {
              result = (Map)session.getAttribute(profileID);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END retrieveProfile profile="+(result != null ? "**PROFILE**" : "null"));
          }
  
          return result;
      }
  
      /**
       * Check if the profile is already cached
       */
      private boolean isProfileCached(String profileID, Map configuration)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN isProfileCached id="+profileID+", configuration="+configuration);
          }
          boolean result = false;
  
          if (configuration != null && this.getIsAdminProfile(profileID) == false) {
              String storePrefix = (String)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
              if (storePrefix != null) {
                  String key = profileID.substring(1);
                  result = this.getProfileStore().containsKey(key);
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END isProfileCached result="+result);
          }
          return result;
      }
  
      /**
       * Cache the profile (if cache is turned on)
       */
      private void cacheProfile(String profileID,
                                Map profile,
                                Map configuration) {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN cacheProfile id="+profileID+", profile="+profile);
          }
          try {
              if (configuration != null && this.getIsAdminProfile(profileID) == false) {
                  String storePrefix = (String)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
                  if (storePrefix != null) {
                      String key = profileID.substring(1);
                      this.getProfileStore().store(key, profile);
                  }
              }
          } catch (Exception local) {
              this.getLogger().warn("Caching Profile failed.", local);
              // local exceptions are ignored
              // we dont want to get an exception response due to cache problems
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END cacheProfile");
          }
      }
  
      /**
       * Retrieve the cached profil if available
       */
      private Map getCachedProfile(String profileID, Map configuration) {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getCachedProfile id="+profileID);
          }
  
          Map result = null;
  
          try {
              if (configuration != null && this.getIsAdminProfile(profileID) == false) {
                  final String storePrefix = (String)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
                  if (storePrefix != null) {
                      final String key = profileID.substring(1);
                      final Store store = this.getProfileStore();
                      if (store.containsKey(key) == true) {
                          result = (Map)store.get(key);
                      }
                  }
              }
          } catch (Exception local) {
              // local exceptions are ignored
              // we dont want to get an exception response due to cache problems
              this.getLogger().warn("Getting cached Profile failed.", local);
              result = null;
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getCachedProfile profile="+(result != null ? "**PROFILE**" : "null"));
          }
          return result;
      }
  
      /**
       * Clean up the cache, if the global profile was saved, delete all role and user profiles.
       * If a role profile was saved delete all user profiles. If the basic profile was
       * saved delete all profiles.
       */
      private void cleanUpCache(String type, String role, Map configuration)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN cleanUpCache type="+type+", role="+role+", config="+configuration);
          }
          if (configuration != null
              && type != null
              && type.equals(PortalManager.BUILDTYPE_VALUE_ID) == false) {
              String storePrefix = (String)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
              if (storePrefix != null) {
                  Store store = this.getProfileStore();
                  Enumeration keys = store.keys();
                  String   currentKey;
                  String  deleteGlobal = null;
                  String  deleteRole = null;
                  String  deleteUser = null;
  
                  if (type.equals(PortalManager.BUILDTYPE_VALUE_BASIC) == true ||
                      type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true) {
                      if (type.equals(PortalManager.BUILDTYPE_VALUE_BASIC) == true) {
                          deleteGlobal = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, false).substring(1);
                      }
                      deleteRole = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, false);
                      deleteRole = deleteRole.substring(1, deleteRole.lastIndexOf(':')+1) + PortalManager.BUILDTYPE_VALUE_ROLE;
                      deleteUser = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, false);
                      deleteUser = deleteUser.substring(1, deleteUser.lastIndexOf(':')+1) + PortalManager.BUILDTYPE_VALUE_ID;
                  } else { // role
                      deleteGlobal = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ROLE, role, null, false).substring(1);
                      deleteUser = this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID, role, "a", false);
                      deleteUser = deleteUser.substring(1, deleteUser.length()-1);
                  }
  
                  while (keys.hasMoreElements() == true) {
                      currentKey = (String)keys.nextElement();
                      if (deleteGlobal != null && currentKey.equals(deleteGlobal) == true) {
                          store.remove(currentKey);
                      } else if (deleteRole != null && currentKey.startsWith(deleteRole) == true) {
                          store.remove(currentKey);
                      } else if (deleteUser != null && currentKey.startsWith(deleteUser) == true) {
                          store.remove(currentKey);
                      }
                  }
              }
          } else if (configuration != null && type == null) {
              // clean whole cache
              String storePrefix = (String)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
              if (storePrefix != null) {
                  Store store = this.getProfileStore();
                  Enumeration keys = store.keys();
                  String currentKey;
                  String delete;
  
                  delete = this.getProfileID(PortalManager.BUILDTYPE_VALUE_GLOBAL, null, null, false);
                  delete = delete.substring(1, delete.lastIndexOf(':') + 1);
                  while (keys.hasMoreElements() == true) {
                      currentKey = (String)keys.nextElement();
                      if (currentKey.startsWith(delete) == true) {
                          store.remove(currentKey);
                      }
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END cleanUpCache");
          }
      }
  
      /**
       * Build the run profil and store it in the <code>profileMap</code>.
       */
      private void buildRunProfile(Map              profileMap,
                                   SessionContext  context,
                                   DocumentFragment baseProfile)
      throws SAXException, ProcessingException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildRunProfile context="+context+", profile="+baseProfile);
          }
  
          // The map containing the coplets which appear on each medium
          Map defaultCoplets = new HashMap(20, 5);
          // The map containing for each media type a map with coplets which
          // appear only for the given media
          Map mediaCoplets   = new HashMap(5, 2);
  
          profileMap.put(PortalConstants.PROFILE_DEFAULT_COPLETS, defaultCoplets);
          profileMap.put(PortalConstants.PROFILE_MEDIA_COPLETS, mediaCoplets);
  
          // get AuthenticationManager instance
          String[] types = this.getAuthenticationManager().getMediaTypes();
          Map      mediaMap;
          for(int i = 0; i < types.length; i++) {
              mediaCoplets.put(types[i], new HashMap(5, 3));
          }
  
          // build misc nodes
          Node[] miscNodes = new Node[13];
          miscNodes[PortalConstants.PROFILE_MISC_HEADER_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","layout-profile","portal","header","exists"}, false);
          miscNodes[PortalConstants.PROFILE_MISC_FOOTER_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","layout-profile","portal","footer","exists"}, false);
          miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","portal-profile","content","header"}, false);
          miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","portal-profile","content","footer"}, false);
          miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]= DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","layout-profile","portal","columns","number"}, false);
          miscNodes[PortalConstants.PROFILE_MISC_MESSAGES_NODE]= DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","personal-profile","messages"}, false);
          for(int i = 1; i <= PortalConstants.MAX_COLUMNS; i++) {
              miscNodes[7 + i] = DOMUtil.getSingleNode(baseProfile,
                  "profile/portal-profile/content/column[@position='"+i+"']");
          }
  
          profileMap.put(PortalConstants.PROFILE_MISC_POINTER, miscNodes);
  
          // build coplet configs
          NodeList coplets;
          int      i, l;
          Element  configElement;
          String   copletID;
          String   copletMedia;
  
          coplets = DOMUtil.getNodeListFromPath(baseProfile, new String[] {"profile","coplets-profile","coplets","coplet"});
  
          if (coplets != null) {
  
              l = coplets.getLength();
              for(i = 0; i < l; i++) {
                  configElement = (Element)coplets.item(i);
                  if (DOMUtil.getValueAsBooleanOf(configElement, "configuration/active") == true) {
  
                      copletID = configElement.getAttributeNS(null, "id");
                      if (configElement.hasAttributeNS(null, "media") == true) {
                          copletMedia = configElement.getAttributeNS(null, "media");
                          mediaMap = (Map)mediaCoplets.get(copletMedia);
                          if (mediaMap != null) {
                              mediaMap.put(copletID, configElement);
                          }
                      } else {
                          copletMedia = null;
                          defaultCoplets.put(copletID, configElement);
                      }
  
                      // Now: add the coplet if mandatory and missing
                      if (DOMUtil.getValueAsBooleanOf(configElement, "configuration/mandatory") == true) {
                          // get all coplet instances
                          NodeList copletElements;
  
                          // the next is crap, but it works....
                          // search all coplets (columns, header, footer)
                          if (copletMedia == null) {
                              copletElements = DOMUtil.selectNodeList(baseProfile,
                                  "profile/portal-profile/content/column/coplets/coplet[@id='"+copletID+"' and not(@media)]");
                          } else {
                              copletElements = DOMUtil.selectNodeList(baseProfile,
                                  "profile/portal-profile/content/column/coplets/coplet[@id='"+copletID+"' and media='"+copletMedia+"']");
                          }
  
                          if (copletElements == null || copletElements.getLength() == 0) {
                              if (copletMedia == null) {
                                  copletElements = DOMUtil.selectNodeList(baseProfile,
                                     "profile/portal-profile/content/header/coplet[@id='"+copletID+"' and not(@media)]");
                              } else {
                                  copletElements = DOMUtil.selectNodeList(baseProfile,
                                     "profile/portal-profile/content/header/coplet[@id='"+copletID+"' and media='"+copletMedia+"']");
                              }
                          }
  
                          if (copletElements == null || copletElements.getLength() == 0) {
                              if (copletMedia == null) {
                                  copletElements = DOMUtil.selectNodeList(baseProfile,
                                     "profile/portal-profile/content/footer/coplet[@id='"+copletID+"' and not(@media)]");
                              } else {
                                  copletElements = DOMUtil.selectNodeList(baseProfile,
                                     "profile/portal-profile/content/footer/coplet[@id='"+copletID+"' and media='"+copletMedia+"']");
                              }
                          }
  
                          if (copletElements == null || copletElements.getLength() == 0) {
                              // mandatory coplet is not configured, so add it to the first column
                              Node content = DOMUtil.getSingleNode(baseProfile,
                                    "profile/portal-profile/content/column[@position='1']/coplets");
                              if (content == null)
                                  throw new ProcessingException("Element not found: portal-profile/content/column/coplets");
                              Element el = content.getOwnerDocument().createElementNS(null, "coplet");
                              el.setAttributeNS(null, "id", copletID);
                              if (copletMedia != null) {
                                  el.setAttributeNS(null, "media", copletMedia);
                              }
                              // Set position attribute
                              NodeList childs = DOMUtil.getNodeListFromPath(content, new String[] {"coplet"});
                              int      childsCount = (childs == null ? 0 : childs.getLength());
                              el.setAttributeNS(null, "position", ""+(childsCount+1));
                              Text    t;
                              content.appendChild(el);
                              content = el;
                              el = content.getOwnerDocument().createElementNS(null, "status");
                              content.appendChild(el);
                              content = el;
                              el = content.getOwnerDocument().createElementNS(null, "visible");
                              content.appendChild(el);
                              content = el;
                              t = content.getOwnerDocument().createTextNode("true");
                              content.appendChild(t);
                          } else {
                              // is any of them visible?
                              boolean found;
                              boolean origVisible = DOMUtil.getValueAsBooleanOf(configElement, "status/visible");
                              int si, sl;
                              sl = copletElements.getLength();
                              si = 0;
                              found = false;
                              while (si < sl && found == false) {
                                  found = DOMUtil.getValueAsBooleanOf(copletElements.item(si),
                                             "status/visible", origVisible);
                                  si++;
                              }
                              if (found == false) {
                                  // set first to visible
                                  // first: is status node available
                                  Node statusElem = DOMUtil.getFirstNodeFromPath(copletElements.item(0), new String[] {"status"}, false);
                                  if (statusElem == null) {
                                      statusElem = copletElements.item(0).getOwnerDocument().createElementNS(null, "status");
                                      copletElements.item(0).appendChild(statusElem);
                                  }
                                  // second: is visible node available
                                  Node visibleElem = DOMUtil.getFirstNodeFromPath(statusElem, new String[] {"visible"}, false);
                                  if (visibleElem == null) {
                                      visibleElem = statusElem.getOwnerDocument().createElementNS(null, "visible");
                                      statusElem.appendChild(visibleElem);
                                  }
                                  // remove old childs
                                  while (visibleElem.hasChildNodes() == true) {
                                      visibleElem.removeChild(visibleElem.getFirstChild());
                                  }
                                  visibleElem.appendChild(statusElem.getOwnerDocument().createTextNode("true"));
                              }
                          }
                      }
                  }
              }
          }
  
          // Numerate all coplets by adding an attribute number with a unique value
          // and put them into the corresponding maps.
          // update the status section of the coplet: Only the values of the coplet
          // configuration are allowed. Not less and not more!
          // All coplets are required to have
          // the number attribute! So this is only a compatibility function
          // which adds the first time the number to the coplets
          // If the number attribute is available, the node with the highest
          // number is searched
          NodeList copletElements;
          int     number = 0;
          Element  content = (Element)DOMUtil.getFirstNodeFromPath(baseProfile,
                         new String[] {"profile","portal-profile","content"}, false);
          Element  currentCoplet;
          NodeList statusConfigList;
          NodeList statusCopletList;
          Element  statusCopletElement;
          int      list_index, list_length;
          Node     currentStatus;
          int      highestCopletNumber = -1;
  
          for(i = 0; i < 7; i++) {
              if (i == 0) {
                  copletElements = DOMUtil.getNodeListFromPath(content,
                     new String[] {"header","coplet"});
              } else if (i == 1) {
                  copletElements = DOMUtil.getNodeListFromPath(content,
                     new String[] {"footer","coplet"});
              } else {
                  copletElements = DOMUtil.selectNodeList(content,
                     "column[@position='"+(i-1)+"']/coplets/coplet");
              }
              if (copletElements != null && copletElements.getLength() > 0) {
                  Element[] list = new Element[copletElements.getLength()];
                  for(int index = 0; index < copletElements.getLength(); index++) {
                      list[index] = (Element)copletElements.item(index);
                  }
  
                  for(int index = 0; index < list.length; index++) {
                      // get coplet element
                      currentCoplet = list[index];
  
                      String numberValue = currentCoplet.getAttributeNS(null, "number");
                      if (numberValue == null || numberValue.equals("") == true) {
                          // create unique number attribute
                          currentCoplet.setAttributeNS(null, "number", ""+number);
                          miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = currentCoplet;
                          number++;
                      } else {
                          int currentNumber = new Integer(numberValue).intValue();
                          if (currentNumber > highestCopletNumber) {
                              highestCopletNumber = currentNumber;
                              number = highestCopletNumber+1;
                              miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = currentCoplet;
                          }
                      }
                      // update status
                      configElement = this.getCopletConfiguration(currentCoplet.getAttributeNS(null, "id"),
                                                        defaultCoplets,
                                                        mediaCoplets);
                      if (configElement != null) {
                          statusCopletElement = (Element)DOMUtil.selectSingleNode(configElement, "status");
                          statusConfigList = DOMUtil.selectNodeList(statusCopletElement, "*");
                          statusCopletList = DOMUtil.selectNodeList(currentCoplet, "status/*");
                          // first test if each status is included in the config
                          if (statusCopletList != null) {
                              list_length = statusCopletList.getLength();
                              for(list_index = list_length-1; list_index >= 0; list_index--) {
                                  currentStatus = statusCopletList.item(list_index);
                                  if (currentStatus.getNodeType() == Node.ELEMENT_NODE) {
                                      if (DOMUtil.getFirstNodeFromPath(configElement, new String[] {"status", currentStatus.getNodeName()}, false) == null) {
                                          currentStatus.getParentNode().removeChild(currentStatus);
                                      }
                                  }
                              }
                          }
                          // second, test if each status attribute of the config is included
                          if (statusConfigList != null) {
                              list_length = statusConfigList.getLength();
                              for(list_index = 0; list_index < list_length; list_index++) {
                                  currentStatus = statusConfigList.item(list_index);
                                  if (currentStatus.getNodeType() == Node.ELEMENT_NODE) {
                                      if (DOMUtil.getFirstNodeFromPath(statusCopletElement, new String[] {currentStatus.getNodeName()}, false) == null) {
                                          // create a new element
                                          statusCopletElement.appendChild(statusCopletElement.getOwnerDocument().importNode(currentStatus, true));
                                      }
                                  }
                              }
                          }
                      } else {
                          // coplet not in configuration
                          // adopt position of following coplets and then remove
                          String posAttr = currentCoplet.getAttributeNS(null, "position");
                          NodeList followUps = DOMUtil.selectNodeList(currentCoplet.getParentNode(), "coplet[@position > '"+posAttr+"']");
                          if (followUps != null) {
                              int value;
                              for(int iq = 0; iq < followUps.getLength(); iq++) {
                                  value = new Integer(((Element)followUps.item(iq)).getAttributeNS(null, "position")).intValue();
                                  value -= 1;
                                  ((Element)followUps.item(iq)).setAttributeNS(null, "position", "" + value);
                              }
                          }
                          currentCoplet.getParentNode().removeChild(currentCoplet);
                      }
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildRunProfile");
          }
      }
  
      /**
       *  Add the type information to the profile and do some type checkings
       */
      private void buildTypeProfile(Map              theProfile,
                                    SessionContext  context,
                                    DocumentFragment baseProfile)
      throws SAXException, ProcessingException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildTypeProfile context="+context+", profile="+baseProfile);
          }
          List list = new ArrayList(25);
          List confList = new ArrayList(25);
  
          theProfile.put(PortalConstants.PROFILE_TYPE_PATHS, list);
          theProfile.put(PortalConstants.PROFILE_TYPE_CONF_PATHS, confList);
  
          Element typeElement;
  
          typeElement = (Element)DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","type-profile","elements"}, false);
          if (typeElement != null) {
              if (typeElement.hasChildNodes() == true)
                  this.addTypePath(list, typeElement.getChildNodes(), "profile");
  
              // now we have the list with the xpaths
              this.setTypeInfo(baseProfile, list, null);
  
              // build the conf paths
              int i, l, pos;
              String current;
  
              l = list.size();
              for(i = 0; i < l; i++) {
                  current = (String)list.get(i);
  
                  // now the path has to be changed: the new attributes must be included
                  pos = current.lastIndexOf('/');
                  current = current.substring(0, pos);
  
                  pos = current.lastIndexOf('[');
                  if (current.substring(pos+1).equals("not(@*)]") == true) {
                      current = current.substring(0, pos+1);
                  } else {
                      current = current.substring(0, current.length()-1) + " and ";
                  }
                  current += "@formtype and @formpath and @formdescription]";
                  confList.add(current);
              }
  
          }
  
          // and now the type checking part:
          //
          // If the default layout has changed the number of columns and the current
          // user (or role) is not allowed to change this, we have to adjust the
          // profile. Otherwise the current number of columns has to be stored
          // into the profile layout part.
          Element layoutColumnsNode = (Element)DOMUtil.getFirstNodeFromPath(baseProfile, new String[] {"profile","layout-profile","portal","columns","number"}, false);
          String layoutValue = DOMUtil.getValueOfNode(layoutColumnsNode);
          int layoutColumns = 0;
          if (layoutValue != null && new Integer(layoutValue).intValue() > 0) {
              layoutColumns = new Integer(layoutValue).intValue();
          }
          NodeList columnNodes = DOMUtil.selectNodeList(baseProfile, "profile/portal-profile/content/column[@position]");
          int columns = columnNodes.getLength();
          if (columns != layoutColumns) {
              if (layoutColumnsNode.hasAttributeNS(null, "formtype") == true) {
                  DOMUtil.setValueOfNode(layoutColumnsNode, ""+columns);
              } else {
                  this.changeColumns(baseProfile,
                                     columns,
                                     layoutColumns,
                                     (Node[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER));
                  this.setTypeInfo(baseProfile,
                                   (List)theProfile.get(PortalConstants.PROFILE_TYPE_PATHS),
                                   (List)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS));
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildTypeProfile");
          }
      }
  
      /**
       * Set the tpe information
       */
      private void setTypeInfo(DocumentFragment baseProfile, List paths, List confPaths)
      throws SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN setTypeInfo profile="+baseProfile+", paths="+paths);
          }
          if (baseProfile != null && paths != null) {
              int pos;
              String currentPath;
              String value;
              String description;
              NodeList nodes;
              int nodes_count;
              int path_count = paths.size();
              Node currentNode;
  
              for(int i = 0; i < path_count; i++) {
                  currentPath = (String)paths.get(i);
                  pos = currentPath.lastIndexOf('/');
                  value = currentPath.substring(pos + 1);
                  currentPath = currentPath.substring(0, pos);
                  pos = value.indexOf("|");
                  if (pos != -1) {
                      description = value.substring(pos + 1);
                      value = value.substring(0, pos);
                  } else {
                      description = "UNKNOWN";
                  }
  
                  // get all nodes
                  boolean changed = false;
                  nodes = DOMUtil.selectNodeList(baseProfile, currentPath);
                  if (nodes != null) {
                      nodes_count = nodes.getLength();
                      for(int m = 0; m < nodes_count; m++) {
                          currentNode = nodes.item(m);
                          if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                              ((Element)currentNode).setAttributeNS(null, "formtype", value);
                              ((Element)currentNode).setAttributeNS(null, "formpath",
                                       PortalManager.REQ_PARAMETER_CONF + '.' + i + '.' + m);
                              ((Element)currentNode).setAttributeNS(null, "formdescription", description);
                              changed = true;
                          }
                      }
                  }
                  if (changed == true && confPaths != null) {
                      currentPath = (String)confPaths.get(i);
                      nodes = DOMUtil.selectNodeList(baseProfile, currentPath);
                      if (nodes != null) {
                          nodes_count = nodes.getLength();
                          for(int m = 0; m < nodes_count; m++) {
                              currentNode = nodes.item(m);
                              if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                                  ((Element)currentNode).setAttributeNS(null, "formpath",
                                       PortalManager.REQ_PARAMETER_CONF + '.' + i + '.' + m);
                              }
                          }
                      }
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END setTypeInfo");
          }
      }
  
  
      /**
       * Add the type info to the xpath. This is done recursevly
       */
      private void addTypePath(List list, NodeList childs, String path) {
          // calling method is synced
          int i, l;
          Element current;
          StringBuffer newPath;
  
          l = childs.getLength();
          for(i = 0; i < l; i++) {
              if (childs.item(i).getNodeType() == Node.ELEMENT_NODE) {
                  current = (Element)childs.item(i);
                  newPath = new StringBuffer(path);
                  newPath.append('/').append(current.getNodeName());
                  if (current.hasAttributes() == true) {
                      NamedNodeMap nnm = current.getAttributes();
                      int ia, la;
                      boolean first = true;
                      StringBuffer expression = new StringBuffer();
                      la = nnm.getLength();
                      newPath.append('[');
                      for(ia = 0; ia < la; ia++) {
                          if (nnm.item(ia).getNodeName().equals("type") == false
                              && nnm.item(ia).getNodeName().equals("description") == false) {
                              if (first == false) expression.append(" and ");
                              if (nnm.item(ia).getNodeValue().equals("*") == false) {
                                  expression.append('@')
                                    .append(nnm.item(ia).getNodeName())
                                    .append("='")
                                    .append(nnm.item(ia).getNodeValue())
                                    .append("'");
                              } else {
                                  expression.append('@').append(nnm.item(ia).getNodeName());
                              }
                              first = false;
                          }
                      }
                      if (first == true) {
                          newPath.append("not(@*)");
                      } else {
                          newPath.append(expression);
                      }
                      newPath.append(']');
                  } else {
                      newPath.append("[not(@*)]");
                  }
                  if (current.getAttributeNS(null, "type").length() > 0) {
                      list.add(newPath.toString() + '/' + current.getAttributeNS(null, "type") + '|' + current.getAttributeNS(null, "description"));
                  } else {
                      if (current.hasChildNodes() == true) {
                          this.addTypePath(list, current.getChildNodes(), newPath.toString());
                      }
                  }
              }
          }
      }
  
      /**
       * Build the Map with the portal layouts
       */
      private Map buildPortalLayouts(SessionContext context,
                                   DocumentFragment baseProfile)
      throws SAXException, ProcessingException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildPortalLayouts context="+context+", profile="+baseProfile);
          }
          Map layouts = new HashMap(5, 2);
          Element defLayout = (Element)DOMUtil.getSingleNode(baseProfile,
                          "profile/layout-profile/portal/layouts/layout[not(@*)]");
          Node currentLayout;
          String[] types = this.getAuthenticationManager().getMediaTypes();
  
          for(int i = 0; i < types.length; i++) {
               currentLayout = DOMUtil.getSingleNode(baseProfile,
                 "profile/layout-profile/portal/layouts/layout[media='"+types[i]+"']");
               layouts.put(types[i], (currentLayout == null ? defLayout : currentLayout));
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildPortalLayouts layouts="+layouts);
          }
          return layouts;
      }
  
      /**
       * Build the Map with the coplet layouts
       */
      private Map buildcopleyLayouts(SessionContext context,
                                   DocumentFragment baseProfile)
      throws SAXException, ProcessingException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildcopleyLayouts context="+context+", profile="+baseProfile);
          }
          Map layouts = new HashMap(5, 2);
          Element defLayout = (Element)DOMUtil.getSingleNode(baseProfile,
                          "profile/layout-profile/coplets/layouts/layout[not(@*)]");
          Node currentLayout;
          String[] types = this.getAuthenticationManager().getMediaTypes();
  
          for(int i = 0; i < types.length; i++) {
              currentLayout = DOMUtil.getSingleNode(baseProfile,
                 "profile/layout-profile/coplets/layouts/layout[media='"+types[i]+"']");
             layouts.put(types[i], (currentLayout == null ? defLayout : currentLayout));
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildcopleyLayouts layouts="+layouts);
          }
          return layouts;
      }
  
      /**
       * Import a delta into the profile
       */
      private void importProfileDelta(Element          profileRoot,
                                    DocumentFragment delta,
                                    String           deltaRootTagName,
                                    String           deltaTag)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException  {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN importProfileDelta root=" + profileRoot + ", delta=" + delta + ", deltaRoot:" + deltaRootTagName + ", delta: " + deltaTag);
          }
          Node     deltaRoot   = null;
  
          deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String[] {deltaRootTagName, deltaTag}, false);
  
          if (deltaRoot != null) {
              // root tag found in delta , now search root tag in profile
              String searchName = deltaRoot.getNodeName().substring(0, deltaRoot.getNodeName().lastIndexOf("-delta"));
              searchName = searchName + "-profile";
  
              profileRoot = (Element)DOMUtil.getFirstNodeFromPath(profileRoot, new String[] {searchName}, false);
              if (profileRoot == null) {
                  throw new ProcessingException("Importing Delta: Tag " + searchName + " not found in profile.");
              }
  
              // now import it
              this.importNode(profileRoot, (Element)deltaRoot);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END importProfileDelta");
          }
      }
  
      /**
       * Add the node to the profile (replace an existing one)
       */
      private void addProfilePart(Element          profileRoot,
                                DocumentFragment delta,
                                String           deltaRootTagName,
                                String           deltaTag)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
             this.getLogger().debug("BEGIN addProfilePart root=" + profileRoot + ", delta=" + delta + ", deltaRoot:" + deltaRootTagName + ", delta: " + deltaTag);
          }
          Node     deltaRoot   = null;
          Node     oldNode     = null;
  
          if (deltaRootTagName != null) {
              deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String[] {deltaRootTagName, deltaTag}, false);
          } else {
              deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String[] {deltaTag}, false);
          }
  
          if (deltaRoot != null) {
              // root tag found in delta found, now search root tag in profile
              oldNode = (Element)DOMUtil.getFirstNodeFromPath(profileRoot, new String[] {deltaTag}, false);
              if (oldNode == null) {
                  profileRoot.appendChild(profileRoot.getOwnerDocument().importNode(deltaRoot, true));
              } else {
                  profileRoot.replaceChild(profileRoot.getOwnerDocument().importNode(deltaRoot, true), oldNode);
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END addProfilePart");
          }
      }
  
  
      /**
       * This is the hardest part. Incorporting a node into the profile.
       * For performance reasons there is now tracing here.
       */
      private void importNode(Element profile, Element delta) {
          // calling method is synced
          NodeList profileChilds = null;
          NodeList deltaChilds   = delta.getChildNodes();
          int      i, len;
          int      m, l;
          boolean  found;
          Node     currentDelta = null;
          Node     currentProfile = null;
  
          len = deltaChilds.getLength();
          for(i = 0; i < len; i++) {
              currentDelta = deltaChilds.item(i);
              if (currentDelta.getNodeType() == Node.ELEMENT_NODE) {
                  // search the delta node in the profile
                  profileChilds = profile.getChildNodes();
                  l = profileChilds.getLength();
                  m = 0;
                  found = false;
                  while (found == false && m < l) {
                      currentProfile = profileChilds.item(m);
                      if (currentProfile.getNodeType() == Node.ELEMENT_NODE
                          && currentProfile.getNodeName().equals(currentDelta.getNodeName()) == true) {
  
                          // now we have found a node with the same name
                          // next: the attributes must match also
                          found = this.compareAttributes(currentProfile, currentDelta);
                      }
                      if (found == false) m++;
                  }
                  if (found == true) {
                      // this is not new
  
                      // do we have elements as children or text?
                      if (currentDelta.hasChildNodes() == true) {
                          currentDelta.normalize();
                          currentProfile.normalize();
                          // do a recursive call for sub elements
                          this.importNode((Element)currentProfile, (Element)currentDelta);
                          // and now the text nodes: Remove all from the profile and add all
                          // of the delta
                          NodeList childs = currentProfile.getChildNodes();
                          int      index, max;
                          max = childs.getLength();
                          for(index = max - 1; index >= 0; index--) {
                              if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
                                  currentProfile.removeChild(childs.item(index));
                              }
                          }
                          childs = currentDelta.getChildNodes();
                          max = childs.getLength();
                          for(index = 0; index < max; index++) {
                              if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
                                  currentProfile.appendChild(currentProfile.getOwnerDocument()
                                       .createTextNode(childs.item(index).getNodeValue()));
                              }
                          }
                      }
                  } else {
                      // this is a new node, so it is considered as an old information
                      // No inserting: profile.appendChild(profile.getOwnerDocument().importNode(currentDelta, true));
                  }
              }
  
          }
  
      }
  
      /**
       * Compare Attributes of two nodes. This method returns true only if both
       * nodes have the same number of attributes and the same attributes with equal
       * values.
       * Namespacedefinition nodes are ignored
       * BUT: For type handling the attributes <code>formtype</code>,
       *      <code>formdescription</code> and <code>formpath</code> are ignored!
       */
      private boolean compareAttributes(Node first, Node second) {
          // calling method is synced
          NamedNodeMap attr1 = first.getAttributes();
          NamedNodeMap attr2 = second.getAttributes();
          String value;
  
          if (attr1 == null && attr2 == null) return true;
          if (attr1 == null || attr2 == null) return false;
          int attr1Len = (attr1 == null ? 0 : attr1.getLength());
          int attr2Len = (attr2 == null ? 0 : attr2.getLength());
          if (attr1Len > 0) {
              if (attr1.getNamedItemNS(null, "formtype") != null) attr1Len--;
              if (attr1.getNamedItemNS(null, "formpath") != null) attr1Len--;
              if (attr1.getNamedItemNS(null, "formdescription") != null) attr1Len--;
              int l = attr1.getLength();
              for(int i=0;i<l;i++) {
                  if (attr1.item(i).getNodeName().startsWith("xmlns:") == true)
                      attr1Len--;
              }
          }
          if (attr2Len > 0) {
              if (attr2.getNamedItemNS(null, "formtype") != null) attr2Len--;
              if (attr2.getNamedItemNS(null, "formpath") != null) attr2Len--;
              if (attr2.getNamedItemNS(null, "formdescription") != null) attr2Len--;
              int l = attr2.getLength();
              for(int i=0;i<l;i++) {
                  if (attr2.item(i).getNodeName().startsWith("xmlns:") == true)
                      attr2Len--;
              }
          }
          if (attr1Len != attr2Len) return false;
          int i, l;
          int m, l2;
          i = 0;
          l = attr1.getLength();
          l2 = attr2.getLength();
          boolean ok = true;
          // each attribute of first must be in second with the same value
          while (i < l && ok == true) {
              value = attr1.item(i).getNodeName();
              if (value.equals("formtype") == false
                  && value.equals("formpath") == false
                  && value.equals("formdescription") == false
                  && value.startsWith("xmlns:") == false) {
                  ok = false;
                  m = 0;
                  while (m < l2 && ok == false) {
                      if (attr2.item(m).getNodeName().equals(value) == true) {
                          // same name, same value?
                          ok = attr1.item(i).getNodeValue().equals(attr2.item(m).getNodeValue());
                      }
                      m++;
                  }
  
              }
              i++;
          }
          return ok;
      }
  
  
      /**
       * Parse the fragment(tree denoted by the element)
       * and include the processed xml in the output
       */
      private void processCopletList(List        copletList,
                                     XMLConsumer consumer,
                                     String      copletNotAvailableMessage,
                                     long        defaultCopletTimeout)
      throws ProcessingException, SAXException, IOException, javax.xml.transform.TransformerException {
          // calling method is synced
          for(int i = 0; i < copletList.size(); i++) {
              this.processCoplet((Object[])copletList.get(i),
                           consumer, copletNotAvailableMessage, defaultCopletTimeout);
          }
      }
  
      /**
       * Parse the fragment(tree denoted by the element)
       * and include the processed xml in the output
       */
      private void loadCoplets(Element element,
                               Map     defaultCoplets,
                               Map     mediaCoplets,
                               List    copletList,
                               boolean parallelCoplets,
                               long    defaultCopletTimeout,
                               Element statusProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          // All children, which are coplets are processed, all other tags
          // are ignored
          if (element.hasChildNodes() == true) {
              NodeList childs = element.getChildNodes();
              Node     current = null;
              int i, l;
              l = childs.getLength();
              for(i = 0; i < l; i++) {
                  current = childs.item(i);
                  if (current.getNodeType() == Node.ELEMENT_NODE
                      && current.getNodeName().equals("coplet") == true) {
  
                      // now we have a coplet
                      this.loadCoplet((Element)current,
                               defaultCoplets,
                               mediaCoplets,
                               copletList,
                               parallelCoplets,
                               defaultCopletTimeout,
                               statusProfile);
                  }
              }
          }
      }
  
      /**
       * Load a coplet and store the binary output in the list
       */
      private void loadCoplet(Element         element,
                              Map             defaultCoplets,
                              Map             mediaCoplets,
                              List            copletList,
                              boolean         parallelCoplets,
                              long            defaultCopletTimeout,
                              Element         statusProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          String copletID = element.getAttributeNS(null, "id");
  
          Element copletConf = this.getCopletConfiguration(copletID, defaultCoplets, mediaCoplets);
          if (copletConf != null) {
  
               // first: check visibility
              boolean visible = DOMUtil.getValueAsBooleanOf(element,
                  "status/visible");
              // second: check media
              String media = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE);
              if (visible == true && copletConf.hasAttributeNS(null, "media") == true) {
                  String copletMedia = copletConf.getAttributeNS(null, "media");
                  visible = media.equals(copletMedia);
              }
  
              if (visible == true) {
  
                  Object[] loadedCoplet = new Object[8];
                  copletList.add(loadedCoplet);
  
                  boolean isCustomizable = DOMUtil.getValueAsBooleanOf(copletConf, "configuration/customizable", false);
                  if (isCustomizable == true) {
                      boolean showCustomizePage = DOMUtil.getValueAsBooleanOf(element, "status/customize", false);
                      boolean hasConfig = false;
                      if (statusProfile != null) {
                          Element customInfo = (Element)DOMUtil.getSingleNode(statusProfile,
                                "customization/coplet[@id='"+copletID+"' and @number='"+element.getAttributeNS(null, "number")+"']");
                          hasConfig = (customInfo != null);
                      }
                      if (showCustomizePage == true || hasConfig == false) {
                          Node node = DOMUtil.selectSingleNode(element, "status/customize");
                          DOMUtil.setValueOfNode(node, "true");
                      } else {
                          Node node = DOMUtil.selectSingleNode(element, "status/customize");
                          DOMUtil.setValueOfNode(node, "false");
                      }
                  } else {
                      Node node = DOMUtil.selectSingleNode(element, "status/customize");
                      DOMUtil.setValueOfNode(node, "false");
                  }
  
                  // Create the parameters for the coplet:
                  //   The <status> part is mapped to parameters
                  //   id, number and media are added
                  SourceParameters p = DOMUtil.createParameters(DOMUtil.getFirstNodeFromPath(element, new String[] {"status"}, false), null);
                  p.setSingleParameterValue(PortalConstants.PARAMETER_ID, copletID);
                  p.setSingleParameterValue(PortalConstants.PARAMETER_NUMBER, element.getAttributeNS(null, "number"));
                  p.setSingleParameterValue(PortalConstants.PARAMETER_MEDIA, media);
                  String isPersistent = DOMUtil.getValueOf(copletConf, "configuration/persistent", "false");
                  p.setSingleParameterValue(PortalConstants.PARAMETER_PERSISTENT, isPersistent);
  
                  // the coplet loading is a tricky part:
                  // we create an object array containing all information
                  // for later processing of the coplet
                  // so the processCoplet() method needs no lookup for information
                  // again
                  loadedCoplet[0] = null;
                  loadedCoplet[1] = copletConf;
                  loadedCoplet[2] = p;
                  loadedCoplet[3] = element;
                  loadedCoplet[4] = new Long(System.currentTimeMillis());
                  loadedCoplet[5] = new Long(DOMUtil.getValueOf(copletConf, "configuration/timeout", "-1"));
                  loadedCoplet[7] = statusProfile;
  
                  CopletThread copletThread = new CopletThread();
                  Thread theThread = new Thread(copletThread);
                  loadedCoplet[6] = copletThread;
                  copletThread.init(copletID,
                                    objectModel,
                                    this.getLogger(),
                                    response,
                                    this.getResourceConnector(),
                                    loadedCoplet,
                                    this.manager,
                                    this.resolver);
                  theThread.start();
                  Thread.currentThread().yield();
  
                  if (parallelCoplets == false) {
                      copletThread = (CopletThread)loadedCoplet[6];
                      if (copletThread != null) {
                          long startTime = System.currentTimeMillis() - ((Long)loadedCoplet[4]).longValue();
                          long timeout = ((Long)loadedCoplet[5]).longValue();
                          long waitTime;
                          if (timeout == -1) {
                              waitTime = defaultCopletTimeout;
                          } else {
                              waitTime = timeout - startTime;
                          }
  
                          while (copletThread != null && waitTime > 2) {
                              try {
                                  Thread.sleep(15);
                                  waitTime -= 15;
                              } catch(InterruptedException local) {
                                  // ignore
                              }
                              copletThread = (CopletThread)loadedCoplet[6];
                          }
                          loadedCoplet[6] = null; // mark as loaded
                      }
                  }
  
              }
  
          }
      }
  
      /**
       * Process a coplet which is previously loaded
       */
      private void processCoplet(Object[]    loadedCoplet,
                                 XMLConsumer consumer,
                                 String      notAvailableMessage,
                                 long        defaultCopletTimeout)
      throws ProcessingException,
             SAXException,
             IOException,
             javax.xml.transform.TransformerException  {
          // calling method is synced
  
          Element copletConf = (Element)loadedCoplet[1];
          Element element    = (Element)loadedCoplet[3];
  
          String copletID = element.getAttributeNS(null, "id");
          if (copletConf != null) {
              AttributesImpl attr = new AttributesImpl();
              attr.addAttribute("", "id", "id", "CDATA", copletID);
              attr.addAttribute("", "number", "number", "CDATA", element.getAttributeNS(null, "number"));
              attr.addAttribute("", "position", "position", "CDATA", element.getAttributeNS(null, "position"));
              consumer.startElement("", "coplet", "coplet", attr);
              attr.clear();
  
              // now include all children of the coplet element except status
              NodeList children = copletConf.getChildNodes();
              if (children != null && children.getLength() > 0) {
                  int l = children.getLength();
                  for(int i = 0; i < l; i++) {
                      if (children.item(i).getNodeName().equals("status") == false
                          && children.item(i).getNodeType() == Node.ELEMENT_NODE) {
                          IncludeXMLConsumer.includeNode(children.item(i), consumer, consumer);
                      }
                  }
              }
  
              // now the status parameter
              SourceParameters p = DOMUtil.createParameters(DOMUtil.getFirstNodeFromPath(element, new String[] {"status"}, false), null);
              consumer.startElement("", "status", "status", attr);
              children = DOMUtil.selectNodeList(element, "status/*");
              if (children != null && children.getLength() > 0) {
                  int l = children.getLength();
                  for(int i = 0; i < l; i++) {
                      if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
                          IncludeXMLConsumer.includeNode(children.item(i), consumer, consumer);
                      }
                  }
              }
              consumer.endElement("", "status", "status");
  
              // now the content:
              consumer.startElement("", "content", "content", attr);
  
              CopletThread thread = (CopletThread)loadedCoplet[6];
              if (thread != null) {
                  long startTime = System.currentTimeMillis() - ((Long)loadedCoplet[4]).longValue();
                  long timeout = ((Long)loadedCoplet[5]).longValue();
                  long waitTime;
                  if (timeout == -1) {
                      waitTime = defaultCopletTimeout;
                  } else {
                      waitTime = timeout - startTime;
                  }
  
                  while (thread != null && waitTime > 2) {
                      try {
                          Thread.sleep(15);
                          waitTime -= 15;
                      } catch(InterruptedException local) {
                          // ignore
                      }
                      thread = (CopletThread)loadedCoplet[6];
                  }
              }
              byte[] content = (byte[])loadedCoplet[0];
              if (content != null) {
                  if (content.length > 0) {
                      XMLDeserializer interpreter = null;
                      try {
                          interpreter = (XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
                          interpreter.setConsumer(new IncludeXMLConsumer(consumer, consumer));
                          interpreter.deserialize(content);
                      } catch (ComponentException e) {
                          throw new ProcessingException("Component for XMLDeserializer not found." + e, e);
                      } finally {
                          if (interpreter != null) this.manager.release((Component)interpreter);
                      }
                  }
              } else {
                  notAvailableMessage = DOMUtil.getValueOf(copletConf,
                           "configuration/messages/coplet_not_available", notAvailableMessage);
                  consumer.characters(notAvailableMessage.toCharArray(), 0, notAvailableMessage.length());
              }
              consumer.endElement("", "content", "content");
              consumer.endElement("", "coplet", "coplet");
  
          }
      }
  
      /**
       * Get the coplet with the id
       */
      private Element getCopletConfiguration(String copletID,
                                             Map    defaultCoplets,
                                             Map    mediaCoplets) {
          // calling method is synced
          String media = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE);
          Map    coplets = (Map)mediaCoplets.get(media);
          Element coplet = null;
          if (coplets != null) coplet = (Element)coplets.get(copletID);
          if (coplet == null)  coplet = (Element)defaultCoplets.get(copletID);
          return coplet;
      }
  
      /**
       * Get the coplet Element
       */
      private Element getCopletElement(DocumentFragment profile,
                                       String copletID,
                                       String copletNr,
                                       Node[] miscNodes)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          Element node = null;
  
          // first test content, then header and then footer
          int colindex = 8;
          while (node == null && colindex < 13) {
              if (miscNodes[colindex] != null) {
                  node = (Element)DOMUtil.getSingleNode(miscNodes[colindex],
                          "coplets/coplet[@id='"+copletID+"' and @number='"+copletNr+"']");
                  colindex++;
              } else {
                  colindex = 13;
              }
          }
          if (node == null && miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] != null) {
              node = (Element)DOMUtil.getSingleNode(miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE],
                        "coplet[@id='"+copletID+"' and @number='"+copletNr+"']");
          }
          if (node == null && miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] != null) {
              node = (Element)DOMUtil.getSingleNode(miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE],
                        "coplet[@id='"+copletID+"' and @number='"+copletNr+"']");
          }
          return node;
      }
  
      /**
       * Modify the coplet.
       * This method returns true if the type informations must be recalculated
       */
      private boolean modifyCoplet(String requestString,
                                   SessionContext context,
                                   Map             theProfile,
                                   DocumentFragment profile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // synchronized as the caller is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN modifyCoplet request=" + requestString);
          }
          boolean result = false;
  
  
          int pos, pos2;
          pos  = requestString.indexOf('_');
          pos2 = requestString.indexOf('_', pos+1);
          if (pos != -1 && pos2 != -1) {
              Element coplet = null;
  
              String copletID;
              String copletNr;
              String argument = null;
  
              copletID = requestString.substring(pos+1,pos2);
              copletNr = requestString.substring(pos2+1);
              pos = copletNr.indexOf('_');
              if (pos != -1) {
                  argument = copletNr.substring(pos+1);
                  copletNr = copletNr.substring(0, pos);
              }
  
              // create a new coplet: in the given column, header or footer
              if (requestString.startsWith(PortalManager.REQ_CMD_NEW) == true
                  && this.isCopletAvailable(context, copletID,
                                   (Map)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
                                   (Map)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS))) {
                  Node[] miscNodes = (Node[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER);
                  // determine the coplet number
                  Node   lastCoplet = miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE];
                  String lastNumber = null;
                  if (lastCoplet != null) {
                      lastNumber = ((Element)lastCoplet).getAttributeNS(null, "number");
                      if (lastNumber != null) {
                          int value = new Integer(lastNumber).intValue();
                          value++;
                          lastNumber = ""+value;
                      }
                  }
                  if (lastNumber == null) lastNumber = "0";
  
                  Node copletsNode;
                  if (copletNr.equals("header") == true) {
                      copletsNode = miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE];
                      if (copletsNode == null) {
                          copletsNode = DOMUtil.selectSingleNode(profile, "profile/portal-profile/content/header");
                          miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] = copletsNode;
                      } else { // remove old coplet
                          Node oldCoplet = DOMUtil.getFirstNodeFromPath(copletsNode, new String[] {"coplet"}, false);
                          if (oldCoplet != null) copletsNode.removeChild(oldCoplet);
                      }
                  } else if (copletNr.equals("footer") == true) {
                      copletsNode = miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE];
                      if (copletsNode == null) {
                          copletsNode = DOMUtil.selectSingleNode(profile, "profile/portal-profile/content/footer");
                          miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] = copletsNode;
                      } else { // remove old coplet
                          Node oldCoplet = DOMUtil.getFirstNodeFromPath(copletsNode, new String[] {"coplet"}, false);
                          if (oldCoplet != null) copletsNode.removeChild(oldCoplet);
                      }
                  } else {
                      Node columnNode = miscNodes[7+new Integer(copletNr).intValue()];
                      copletsNode = DOMUtil.getFirstNodeFromPath(columnNode, new String[] {"coplets"}, false);
                  }
                  Element copletNode;
                  Document doc = copletsNode.getOwnerDocument();
                  copletNode = doc.createElementNS(null, "coplet");
                  copletsNode.appendChild(copletNode);
                  copletNode.setAttributeNS(null, "id", copletID);
                  copletNode.setAttributeNS(null, "number", lastNumber);
                  // set position
                  NodeList childs = DOMUtil.getNodeListFromPath(copletsNode, new String[] {"coplet"});
                  int childsCount = (childs == null ? 0 : childs.getLength());
                  copletNode.setAttributeNS(null, "position", ""+(childsCount));
                  miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = copletNode;
  
                  // copy status
                  Element configElement = this.getCopletConfiguration(copletID,
                                                        (Map)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
                                                        (Map)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
                  Element configStatus = (Element)DOMUtil.getFirstNodeFromPath(configElement, new String[] {"status"}, false);
                  copletNode.appendChild(configStatus.cloneNode(true));
  
                  // clear type information for each status
                  Element status = (Element)copletNode.getElementsByTagName("status").item(0);
                  NodeList parameters = status.getChildNodes();
                  Node    current;
                  Element statusNode;
                  if (parameters != null) {
                      for(int i = 0; i < parameters.getLength(); i++) {
                          current = parameters.item(i);
                          if (current.getNodeType() == Node.ELEMENT_NODE) {
                              statusNode = (Element)current;
                              if (statusNode.hasAttributeNS(null, "formpath") == true)
                                  statusNode.removeAttributeNS(null, "formpath");
                              if (statusNode.hasAttributeNS(null, "formtype") == true)
                                  statusNode.removeAttributeNS(null, "formtype");
                              if (statusNode.hasAttributeNS(null, "formdescription") == true)
                                  statusNode.removeAttributeNS(null, "formdescription");
                          }
                      }
                  }
                  result = true;
  
             } else {
                  coplet = this.getCopletElement(profile,
                                     copletID,
                                      copletNr,
                                      (Node[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER));
                  if (coplet != null) {
                      if (requestString.startsWith(PortalManager.REQ_CMD_CLOSE) == true ||
                          requestString.startsWith(PortalManager.REQ_CMD_HIDE) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/visible");
                           DOMUtil.setValueOfNode(node, "false");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_OPEN) == true ||
                          requestString.startsWith(PortalManager.REQ_CMD_SHOW) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/visible");
                           DOMUtil.setValueOfNode(node, "true");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_MINIMIZE) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/size");
                           DOMUtil.setValueOfNode(node, "min");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_MAXIMIZE) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/size");
                           DOMUtil.setValueOfNode(node, "max");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_CUSTOMIZE) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/customize");
                           DOMUtil.setValueOfNode(node, "true");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_UPDATE) == true) {
                           Node node = DOMUtil.selectSingleNode(coplet, "status/customize");
                           DOMUtil.setValueOfNode(node, "false");
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_DELETE) == true) {
                          // delete the status of the coplet
                          Node statusNode = DOMUtil.getSingleNode(profile,
                               "profile/status-profile/customization/coplet[@id='"+copletID+"' and @number='"+copletNr+"']");
                          if (statusNode != null) {
                              statusNode.getParentNode().removeChild(statusNode);
                              Element configElement = this.getCopletConfiguration(copletID,
                                                        (Map)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
                                                        (Map)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
                              boolean isPersistent = DOMUtil.getValueAsBooleanOf(configElement, "configuration/persistent", false);
                              if (isPersistent == true) {
                                  // mark the status profile to be saved
                                  theProfile.put(PortalConstants.PROFILE_SAVE_STATUS_FLAG, "true");
                              }
                          }
                          String posAttr = coplet.getAttributeNS(null, "position");
                          NodeList followUps = DOMUtil.selectNodeList(coplet.getParentNode(), "coplet[@position > '"+posAttr+"']");
                          coplet.getParentNode().removeChild(coplet);
                          coplet = null;
                          if (followUps != null) {
                              int value;
                              for(int i = 0; i < followUps.getLength(); i++) {
                                  value = new Integer(((Element)followUps.item(i)).getAttributeNS(null, "position")).intValue();
                                  value -= 1;
                                  ((Element)followUps.item(i)).setAttributeNS(null, "position", "" + value);
                             }
                          }
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_MOVE) == true) {
                          if (argument != null) {
                              Element  copletsElement = (Element)DOMUtil.getSingleNode(profile,
                                    "profile/portal-profile/content/column[@position='"+argument+"']/coplets");
                              if (copletsElement != null) {
                                  if (coplet.getParentNode().equals(copletsElement) == false) {
                                       String posAttr = coplet.getAttributeNS(null, "position");
                                       NodeList followUps = DOMUtil.selectNodeList(coplet.getParentNode(), "coplet[@position > '"+posAttr+"']");
                                       coplet.getParentNode().removeChild(coplet);
                                       // set position attribute
                                       NodeList childs = DOMUtil.getNodeListFromPath(copletsElement, new String[] {"coplet"});
                                       int childsCount = (childs == null ? 0 : childs.getLength());
                                       coplet.setAttributeNS(null, "position", "" + (childsCount + 1));
                                       copletsElement.appendChild(coplet);
                                       if (followUps != null) {
                                           int value;
                                           for(int i = 0; i < followUps.getLength(); i++) {
                                               value = new Integer(((Element)followUps.item(i)).getAttributeNS(null, "position")).intValue();
                                               value -= 1;
                                               ((Element)followUps.item(i)).setAttributeNS(null, "position", "" + value);
                                           }
                                       }
                                   }
                              }
                          }
                      } else if (requestString.startsWith(PortalManager.REQ_CMD_MOVEROW) == true) {
                          if (argument != null) {
                              Element newCoplet = (Element)DOMUtil.getSingleNode(coplet.getParentNode(),
                                                   "coplet[@position='"+argument+"']");
                              if (newCoplet != null) {
                                  String position = coplet.getAttributeNS(null, "position");
                                  coplet.removeAttributeNS(null, "position");
                                  coplet.setAttributeNS(null, "position", argument);
                                  newCoplet.removeAttributeNS(null, "position");
                                  newCoplet.setAttributeNS(null, "position", position);
                              }
                          }
                      }
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END modifyCoplet calculate="+result);
          }
          return result;
      }
  
      /**
       * Check if the coplet is available for the current logged in user
       * If the user is not logged in, this returns false.
       * First the default coplets are searched. If none is found then
       * the coplets for each media are searched.
       */
      private boolean isCopletAvailable(SessionContext context,
                                      String copletID,
                                      Map defaultCoplets,
                                      Map mediaCoplets)
      throws ProcessingException {
          // no sync required
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN isCopletAvailable coplet="+copletID);
          }
          boolean result = false;
  
          if (context != null) {
              result = defaultCoplets.containsKey(copletID);
              if (result == false) {
                  Iterator iter = mediaCoplets.values().iterator();
                  while (result == false && iter.hasNext() == true) {
                      result = ((Map)iter.next()).containsKey(copletID);
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END isCopletAvailable result=" + result);
          }
          return result;
      }
  
      /**
       * Check the authentication for the coplet. If it is not available do a redirect
       */
      public boolean checkAuthentication(Redirector redirector, String copletID)
      throws SAXException, IOException, ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN checkAuthentication coplet="+copletID);
          }
          boolean result = false;
          SessionContext context = this.getContext(false);
          if (context != null
              && (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE) != null) {
  
              try {
                  this.getSessionManager().startReadingTransaction(context);
                  Map theProfile = this.retrieveProfile(this.getProfileID(PortalManager.BUILDTYPE_VALUE_ID,
                       (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE),
                       (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ID), false));
  
                  if (theProfile != null) {
                      if (copletID == null || copletID.trim().length() == 0) {
                          result = true;
                      } else {
                          result = this.isCopletAvailable(context,
                                        copletID,
                                        (Map)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
                                        (Map)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
                      }
                  }
              } finally {
                  this.getSessionManager().stopReadingTransaction(context);
              } // end synced
          }
  
  
          if (result == false) {
              Map config = this.getConfiguration();
              if (config != null) {
                  String redirectURI = (String)config.get(PortalConstants.CONF_AUTH_REDIRECT);
                  if (redirectURI == null) {
                      redirectURI = (String)config.get(PortalConstants.CONF_PORTAL_URI);
                  }
                  if (redirectURI != null) {
                      redirector.globalRedirect( false, redirectURI );
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END checkAuthentication result=" + result);
          }
          return result;
      }
  
      /**
       * Get the configuration. This configuration is an authentication application configuration
       * for the current application with the name "portal".
       * The first time this configuration is build it is stored in the session
       * so later requests get the cached result.
       */
      private Map getConfiguration()
      throws SAXException, IOException, ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getConfiguration");
          }
          Map result = null;
          String appName = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME);
          String handlerName = (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME);
          Session session = this.getSessionManager().getSession(false);
          if (session != null && appName != null && handlerName != null) {
  
              synchronized (session) {
                  result = (Map)session.getAttribute(PortalConstants.ATTRIBUTE_CONFIGURATION + handlerName + ':' + appName);
                  if (result == null) {
  
                      try {
                          Configuration config;
  
                          Configuration conf = this.getAuthenticationManager().getModuleConfiguration(PortalConstants.AUTHENTICATION_MODULE_NAME);
                          if (conf == null) {
                              throw new ProcessingException("portal: Configuration for application '" + appName + "' not found.");
                          }
                          result = new HashMap(10, 2);
                          // auth-redirect (optional)
                          config = conf.getChild("auth-redirect", false);
                          if (config != null) {
                              result.put(PortalConstants.CONF_AUTH_REDIRECT, config.getValue());
                          }
  
                          // portal-uri (required)
                          config = conf.getChild("portal-uri", false);
                          if (config == null) {
                              throw new ProcessingException("portal: portal-uri required for application '"+appName+"'");
                          }
                          result.put(PortalConstants.CONF_PORTAL_URI, config.getValue());
  
                          // profile-cache (optional)
                          config = conf.getChild("profile-cache", false);
                          if (config != null && config.getValueAsBoolean() == true) {
                              result.put(PortalConstants.CONF_PROFILE_CACHE, appName);
                          }
  
                          // parallel coplets
                          config = conf.getChild("process-coplets-parallel", false);
                          if (config != null) {
                              result.put(PortalConstants.CONF_PARALLEL_COPLETS, new Boolean(config.getValueAsBoolean(false)));
                          } else {
                              result.put(PortalConstants.CONF_PARALLEL_COPLETS, new Boolean(false));
                          }
  
                          // timeout
                          config = conf.getChild("default-coplet-timeout", false);
                          if (config != null) {
                              result.put(PortalConstants.CONF_COPLET_TIMEOUT, new Long(config.getValueAsLong(600000)));
                          } else {
                              result.put(PortalConstants.CONF_COPLET_TIMEOUT, new Long(600000));
                          }
  
                          // and now the profile
                          config = conf.getChild("profile", false);
                          if (config == null) throw new ProcessingException("portal: profile configuration required for application '" + appName + "'");
                          Configuration child;
  
                          // build resource (optional)
                          child = config.getChild("buildprofile", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_BUILD_RESOURCE, new Resource(this.resolver,
                                                                                     child.getAttribute("uri")));
                          }
  
                          // base resource, type is optional
                          child = config.getChild("layout-base", false);
                          if (child == null) {
                              throw new ProcessingException("portal: layout-base required for application '" + appName + "'");
                          }
                          result.put(PortalConstants.CONF_LAYOUTBASE_RESOURCE, new Resource(this.resolver,
                                                                                      child.getAttribute("uri")));
                          child = config.getChild("coplet-base", false);
                          if (child == null) {
                              throw new ProcessingException("portal: coplet-base required for application '" + appName + "'");
                          }
                          result.put(PortalConstants.CONF_COPLETBASE_RESOURCE, new Resource(this.resolver,
                                                                                      child.getAttribute("uri")));
                          child = config.getChild("type-base", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_TYPEBASE_RESOURCE, new Resource(this.resolver,
                                                                                        child.getAttribute("uri")));
                          }
  
                          // coplet base save (is optional)
                          child = config.getChild("coplet-base-save", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_COPLETBASE_SAVE_RESOURCE, new Resource(this.resolver,
                                                                                               child.getAttribute("uri")));
                          }
  
                          // global delta (load required)
                          child = config.getChild("global-delta-load", false);
                          if (child == null) {
                              throw new ProcessingException("portal: global-delta-load required for application '" + appName + "'");
                          }
                          result.put(PortalConstants.CONF_GLOBALDELTA_LOADRESOURCE, new Resource(this.resolver,
                                                                                           child.getAttribute("uri")));
                          child = config.getChild("global-delta-save", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_GLOBALDELTA_SAVERESOURCE, new Resource(this.resolver,
                                                                                               child.getAttribute("uri")));
                          }
                          child = config.getChild("global-type-delta", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_GLOBALDELTA_TYPERESOURCE, new Resource(this.resolver,
                                                                                               child.getAttribute("uri")));
                          }
  
                          // role delta (optional)
                          child = config.getChild("role-delta-load", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_ROLEDELTA_LOADRESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
                          child = config.getChild("role-delta-save", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_ROLEDELTA_SAVERESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
                          child = config.getChild("role-type-delta", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_ROLEDELTA_TYPERESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
  
                          // User delta
                          child = config.getChild("user-delta-load", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_USERDELTA_LOADRESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
                          child = config.getChild("user-delta-save", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_USERDELTA_SAVERESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
                          child = config.getChild("user-type-delta", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_USERDELTA_TYPERESOURCE, new Resource(this.resolver,
                                                                                             child.getAttribute("uri")));
                          }
  
                          // Personal information
                          child = config.getChild("user-status-load", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_STATUS_LOADRESOURCE, new Resource(this.resolver,
                                                                                          child.getAttribute("uri")));
                          }
                          child = config.getChild("user-status-save", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_STATUS_SAVERESOURCE, new Resource(this.resolver,
                                                                                          child.getAttribute("uri")));
                          }
  
                          // Admin Type profil
                          child = config.getChild("admin-type-base", false);
                          if (child != null) {
                              result.put(PortalConstants.CONF_ADMIN_TYPE_BASE, new Resource(this.resolver,
                                                                                      child.getAttribute("uri")));
                          }
  
                          // store the config in the session
                          session.setAttribute(PortalConstants.ATTRIBUTE_CONFIGURATION + handlerName + ':' + appName, result);
                      } catch (ConfigurationException conf) {
                          throw new ProcessingException("ConfigurationException: " + conf, conf);
                      }
                  }
              }
  
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getConfiguration conf="+result);
          }
          return result;
      }
  
      /**
       * Build the profile for the required level if not already done
       */
      private void createProfile(SessionContext context,
                                String type,
                                String role,
                                String id,
                                boolean adminProfile)
      throws SAXException, IOException, ProcessingException {
          // no sync required
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN createProfile context="+context+
                                     ", type="+type+
                                     ", role="+role+
                                     ", id="+id);
          }
  
          SourceParameters pars = this.getAuthenticationManager().createParameters(null);
          pars.setSingleParameterValue("type", type);
          pars.setSingleParameterValue("admin", (adminProfile == true ? "true" : "false"));
  
          if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == false ||
              role != null) {
              pars.setSingleParameterValue("ID", id);
              pars.setSingleParameterValue("role", role);
          } else {
              id = pars.getParameter("ID", null);
              role = pars.getParameter("role", null);
          }
  
          Map map = this.getConfiguration();
          if (map == null) {
              throw new ProcessingException("portal Configuration not found.");
          }
  
          // is the configuration build by using a own resource?
          Resource resource = (Resource)map.get(PortalConstants.CONF_BUILD_RESOURCE);
          if (resource != null) {
              if (this.getLogger().isInfoEnabled() == true) {
                  this.getLogger().info("Building portal profile: " + resource.getResourceIdentifier());
              }
              this.getResourceConnector().loadXML(resource.getResourceType(),null,
                                         resource.getResourceIdentifier(),pars);
          } else {
              this.buildProfile(type, role, id, adminProfile);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END createProfile");
          }
  
      }
  
      /**
       * Get the base profile for the current application.
       * The base profile consists of the layout and the coplet profile
       * and optional the type profile
       */
      private DocumentFragment buildBaseProfile(Map config, boolean adminProfile)
      throws ProcessingException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildBaseProfile config="+config+", adminProfile="+adminProfile);
          }
          DocumentFragment copletsFragment;
          DocumentFragment layoutFragment;
          DocumentFragment typeFragment;
          DocumentFragment profile;
          Document         profileDoc;
          Element          profileRoot;
          Resource         res;
  
          SourceParameters pars = new SourceParameters();
          pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
          pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
          pars.setSingleParameterValue("profile", "coplet-base");
  
          // First load the base profiles: copletProfile + layoutProfile
          res = (Resource)config.get(PortalConstants.CONF_COPLETBASE_RESOURCE);
          if (res == null) {
              throw new ProcessingException("No configuration for portal-coplet base profile found.");
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("Loading coplet base profile");
          }
          copletsFragment = this.loadXML(res.getResourceType(), null,
                                         res.getResourceIdentifier(), pars,
                                         "Error loading coplet base profile." + res.getResourceIdentifier());
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("coplet base profile loaded");
          }
          res = (Resource)config.get(PortalConstants.CONF_LAYOUTBASE_RESOURCE);
          if (res == null) {
              throw new ProcessingException("No configuration for portal-layout base profile found.");
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("loading layout base profile");
          }
          pars.setSingleParameterValue("profile", "layout-base");
          layoutFragment = this.loadXML(res.getResourceType(), null,
                                        res.getResourceIdentifier(), pars,
                                        "Error loading layout base profile " + res.getResourceIdentifier());
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("layout base profile loaded");
          }
          // now create the base profile containing the above profiles
          profileDoc = DOMUtil.createDocument();
          profile = profileDoc.createDocumentFragment();
          profileRoot = profileDoc.createElementNS(null, "profile");
          profile.appendChild(profileRoot);
          profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(layoutFragment,
                                                                    "layout-profile"), true));
          profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(copletsFragment,
                                                                    "coplets-profile"), true));
  
          // if avalailable append the type profile
          if (adminProfile == true) {
              res = (Resource)config.get(PortalConstants.CONF_ADMIN_TYPE_BASE);
              pars.setSingleParameterValue("profile", "admin-type-base");
          } else {
              res = (Resource)config.get(PortalConstants.CONF_TYPEBASE_RESOURCE);
              pars.setSingleParameterValue("profile", "type-base");
          }
          if (res != null) {
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading type base profile");
              }
              typeFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading type base profile " +res.getResourceIdentifier());
              profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(typeFragment,
                                "type-profile"), true));
  
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("type base profile loaded");
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildBaseProfile profile=" + profile);
          }
          return profile;
      }
  
      /**
       * Build the global profile.
       */
      private void buildGlobalProfile(Element profileRoot,
                                      Map config,
                                      boolean adminProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN buildGlobalProfile profileRoot="+profileRoot+", config="+config+", adminProfile="+adminProfile);
          }
          DocumentFragment globalFragment;
          Resource res = (Resource)config.get(PortalConstants.CONF_GLOBALDELTA_LOADRESOURCE);
          if (res == null) {
              throw new ProcessingException("No configuration for portal-role delta profile found.");
          }
          SourceParameters pars = new SourceParameters();
          pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
          pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
          pars.setSingleParameterValue("profile", "global-delta");
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("loading global profile");
          }
          globalFragment = this.loadXML(res.getResourceType(), null,
                                        res.getResourceIdentifier(), pars,
                                        "Error loading global profile " + res.getResourceIdentifier());
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("global profile loaded");
          }
          this.importProfileDelta(profileRoot, globalFragment, "global-delta", "layout-delta");
          this.importProfileDelta(profileRoot, globalFragment, "global-delta", "coplets-delta");
          this.addProfilePart(profileRoot, globalFragment, "global-delta", "portal-profile");
          this.addProfilePart(profileRoot, globalFragment, "global-delta", "personal-profile");
  
          // types
          res = (Resource)config.get(PortalConstants.CONF_GLOBALDELTA_TYPERESOURCE);
          if (adminProfile == false && res != null) {
              pars.setSingleParameterValue("profile", "global-type-delta");
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading global type profile");
              }
              globalFragment = this.loadXML(res.getResourceType(), null,
                                            res.getResourceIdentifier(), pars,
                                            "Error loading global type profile " + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("global type profile loaded");
              }
              this.addProfilePart(profileRoot, globalFragment, "global-delta", "type-profile");
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END buildGlobalProfile");
          }
      }
  
      /**
       * Build the role profile
       */
      private void buildRoleProfile(Element profileRoot,
                                              Map config,
                                              String role,
                                              boolean adminProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
  
          DocumentFragment roleFragment;
          SourceParameters pars;
          pars = new SourceParameters();
          pars.setSingleParameterValue("role", role);
          pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
          pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
          pars.setSingleParameterValue("profile", "role-delta");
  
          Resource res = (Resource)config.get(PortalConstants.CONF_ROLEDELTA_LOADRESOURCE);
          if (res != null) {
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading role profile");
              }
              roleFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading role profile "  + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("role profile loaded");
              }
              this.importProfileDelta(profileRoot, roleFragment, "role-delta", "layout-delta");
              this.importProfileDelta(profileRoot, roleFragment, "role-delta", "coplets-delta");
              this.addProfilePart(profileRoot, roleFragment, "role-delta", "portal-profile");
              this.importProfileDelta(profileRoot, roleFragment, "role-delta", "personal-delta");
          }
  
          // types
          res = (Resource)config.get(PortalConstants.CONF_ROLEDELTA_TYPERESOURCE);
          if (adminProfile == false && res != null) {
              pars.setSingleParameterValue("profile", "role-type-delta");
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading role type profile");
              }
              roleFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading role type profile " + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("role type profile loaded");
              }
              this.addProfilePart(profileRoot, roleFragment, "role-delta", "type-profile");
          }
      }
  
      /**
       * Build the user profile
       */
      private void buildUserProfile(Element profileRoot,
                                  Map config,
                                  String role,
                                  String id,
                                  boolean adminProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          DocumentFragment userFragment;
          SourceParameters pars;
          pars = new SourceParameters();
          pars.setSingleParameterValue("ID", id);
          pars.setSingleParameterValue("role", role);
          pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
          pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
          pars.setSingleParameterValue("profile", "user-delta");
  
          Resource res = (Resource)config.get(PortalConstants.CONF_USERDELTA_LOADRESOURCE);
          if (res != null) {
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading user profile");
              }
              userFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading user profile " + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("user profile loaded");
              }
              this.importProfileDelta(profileRoot, userFragment, "user-delta", "layout-delta");
              this.importProfileDelta(profileRoot, userFragment, "user-delta", "coplets-delta");
              this.addProfilePart(profileRoot, userFragment, "user-delta", "portal-profile");
              this.importProfileDelta(profileRoot, userFragment, "user-delta", "personal-delta");
          }
  
          // types
          res = (Resource)config.get(PortalConstants.CONF_USERDELTA_TYPERESOURCE);
          if (adminProfile == false && res != null) {
              pars.setSingleParameterValue("profile", "user-type-delta");
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading user type profile");
              }
              userFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading user type profile " + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("user type profile loaded");
              }
              this.addProfilePart(profileRoot, userFragment, "user-delta", "type-profile");
          }
      }
  
      /**
       * Load the user status profile (if available)
       */
      private void buildUserStatusProfile(Element profileRoot,
                                          Map config,
                                          String role,
                                          String id,
                                          boolean adminProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          Resource res = (Resource)config.get(PortalConstants.CONF_STATUS_LOADRESOURCE);
  
          // remove the old status profile
          Node statusProfile = DOMUtil.getFirstNodeFromPath(profileRoot, new String[] {"status-profile"}, false);
          if (statusProfile != null) {
              profileRoot.removeChild(statusProfile);
          }
  
          if (res != null) {
              DocumentFragment userFragment;
              SourceParameters pars;
              pars = new SourceParameters();
              pars.setSingleParameterValue("ID", id);
              pars.setSingleParameterValue("role", role);
              pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
              pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
              pars.setSingleParameterValue("profile", "user-status");
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("loading user status profile");
              }
              userFragment = this.loadXML(res.getResourceType(), null,
                                          res.getResourceIdentifier(), pars,
                                          "Error loading user status profile " + res.getResourceIdentifier());
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("user status profile loaded");
              }
              this.addProfilePart(profileRoot, userFragment, null, "status-profile");
          }
          // test if the status-profile node is available
          // if not create one
          if (DOMUtil.getFirstNodeFromPath(profileRoot, new String[] {"status-profile"}, false) == null) {
              statusProfile = profileRoot.getOwnerDocument().createElementNS(null, "status-profile");
              profileRoot.appendChild(statusProfile);
          }
      }
  
      /**
       * Save the user status profile (if available)
       */
      private void saveUserStatusProfile(Map profile,
                                         Map config,
                                         String role,
                                         String id,
                                         boolean adminProfile)
      throws ProcessingException, SAXException, javax.xml.transform.TransformerException {
          // calling method is synced
          Resource res = (Resource)config.get(PortalConstants.CONF_STATUS_SAVERESOURCE);
          Element statusProfile = (Element)DOMUtil.getFirstNodeFromPath((DocumentFragment)profile.get(PortalConstants.PROFILE_PROFILE),
                           new String[] {"profile","status-profile"}, false);
          if (res != null && statusProfile != null) {
              DocumentFragment userFragment = statusProfile.getOwnerDocument().createDocumentFragment();
              Element oldParent = (Element)statusProfile.getParentNode();
              Element saveStatus = (Element)statusProfile.cloneNode(true);
              userFragment.appendChild(saveStatus);
              // now filter all not persistent coplets!
              NodeList list = DOMUtil.getNodeListFromPath(saveStatus, new String[] {"customization","coplet"});
              String copletID;
              String copletNumber;
              Element coplet;
              Element copletConfig;
              Map copletConfigs = (Map)profile.get(PortalConstants.PROFILE_DEFAULT_COPLETS);
              Map mediaCopletConfigs = (Map)profile.get(PortalConstants.PROFILE_MEDIA_COPLETS);
              boolean isPersistent;
              for(int i = 0; i < list.getLength(); i++) {
                  coplet = (Element)list.item(i);
                  copletID = coplet.getAttributeNS(null, "id");
                  copletNumber = coplet.getAttributeNS(null, "number");
                  copletConfig = this.getCopletConfiguration(copletID, copletConfigs, mediaCopletConfigs);
                  isPersistent = DOMUtil.getValueAsBooleanOf(copletConfig, "configuration/persistent", false);
                  if (isPersistent == false) {
                      coplet.getParentNode().removeChild(coplet);
                  }
              }
  
              try {
  
                  SourceParameters pars;
                  pars = new SourceParameters();
                  pars.setSingleParameterValue("ID", id);
                  pars.setSingleParameterValue("role", role);
                  pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
                  pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
                  pars.setSingleParameterValue("profile", "user-status");
  
                  this.getResourceConnector().saveXML(res.getResourceType(), null,
                                res.getResourceIdentifier(), pars,
                                userFragment);
              } finally {
                  userFragment.removeChild(saveStatus);
              }
          }
      }
  
      /**
       * Change the profile according to the request parameter
       */
      private void changeProfile()
      throws ProcessingException, SAXException, IOException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN changeProfile");
          }
          SessionContext context = this.getContext(false);
  
          if (context != null) {
              try {
                  Map theProfile = null;
                  String profileID = this.request.getParameter(PortalManager.REQ_PARAMETER_PROFILE);
                  if (profileID != null) {
                      theProfile = this.retrieveProfile(profileID);
                  }
  
                  if (theProfile != null) {
                      synchronized (context) {
                          DocumentFragment profile = (DocumentFragment)theProfile.get(PortalConstants.PROFILE_PROFILE);
                          Node[]           miscNodes = (Node[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER);
                          Element          columns = (Element)miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE];
                          Enumeration      enum = this.request.getParameterNames();
                          String           current;
                          boolean          saveProfile = false;
  
                          // first iteration: all changing commands
                          while (enum.hasMoreElements() == true) {
                              current = (String)enum.nextElement();
                              if (current.startsWith(PortalManager.REQ_PARAMETER_CONF) == true) {
                                  int pos1, pos2;
                                  pos1 = current.indexOf('.');
                                  pos2 = current.indexOf('.', pos1+1);
                                  if (pos1 != -1 && pos2 != -1) {
                                      int pathIndex = new Integer(current.substring(pos1+1, pos2)).intValue();
                                      int place= new Integer(current.substring(pos2+1)).intValue();
                                      List typePaths = (List)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS);
                                      String path = (String)typePaths.get(pathIndex);
                                      if (path != null) {
                                          NodeList nodes = DOMUtil.selectNodeList(profile, path);
                                          if (nodes != null) {
                                              Node node = nodes.item(place);
                                              if (node != null) {
                                                  if (node.equals(columns) == false) {
                                                          DOMUtil.setValueOfNode(node, request.getParameter(current));
                                                  }
                                              }
                                          }
  
                                      }
                                  }
                              }
                          }
  
                          // second: all new
                          boolean     calculate = false;
                          enum = this.request.getParameterNames();
                          while (enum.hasMoreElements() == true) {
  
                              current = (String)enum.nextElement();
                              if (current.startsWith(PortalManager.REQ_PARAMETER_CONF) == true) {
                                  int pos1, pos2;
                                  pos1 = current.indexOf('.');
                                  pos2 = current.indexOf('.', pos1+1);
                                  if (pos1 != -1 && pos2 != -1) {
                                      int pathIndex = new Integer(current.substring(pos1+1, pos2)).intValue();
                                      int place= new Integer(current.substring(pos2+1)).intValue();
                                      List typePaths = (List)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS);
                                      String path = (String)typePaths.get(pathIndex);
                                      if (path != null) {
                                          NodeList nodes = DOMUtil.selectNodeList(profile, path);
                                          if (nodes != null) {
                                              Node node = nodes.item(place);
                                              if (node != null) {
                                                  if (node.equals(columns) == true) {
                                                      int columnNumber = new Integer(this.request.getParameter(current)).intValue();
                                                      int oldNumber = new Integer(DOMUtil.getValueOfNode(columns)).intValue();
                                                      if (columnNumber > 0 && columnNumber != oldNumber && columnNumber <= PortalConstants.MAX_COLUMNS) {
                                                          this.changeColumns(profile,
                                                                 oldNumber,
                                                                 columnNumber,
                                                                 miscNodes);
                                                          calculate = true;
                                                          DOMUtil.setValueOfNode(node, request.getParameter(current));
                                                      }
                                                  }
                                              }
                                          }
  
                                      }
                                  }
  
                              } else if (current.equals(PortalManager.REQ_PARAMETER_CMD) == true) {
                                  String[] cmds = request.getParameterValues(current);
                                  if (cmds != null && cmds.length > 0) {
                                      for(int i = 0; i < cmds.length; i++) {
                                          if (cmds[i].equals(PortalManager.REQ_CMD_SAVEPROFILE) == true) {
                                              saveProfile = true;
                                          } else {
                                              if (this.modifyCoplet(cmds[i], context, theProfile, profile) == true) {
                                                  calculate = true;
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                          // set type infos
                          if (calculate == true) {
                              this.setTypeInfo(profile,
                                   (List)theProfile.get(PortalConstants.PROFILE_TYPE_PATHS),
                                   (List)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS));
                          }
  
                          // test if the status profile changed
                          Object statusChanged = theProfile.get(PortalConstants.PROFILE_SAVE_STATUS_FLAG);
                          if (statusChanged != null) {
                              theProfile.remove(PortalConstants.PROFILE_SAVE_STATUS_FLAG);
                              this.saveUserStatusProfile(theProfile,
                                                         this.getConfiguration(),
                                                         this.getRole(profileID),
                                                         this.getID(profileID),
                                                         this.getIsAdminProfile(profileID));
                          }
  
                          // save the profile
                          if (saveProfile == true) {
                              Map      conf = this.getConfiguration();
                              String   role = this.getRole(profileID);
                              String   id   = this.getID(profileID);
                              String   type = this.getType(profileID);
                              Resource saveResource;
                              String   profileType;
  
                              if (type.equals(PortalManager.BUILDTYPE_VALUE_GLOBAL) == true) {
                                  saveResource = (Resource)conf.get(PortalConstants.CONF_GLOBALDELTA_SAVERESOURCE);
                                  profileType = "global-delta";
                              } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ROLE) == true) {
                                  saveResource = (Resource)conf.get(PortalConstants.CONF_ROLEDELTA_SAVERESOURCE);
                                  profileType = "role-delta";
                              } else if (type.equals(PortalManager.BUILDTYPE_VALUE_ID) == true) {
                                  saveResource = (Resource)conf.get(PortalConstants.CONF_USERDELTA_SAVERESOURCE);
                                  profileType = "user-delta";
                              } else {
                                  throw new ProcessingException("portal: No save resource defined for type '"+type+"'.");
                              }
  
                              // patch
                              // search for all "status/customize" nodes and set them
                              // to false
                              NodeList statusNodes = DOMUtil.selectNodeList(profile,
                                      "profile/portal-profile/content/descendant::status/customize");
                              if (statusNodes != null) {
                                  String value;
                                  for(int l=0; l < statusNodes.getLength(); l++) {
                                      value = DOMUtil.getValueOfNode(statusNodes.item(l));
                                      if (value.equals("true") == true) {
                                          DOMUtil.setValueOfNode(statusNodes.item(l), "false");
                                      }
                                  }
                              }
  
                              // build delta
                              DocumentFragment delta;
                              delta = this.buildProfileDelta(type, role, id, this.getIsAdminProfile(profileID));
                              SourceParameters pars = new SourceParameters();
                              pars.setSingleParameterValue("type", profileType);
                              if (id != null) pars.setSingleParameterValue("ID", id);
                              if (role != null) pars.setSingleParameterValue("role", role);
                              pars.setSingleParameterValue("application", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME));
                              pars.setSingleParameterValue("handler", (String)this.request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
                              this.getResourceConnector().saveXML(saveResource.getResourceType(), null,
                                   saveResource.getResourceIdentifier(), pars,
                                   delta);
                              if (delta.getParentNode() != null) delta.getParentNode().removeChild(delta);
                              delta = null;
  
                              // cache the profile
                              // The profile is only cached if it is already in the cache!
                              // Why? During login the profile is build and cached, so it is in the cache.
                              // But: If a user logs in, the profile is cached.
                              // Now the admin logs in, changes the global profile and saves it.
                              // The cache is invalidated, including the user profile.
                              // Now the user changes his profile and saves it.
                              // If it now would be cached, it would be invalid as it would
                              // not reflect the changes by the admin.
                              // But if the old profile is still in the cache, nobody
                              // has changed a profile above.
                              // Note CZ: The above is correct, but for building the delta
                              // the "previous" profile is build and cached ! Thus we can
                              // easily cache the new profile.
  //                            if (this.isProfileCached(profileID, conf) == true) {
                              this.cacheProfile(profileID, theProfile, conf); // cache it
                              // now the hardest part, clean up the cache
                              this.cleanUpCache(type, role, conf);
  //                          }
  
                          }
  
                      } // end synchronized
                  }
              } catch (javax.xml.transform.TransformerException local) {
                  throw new ProcessingException("TransformerException: " + local, local);
              }
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END changeProfile");
          }
      }
  
      /**
       * Change the number of the columns
       */
      private void changeColumns(DocumentFragment profile,
                                 int oldNumber,
                                 int columnNumber,
                                 Node[] miscNodes)
      throws SAXException, javax.xml.transform.TransformerException {
          // calling method is (hopefully) synced
          if (columnNumber < oldNumber) {
              // remove columns and all coplets to the first one
              Node columnNode;
              Node firstColumn = DOMUtil.getSingleNode(profile,
                          "profile/portal-profile/content/column[@position='1']/coplets");
              NodeList firstColumnCoplets = DOMUtil.getNodeListFromPath(firstColumn, new String[] {"coplet"});
              int copletsCount = (firstColumnCoplets == null ? 0 : firstColumnCoplets.getLength());
              for(int i = columnNumber + 1; i <= oldNumber; i++) {
                  columnNode = miscNodes[7+i];
                  if (columnNode != null) {
                      NodeList coplets = DOMUtil.getNodeListFromPath(columnNode, new String[] {"coplets","coplet"});
                      Node coplet;
                      if (coplets != null && coplets.getLength() > 0) {
                          for(int m = 0; m < coplets.getLength(); m++) {
                              coplet = coplets.item(m);
                              coplet.getParentNode().removeChild(coplet);
                              copletsCount++;
                              ((Element)coplet).setAttributeNS(null, "position", "" + copletsCount);
                              firstColumn.appendChild(coplet);
                          }
                      }
                      columnNode.getParentNode().removeChild(columnNode);
                      miscNodes[7+i] = null;
                  }
              }
          } else if (columnNumber <= PortalConstants.MAX_COLUMNS) {
              // add new columns
              Node contentNode = DOMUtil.getFirstNodeFromPath(profile,
                          new String[] {"profile","portal-profile","content"}, false);
              Document doc = contentNode.getOwnerDocument();
              Element newColumn;
              Element el;
              for(int i = oldNumber + 1; i <= columnNumber; i++) {
                  newColumn = doc.createElementNS(null, "column");
                  newColumn.setAttributeNS(null, "position", ""+i);
                  miscNodes[7+i] = newColumn;
                  contentNode.appendChild(newColumn);
                  el = doc.createElementNS(null, "width");
                  el.appendChild(doc.createTextNode("5%"));
                  newColumn.appendChild(el);
                  el = doc.createElementNS(null, "coplets");
                  newColumn.appendChild(el);
              }
          }
      }
  
      /** Empty attributes (for performance)
       */
      private Attributes emptyAttributes = new AttributesImpl();
  
      /**
       * Send SAX events to the next pipeline component.
       * The characters event for the given text is send to the next
       * component in the current pipeline.
       * @param text The string containing the information.
       */
      public void sendTextEvent(XMLConsumer consumer, String text)
      throws SAXException {
          consumer.characters(text.toCharArray(), 0, text.length());
      }
  
      /**
       * Send SAX events to the next pipeline component.
       * The startElement event for the given element is send
       * to the next component in the current pipeline.
       * The element has no namespace and no attributes
       * @param localname The name of the event.
       */
      public void sendStartElementEvent(XMLConsumer consumer, String localname)
      throws SAXException {
          consumer.startElement("", localname, localname, emptyAttributes);
      }
  
      /**
       * Send SAX events to the next pipeline component.
       * The startElement event for the given element is send
       * to the next component in the current pipeline.
       * The element has no namespace.
       * @param localname The name of the event.
       * @param attr The Attributes of the element
       */
      public void sendStartElementEvent(XMLConsumer consumer, String localname, Attributes attr)
      throws SAXException {
          consumer.startElement("", localname, localname, attr);
      }
  
      /**
       * Send SAX events to the next pipeline component.
       * The endElement event for the given element is send
       * to the next component in the current pipeline.
       * The element has no namespace.
       * @param localname The name of the event.
       */
      public void sendEndElementEvent(XMLConsumer consumer, String localname)
      throws SAXException {
          consumer.endElement("", localname, localname);
      }
  
      /**
       * Send SAX events to the next pipeline component.
       * The node is parsed and the events are send to
       * the next component in the pipeline.
       * @param node The tree to be included.
       */
      public void sendEvents(XMLConsumer consumer, Node node)
      throws SAXException {
          IncludeXMLConsumer.includeNode(node, consumer, consumer);
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/components/Coplet.java
  
  Index: Coplet.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.components;
  
  import java.util.Map;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.SAXException;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.cocoon.ProcessingException;
  
  /**
   * The coplet interface
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: Coplet.java,v 1.2 2002/04/19 11:02:58 cziegeler Exp $
  */
  public interface Coplet {
  
      /**
       * 	This will be called before execute() is called. Should really
       *  only be called when the coplet is loaded (caching).
       *
      */
      boolean init(Map                objectModel,
                   SourceParameters   parameters)
      throws ProcessingException;
  
      /**
       * Should stream the content to the consumer.
       * The content must be inside a <content> node!
       * If no content is provided (e.g. if size is min)
       * than no <content> node should be generated!
       */
      void execute(ContentHandler     contentHandler,
                   LexicalHandler     lexicalHandler,
                   Map                objectModel,
                   SourceParameters   parameters)
      throws SAXException, ProcessingException;
  }
  
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/components/CopletThread.java
  
  Index: CopletThread.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.components;
  
  import java.io.ByteArrayOutputStream;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.w3c.dom.Element;
  import org.w3c.dom.NodeList;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentSelector;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.parameters.Parameters;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.sax.XMLSerializer;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.transformation.Transformer;
  import org.apache.cocoon.webapps.portal.PortalConstants;
  import org.apache.cocoon.webapps.portal.context.SessionContextImpl;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  
  /**
   * This is the thread for loading one coplet in the background.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: CopletThread.java,v 1.4 2002/07/31 13:13:31 stephan Exp $
  */
  public final class CopletThread implements Runnable {
  
      private Logger           logger;
      private String           copletID;
      private Map              objectModel;
      private Response         response;
      private ResourceConnector resourceConnector;
      private Object[]         loadedCoplet;
      private ComponentManager manager;
      private SourceResolver   resolver;
  
      /**
       * Initialise all instance variables.
       * The main information is the loadedCoplet array:
       * 0 : contains the result of the coplet loading, <code>null</code>or
       *     the compiled sax events
       * 1 : The coplet configuration element from the coplet profile
       * 2 : The resource parameters
       * 3 : The coplet element
       * 4 : Current time
       * 5 : The timeout
       * 6 : The thread (this)
       * 7 : The status profile
       */
      public void init(String  copletID,
                       Map     objectModel,
                       Logger  logger,
                       Response response,
                       ResourceConnector resourceConnector,
                       Object[] loadedCoplet,
                       ComponentManager manager,
                       SourceResolver resolver) {
          this.copletID = copletID;
          this.objectModel = objectModel;
          this.logger = logger;
          this.response = response;
          this.resourceConnector = resourceConnector;
          this.loadedCoplet = loadedCoplet;
          this.manager = manager;
          this.resolver = resolver;
      }
  
      /**
       * Process one coplet
       */
      public void run() {
          XMLSerializer compiler = null;
          Element copletConf = (Element)this.loadedCoplet[1];
          SourceParameters p = (SourceParameters)loadedCoplet[2];
  
          try {
              // Determine the resource to load
              // If the coplet is customizable and has no customization info
              // the customization resource is loaded, otherwise the resource
              Resource resource = null;
              boolean showCustomizePage = p.getParameterAsBoolean(PortalConstants.PARAMETER_CUSTOMIZE, false);
              if (showCustomizePage == true) {
                  final String value = DOMUtil.getValueOf(copletConf, "customization/@uri", null);
                  if (value == null) {
                      this.logger.error("The coplet '"+this.copletID+"' is customizable but has no customization info.");
                  }
                  resource = new Resource(this.resolver, value);
              }
              if (resource == null) {
                  resource = new Resource(this.resolver, DOMUtil.getValueOf(copletConf, "resource/@uri"));
              }
              boolean handlesSizable = DOMUtil.getValueAsBooleanOf(copletConf, "configuration/handlesSizable", false);
  
              if (handlesSizable == false && p.getParameter("size", "max").equals("max") == false) {
                  // do nothing here
                  loadedCoplet[0] = new byte[0];
              } else {
  
                  compiler = (XMLSerializer)this.manager.lookup(XMLSerializer.ROLE);
                  compiler.startDocument();
  
                  XMLConsumer nextConsumer = compiler;
                  NodeList transformations = DOMUtil.selectNodeList(copletConf,
                                                          "transformation/stylesheet");
                  Transformer xslT = null;
                  ArrayList transformers = new ArrayList();
                  ComponentSelector selector = null;
                  Request request = ObjectModelHelper.getRequest(this.objectModel);
  
                  try {
                      if (transformations != null && transformations.getLength() > 0) {
                          selector = (ComponentSelector) this.manager.lookup(Transformer.ROLE + "Selector");
                          nextConsumer = new IncludeXMLConsumer(nextConsumer);
                          for(int k = transformations.getLength()-1; k >=0; k--) {
                              xslT = (Transformer)selector.select("xslt");
                              transformers.add(xslT);
                              xslT.setup(resolver,
                                         objectModel,
                                         DOMUtil.getValueOfNode(transformations.item(k)),
                                         new Parameters());
                              xslT.setConsumer(nextConsumer);
                              nextConsumer = xslT;
                          }
                          nextConsumer.startDocument();
                      }
                      switch (resource.getResourceType()) {
                          case ResourceConnector.RESOURCE_TYPE_CLASS: {
                               Coplet theCoplet;
                               try {
                                   Class loaderClass = Class.forName(resource.getResourceIdentifier());
                                   theCoplet = (Coplet)loaderClass.newInstance();
                               } catch (ClassNotFoundException cnfException) {
                                   throw new ProcessingException("getCoplet: Class not found: " + resource.getResourceIdentifier(), cnfException);
                               } catch (IllegalAccessException iaException) {
                                   throw new ProcessingException("getCoplet: Illegal Access: " + resource.getResourceIdentifier(), iaException);
                               } catch (InstantiationException iException) {
                                   throw new ProcessingException("getCoplet: Instantion exception: " + resource.getResourceIdentifier(), iException);
                               }
                               theCoplet.init(objectModel, p);
                               theCoplet.execute(nextConsumer, nextConsumer, objectModel, p);
                               break;
                          }
                          default: {
                              boolean includeFragment = true;
                              boolean handlesParameters = DOMUtil.getValueAsBooleanOf(copletConf, "configuration/handlesParameters", true);
                              String size = p.getParameter("size", "max");
                              if (resource.getResourceType() == ResourceConnector.RESOURCE_TYPE_FILE) {
                                  // files have no possibility to evaluate minimized, so if they are not maximized
                                  // they will be neglected
                                  includeFragment = size.equals("max");
  
                              } else {
                                  includeFragment = size.equals("max");
                                  if (includeFragment == false) {
                                      if (this.logger.isWarnEnabled() == true) {
                                          this.logger.warn("Minimized coplet '"+copletID+"' not handled correctly.");
                                      }
                                  }
                              }
                              if ( includeFragment == true) {
                                  String res;
  
                                  if (resource.getResourceType() == ResourceConnector.RESOURCE_TYPE_URI) {
                                       if (this.response != null) {
                                           res = this.response.encodeURL(resource.getResourceIdentifier());
                                       } else {
                                           res = resource.getResourceIdentifier();
                                       }
                                  } else {
                                       res = resource.getResourceIdentifier();
                                  }
                                  if (this.logger.isDebugEnabled() == true) {
                                      this.logger.debug("portal: Loading coplet " + copletID);
                                  }
                                  // add the parameters to the request attributes
                                  Map info = new HashMap(3);
                                  SessionContextImpl.copletInfo.set(info);
                                  info.put(PortalConstants.COPLETINFO_PARAMETERS, p);
                                  info.put(PortalConstants.COPLETINFO_PORTALURI, request.getRequestURI());
                                  info.put(PortalConstants.COPLETINFO_STATUSPROFILE, loadedCoplet[7]);
                                  XMLConsumer xc = new IncludeXMLConsumer(nextConsumer);
                                  this.resourceConnector.streamXML(resource.getResourceType(), null,
                                             res, (handlesParameters == true ? p : null),
                                             xc  , xc);
                                  if (this.logger.isDebugEnabled() == true) {
                                      this.logger.debug("portal: Loaded coplet " + copletID);
                                  }
                              }
                          }
                      }
                      if (xslT != null) {
                          xslT.endDocument();
                          xslT = null;
                      }
                  } finally {
                      SessionContextImpl.copletInfo.set(null);
                      if (selector != null) {
                          for(int i=0; i<transformers.size(); i++) {
                              selector.release((Component)transformers.get(i));
                          }
                          this.manager.release((Component)selector);
                      }
                  }
                  transformers.clear();
                  nextConsumer = null;
                  compiler.endDocument();
                  loadedCoplet[0] = compiler.getSAXFragment();
  
              }
          } catch (Exception local) {
              // this exception is ignored and an error message is included
              // later on when the coplet is processed
              this.logger.error("Exception during processing of coplet: " + copletID, local);
          } catch (Throwable local) {
              // this exception is ignored and an error message is included
              // later on when the coplet is processed
              this.logger.error("Exception during processing of coplet: " + copletID, local);
          } finally {
              if (compiler != null) this.manager.release((Component)compiler);
          }
          loadedCoplet[6] = null;
          copletID = null;
          copletConf = null;
          this.logger = null;
          objectModel = null;
          p = null;
          response = null;
          resourceConnector = null;
          loadedCoplet = null;
          manager = null;
          resolver = null;
      } // END run
  } // END CLASS
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/acting/LogoutAction.java
  
  Index: LogoutAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.acting;
  
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Iterator;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  
  /**
   *  This action logs the current user out of a given handler
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: LogoutAction.java,v 1.2 2002/08/15 14:51:27 cziegeler Exp $
  */
  public final class LogoutAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws Exception {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN act resolver="+resolver+
                                     ", objectModel="+objectModel+
                                     ", source="+source+
                                     ", par="+par);
          }
  
          final Request request = ObjectModelHelper.getRequest( objectModel );
          final String handlerName = par.getParameter("handler",
                                                      (String)request.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME));
          if ( null == handlerName )
              throw new ProcessingException("LogoutAction requires at least the handler parameter.");
  
          int mode;
          final String modeString = par.getParameter("mode", "if-not-authenticated");
          if ( modeString.equals("if-not-authenticated") ) {
              mode = AuthenticationConstants.LOGOUT_MODE_IF_NOT_AUTHENTICATED;
          } else if ( modeString.equalsIgnoreCase("if-unused") ) {
              mode = AuthenticationConstants.LOGOUT_MODE_IF_UNUSED;
          } else if ( modeString.equalsIgnoreCase("immediately") ) {
              mode = AuthenticationConstants.LOGOUT_MODE_IMMEDIATELY;
          } else {
             throw new ProcessingException("Unknown mode " + modeString);
          }
  
          // authenticate
          AuthenticationManager manager = null;
          try {
              manager = (AuthenticationManager) this.manager.lookup(AuthenticationManager.ROLE);
              manager.logout( handlerName , mode );
          } finally {
              this.manager.release( manager );
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END act map={}");
          }
  
          return EMPTY_MAP;
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/acting/LoginAction.java
  
  Index: LoginAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.acting;
  
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Iterator;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  import org.apache.cocoon.webapps.session.SessionConstants;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.w3c.dom.DocumentFragment;
  
  /**
   *  This action logs the current user into a given handler. If the
   *  authentication is successful, a map is returned with the authentication
   *  information and a session is created (if it not already exists).
   *  If the authentication is not successful, the error information is stored
   *  into the temporary context.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: LoginAction.java,v 1.4 2002/07/05 07:16:33 cziegeler Exp $
  */
  public final class LoginAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws Exception {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN act resolver="+resolver+
                                     ", objectModel="+objectModel+
                                     ", source="+source+
                                     ", par="+par);
          }
  
          final String handlerName = par.getParameter("handler", null);
          if ( handlerName == null )
              throw new ProcessingException("LoginAction requires at least the handler parameter.");
          final Request request = ObjectModelHelper.getRequest( objectModel );
  
          // build authentication parameters
          SourceParameters authenticationParameters = new SourceParameters();
          String[] enum = par.getNames();
          if (enum != null) {
              for(int i = 0; i < enum.length; i++) {
                  final String key = enum[i];
                  if ( key.startsWith("parameter_") ) {
                      authenticationParameters.setParameter( key.substring("parameter_".length()),
                                                             par.getParameter(key));
                  }
              }
  
          }
  
          Map map = null;
  
          // authenticate
          AuthenticationManager authManager = null;
          try {
              authManager = (AuthenticationManager) this.manager.lookup(AuthenticationManager.ROLE);
              Object o;
  
              o = authManager.authenticate( handlerName,
                                        authenticationParameters);
              if ( null == o) {
                  // success
                  map = authManager.createMap();
  
              } else {
                  SessionManager sessionManager = (SessionManager) this.manager.lookup(SessionManager.ROLE);
                  try {
                      sessionManager.getContext(SessionConstants.TEMPORARY_CONTEXT).appendXML("/", (DocumentFragment)o);
                  } finally {
                      this.manager.release(sessionManager);
                  }
              }
          } finally {
              this.manager.release(authManager);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END act map="+map);
          }
  
          return map;
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/acting/LoggedInAction.java
  
  Index: LoggedInAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.acting;
  
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Iterator;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  
  /**
   *  This action tests if the user is logged in for a given handler.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: LoggedInAction.java,v 1.1 2002/04/17 10:04:52 cziegeler Exp $
  */
  public final class LoggedInAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws Exception {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN act resolver="+resolver+
                                     ", objectModel="+objectModel+
                                     ", source="+source+
                                     ", par="+par);
          }
  
          Map map = null;
          String handlerName = par.getParameter("handler", null);
          AuthenticationManager authManager = null;
  
          try {
              authManager = (AuthenticationManager) this.manager.lookup(AuthenticationManager.ROLE);
              if (authManager.isAuthenticated(handlerName) == true) {
                  map = authManager.createMap();
              }
          } finally {
              this.manager.release(authManager);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END act map="+map);
          }
  
          return map;
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/acting/AuthAction.java
  
  Index: AuthAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.acting;
  
  import java.util.Map;
  import java.util.HashMap;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  
  /**
   *  This is the authentication action
   *  This action contains the complete configuration for the authentication
   *  Manager. During configuration the AuthenticationManager class gets this
   *  configuration to configure the instances properly.
   *  The main task of this action is to check if the user is authenticated
   *  using a handler. If not a redirect takes place.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AuthAction.java,v 1.3 2002/08/13 15:29:11 cziegeler Exp $
  */
  public final class AuthAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws Exception {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN act resolver="+resolver+
                                     ", objectModel="+objectModel+
                                     ", source="+source+
                                     ", par="+par);
          }
          String handlerName = null;
          String applicationName = null;
          AuthenticationManager authManager = null;
          Map map = null;
  
          boolean initialized;
  
          try {
              final Request request = ObjectModelHelper.getRequest( objectModel );
  
              // Are we called as an internal resource?
              if ( objectModel.get("Internal-Request") != null ) {
                  handlerName = (String)request.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME);
                  applicationName = (String)request.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME);
                  initialized = true;
              } else {
                  handlerName = par.getParameter("handler", null);
                  applicationName = par.getParameter("application", null);
                  if (handlerName != null) request.setAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME, handlerName);
                  if (applicationName != null) request.setAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME, applicationName);
                  initialized = false;
              }
  
              authManager = (AuthenticationManager) this.manager.lookup( AuthenticationManager.ROLE );
  
              // do authentication
              if (authManager.checkAuthentication(redirector, !initialized) == false) {
                  // All events are ignored
                  // the sitemap.xsl ensures that only the redirect is processed
              } else {
                  if (initialized == false) {
                      map = authManager.createMap();
                  } else {
                      map = EMPTY_MAP;
                  }
              }
          } finally {
              this.manager.release( authManager );
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END act map="+map);
          }
          return map;
      }
  
  }
  
  
  1.10      +5 -5      xml-cocoon2/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java
  
  Index: SourceWritingTransformer.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- SourceWritingTransformer.java	17 Jul 2002 15:13:01 -0000	1.9
  +++ SourceWritingTransformer.java	27 Sep 2002 09:05:06 -0000	1.10
  @@ -68,10 +68,10 @@
   import org.apache.cocoon.components.source.WriteableSAXSource;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.ResourceNotFoundException;
  -import org.apache.cocoon.webapps.session.xml.XMLUtil;
   import org.apache.cocoon.xml.XMLConsumer;
   import org.apache.cocoon.xml.XMLUtils;
   import org.apache.cocoon.xml.dom.DOMStreamer;
  +import org.apache.cocoon.xml.dom.DOMUtil;
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceException;
   import org.w3c.dom.*;
  @@ -644,12 +644,12 @@
                   // import the fragment
                   Node importNode = resource.importNode(fragment, true);
                   // get the node
  -                Node parent = XMLUtil.selectSingleNode(resource, path);
  +                Node parent = DOMUtil.selectSingleNode(resource, path);
   
                   // replace?
                   if (replacePath != null) {
                       try {
  -                        Node replaceNode = XMLUtil.getSingleNode(parent, replacePath);
  +                        Node replaceNode = DOMUtil.getSingleNode(parent, replacePath);
                           // now get the parent of this node until it is the parent node for insertion
                           while (replaceNode != null && replaceNode.getParentNode().equals(parent) == false) {
                              replaceNode = replaceNode.getParentNode();
  @@ -673,7 +673,7 @@
                                   }
                                   message += ", replacing: " + replacePath;
                                   if (reinsertPath != null) {
  -                                    Node insertAt = XMLUtil.getSingleNode(parent, reinsertPath);
  +                                    Node insertAt = DOMUtil.getSingleNode(parent, reinsertPath);
                                       if (insertAt != null) {
                                           while (replaceNode.hasChildNodes() == true) {
                                               insertAt.appendChild(replaceNode.getFirstChild());
  @@ -711,7 +711,7 @@
   
                   } else {
                       // get the node
  -                    Node parent = XMLUtil.selectSingleNode(resource, path);
  +                    Node parent = DOMUtil.selectSingleNode(resource, path);
                       // add fragment
                       parent.appendChild(importNode);
                       message = "content appended to: " + path;
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/PortalConstants.java
  
  Index: PortalConstants.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal;
  
  /**
   * Some constants for the portal
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: PortalConstants.java,v 1.1 2002/04/17 12:39:19 cziegeler Exp $
  */
  public interface PortalConstants {
  
      /** The name of the portal context. */
      String SESSION_CONTEXT_NAME = "portal";
  
      /** The private context of the portal profile. Some more information
       *  is appended by the PortalManager to this key.
       */
      String PRIVATE_SESSION_CONTEXT_NAME = "org.apache.cocoon.webapps.portal.context.SessionContext";
  
      /** The Module name of the authentication module */
      String AUTHENTICATION_MODULE_NAME = "portal";
  
      /** If a coplet is loaded the <code>SessionInfo.copletInfo</code> map
       *  contains in this key the parameters for the coplet.
       */
      String COPLETINFO_PARAMETERS = "COPLETINFO_PARAMETERS";
  
      /** If a coplet is loaded the <code>SessionInfo.copletInfo</code> map
       *  contains in this key the portal URI
       */
      String COPLETINFO_PORTALURI = "COPLETINFO_PORTALURI";
  
      /** If a coplet is loaded the <code>SessionInfo.copletInfo</code> map
       *  contains in this key the status profile
       */
      String COPLETINFO_STATUSPROFILE = "COPLETINFO_STATUSPROFILE";
  
      // XML Elements
      String ELEMENT_CONFIGURATION="configuration";
      String ELEMENT_ID        = "id";
      String ELEMENT_ADMINCONF = "portaladminconf";
      String ELEMENT_LAYOUT    = "layout";
      String ELEMENT_PORTAL    = "portal";
      String ELEMENT_PORTALCONF= "portalconf";
      String ELEMENT_PROFILE   = "profile";
      String ELEMENT_ROLE      = "role";
      String ELEMENT_STATE     = "state";
      String ELEMENT_COPLET    = "coplet";
      String ELEMENT_COPLETS   = "coplets";
  
      // admin conf states
      final String STATE_USER    = "user";
      final String STATE_ROLE    = "role";
      final String STATE_MAIN    = "main";
      final String STATE_COPLETS = "coplets";
      final String STATE_GLOBAL  = "global";
      final String STATE_COPLET  = "coplet";
      final String STATE_MAIN_ROLE= "mainrole";
  
      /** The name of the attribute holding the portal configuration */
      final String ATTRIBUTE_CONFIGURATION  = "portalConf";
  
      /** The name of the attribute holding the url rewritten portal uri */
      final String ATTRIBUTE_PORTAL_URI  = "portalURI";
  
      final String ATTRIBUTE_COPLET_REPOSITORY = "portalRep";
  
      final String PROFILE_PROFILE        = "profile";   // DocumentFragment
      final String PROFILE_TYPE_PATHS     = "typePaths"; // List
      final String PROFILE_TYPE_CONF_PATHS= "typeConfPaths"; // List
      final String PROFILE_PORTAL_LAYOUTS = "portalLayouts"; // Map
      final String PROFILE_COPLET_LAYOUTS = "copletLayouts"; // Map
      final String PROFILE_MISC_POINTER   = "misc"; // Node[] with the values from below
          final int  PROFILE_MISC_HEADER_NODE = 0;
          final int  PROFILE_MISC_FOOTER_NODE = 1;
          final int  PROFILE_MISC_HEADER_CONTENT_NODE = 2;
          final int  PROFILE_MISC_FOOTER_CONTENT_NODE = 3;
          final int  PROFILE_MISC_COLUMNS_NODE= 4;
          final int  PROFILE_MISC_LAST_COPLET_NODE = 5;
          final int  PROFILE_MISC_MESSAGES_NODE = 6;
          // starting with 8 the columns follow (by now max: 5)
  
      final String PROFILE_DEFAULT_COPLETS= "defCoplets"; // Map
      final String PROFILE_MEDIA_COPLETS  = "mediaCoplets"; // Map
      final String PROFILE_SAVE_STATUS_FLAG= "saveStatus"; // Value not used
  
      /** Configuration Map */
      final String CONF_BUILD_RESOURCE           = "A";
      final String CONF_AUTH_REDIRECT            = "B";
      final String CONF_LAYOUTBASE_RESOURCE      = "C";
      final String CONF_COPLETBASE_RESOURCE      = "D";
      final String CONF_COPLETBASE_SAVE_RESOURCE = "E";
      final String CONF_TYPEBASE_RESOURCE        = "F";
      final String CONF_GLOBALDELTA_LOADRESOURCE = "G";
      final String CONF_GLOBALDELTA_SAVERESOURCE = "H";
      final String CONF_GLOBALDELTA_TYPERESOURCE = "I";
      final String CONF_ROLEDELTA_LOADRESOURCE   = "J";
      final String CONF_ROLEDELTA_SAVERESOURCE   = "K";
      final String CONF_ROLEDELTA_TYPERESOURCE   = "L";
      final String CONF_USERDELTA_LOADRESOURCE   = "M";
      final String CONF_USERDELTA_SAVERESOURCE   = "N";
      final String CONF_USERDELTA_TYPERESOURCE   = "O";
      final String CONF_STATUS_LOADRESOURCE      = "P";
      final String CONF_STATUS_SAVERESOURCE      = "Q";
      final String CONF_ADMIN_TYPE_BASE          = "R";
      final String CONF_PORTAL_URI               = "S";
      final String CONF_PROFILE_CACHE            = "T";
      final String CONF_PARALLEL_COPLETS         = "U";
      final String CONF_COPLET_TIMEOUT           = "V";
  
      final int MAX_COLUMNS = 5;
  
      /* The Parameters for the coplet */
      final String PARAMETER_MEDIA = "media";
      final String PARAMETER_ID    = "id";
      final String PARAMETER_NUMBER= "number";
      final String PARAMETER_CUSTOMIZE = "customize";
      final String PARAMETER_SIZE  = "size";
      final String PARAMETER_VISIBLE= "visible";
      final String PARAMETER_PERSISTENT= "persistent";
  }
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/components/Handler.java
  
  Index: Handler.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.components;
  
  import java.io.IOException;
  import java.util.*;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.Request;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.connector.*;
  import org.xml.sax.SAXException;
  
  /**
   * The authentication Handler.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: Handler.java,v 1.7 2002/08/21 13:36:11 cziegeler Exp $
  */
  public final class Handler
  implements java.io.Serializable {
  
      /** The unique name of the handler */
      private final String name;
  
      /** The redirect-to URI */
      private String redirectURI;
  
      /** The redirect parameters */
      private SourceParameters redirectParameters;
  
      /** The authentication resource */
      private Resource authenticationResource;
  
      /** The load resource (optional) */
      private Resource loadResource;
  
      /** The save resource (optional) */
      private Resource saveResource;
  
      /** The ApplicationHandler */
      private Map applications = new Hashtable(3, 2);
  
      /** The load-users resource */
      private Resource loadUsersResource;
  
      /** The load-roles resource */
      private Resource loadRolesResource;
  
      /** The new-user resource */
      private Resource newUserResource;
  
      /** The new-role resource */
      private Resource newRoleResource;
  
      /** The delete-role resource */
      private Resource deleteRoleResource;
  
      /** The delete-user resource */
      private Resource deleteUserResource;
  
      /** The change-user resource */
      private Resource changeUserResource;
  
      /** The handler contexts */
      private List handlerContexts = new ArrayList(2);
  
      /** Are all apps loaded? */
      private boolean appsLoaded = false;
  
      /**
       * Create a new handler object.
       */
      public Handler(String name) {
          this.name = name;
      }
  
      /**
       * Make a copy
       */
      public Handler copy() {
          final Handler copy = new Handler(this.name);
          copy.redirectURI = this.redirectURI;
          copy.redirectParameters = this.redirectParameters;
          copy.authenticationResource = this.authenticationResource;
          copy.loadResource = this.loadResource;
          copy.saveResource = this.saveResource;
          copy.loadUsersResource = this.loadUsersResource;
          copy.loadRolesResource = this.loadRolesResource;
          copy.newUserResource = this.newUserResource;
          copy.newRoleResource = this.newRoleResource;
          copy.deleteUserResource = this.deleteUserResource;
          copy.deleteRoleResource = this.deleteRoleResource;
          copy.changeUserResource = this.changeUserResource;
          Iterator iter = this.applications.keySet().iterator();
          while (iter.hasNext()) {
              final String name = (String)iter.next();
              copy.applications.put(name, ((ApplicationHandler)this.applications.get(name)).copy(copy));
          }
          return copy;
      }
  
      /**
       * Configure
       */
      public void configure(SourceResolver resolver,
                            Request        request,
                            Configuration  conf)
      throws ProcessingException, SAXException, IOException, ConfigurationException {
          // get login (required)
          Configuration child = conf.getChild("redirect-to", false);
          if (child == null)
              throw new ConfigurationException("Handler '"+this.name+"' needs a redirect-to URI.");
          this.redirectURI = child.getAttribute("uri");
          if ( this.redirectURI.startsWith("cocoon:") ) {
              final int pos = this.redirectURI.indexOf('/');
              if ( pos != -1 && this.redirectURI.length() > pos) {
                  if (this.redirectURI.charAt(pos+1) == '/') {
                      this.redirectURI = this.redirectURI.substring(pos+2).trim();
                      this.redirectURI = request.getContextPath()+"/"+this.redirectURI;
                  } else {
                      this.redirectURI = this.redirectURI.substring(pos+1).trim();
                  }
              }
          }
  
          this.redirectParameters = SourceParameters.create(child);
  
          // get load resource (required)
          child = conf.getChild("authentication", false);
          if (child == null)
              throw new ConfigurationException("Handler '"+this.name+"' needs authentication configuration");
          this.authenticationResource = new Resource(resolver, child.getAttribute("uri"));
          this.authenticationResource.setResourceParameters(SourceParameters.create(child));
  
          // get load resource (optional)
          child = conf.getChild("load", false);
          if (child != null) {
              this.loadResource = new Resource(resolver, child.getAttribute("uri"));
              this.loadResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get save resource (optional)
          child = conf.getChild("save", false);
          if (child != null) {
              this.saveResource = new Resource(resolver, child.getAttribute("uri"));
              this.saveResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get load-users resource (optional)
          child = conf.getChild("load-users", false);
          if (child != null) {
              this.loadUsersResource = new Resource(resolver, child.getAttribute("uri"));
              this.loadUsersResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get load-roles resource (optional)
          child = conf.getChild("load-roles", false);
          if (child != null) {
              this.loadRolesResource = new Resource(resolver, child.getAttribute("uri"));
              this.loadRolesResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get new user resource (optional)
          child = conf.getChild("new-user", false);
          if (child != null) {
              this.newUserResource = new Resource(resolver, child.getAttribute("uri"));
              this.newUserResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get new role resource (optional)
          child = conf.getChild("new-role", false);
          if (child != null) {
              this.newRoleResource = new Resource(resolver, child.getAttribute("uri"));
              this.newRoleResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get delete user resource (optional)
          child = conf.getChild("delete-user", false);
          if (child != null) {
              this.deleteUserResource = new Resource(resolver, child.getAttribute("uri"));
              this.deleteUserResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get delete role resource (optional)
          child = conf.getChild("delete-role", false);
          if (child != null) {
              this.deleteRoleResource = new Resource(resolver, child.getAttribute("uri"));
              this.deleteRoleResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get change user resource (optional)
          child = conf.getChild("change-user", false);
          if (child != null) {
              this.changeUserResource = new Resource(resolver, child.getAttribute("uri"));
              this.changeUserResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // And now: Applications
          child = conf.getChild("applications", false);
          if (child != null) {
              Configuration[] appConfs = child.getChildren("application");
              Configuration appconf;
  
              if (appConfs != null) {
                  for(int i = 0; i < appConfs.length; i++) {
                      appconf = appConfs[i];
  
                      // get name
                      String appName = appconf.getAttribute("name");
  
                      // test if handler is unique
                      if (this.applications.get(appName) != null) {
                          throw new ConfigurationException("Application names must be unique: " + appName);
                      }
  
                      // create handler
                      ApplicationHandler apphandler = new ApplicationHandler(this, appName);
  
                      // store handler
                      this.applications.put(appName, apphandler);
  
                      // configure
                      apphandler.configure(resolver, appconf);
                  }
              }
          }
  
      }
  
  
      /**
       * Get the handler name.
       */
      public String getName() { return name; }
  
      /**
       * Get the redirect URI
       */
      public String getRedirectURI() {
          return this.redirectURI;
      }
  
      /**
       * Get the redirect parameters
       */
      public SourceParameters getRedirectParameters() {
          return this.redirectParameters;
      }
  
      /**
       * Get the authentication resource
       */
      public Resource getAuthenticationResource() {
          return this.authenticationResource;
      }
  
      /**
       * Get the load users resource
       */
      public Resource getLoadUsersResource() { return loadUsersResource; }
  
      /**
       * Get the load roles resource
       */
      public Resource getLoadRolesResource() { return loadRolesResource; }
  
      /**
       * Get the new user resource
       */
      public Resource getNewUserResource() { return this.newUserResource; }
  
      /**
       * Get the new role resource
       */
      public Resource getNewRoleResource() { return this.newRoleResource; }
  
      /** Get the delete user resource */
      public Resource getDeleteUserResource() { return this.deleteUserResource; }
  
      /** Get the delete role resource */
      public Resource getDeleteRoleResource() { return this.deleteRoleResource; }
  
      /** Get the change user resource */
      public Resource getChangeUserResource() { return this.changeUserResource; }
  
      /** Get the save resource */
      public Resource getSaveResource() { return this.saveResource; }
  
      /** Get the save resource */
      public Resource getLoadResource() { return this.loadResource; }
  
      /**
       * Get the applications map
       */
      public Map getApplications() { return applications; }
  
      public void setApplicationsLoaded(boolean value)
      throws ProcessingException {
          this.appsLoaded = value;
      }
  
      public boolean getApplicationsLoaded()
      throws ProcessingException {
          if (this.applications.isEmpty() == true) {
              return true;
          } else {
              return this.appsLoaded;
          }
      }
  
      /**
       * Add a handler context
       */
      public void addHandlerContext(SessionContext context) {
          this.handlerContexts.add( context );
      }
  
      /**
       * Get handler contexts
       */
      public List getHandlerContexts() {
          return this.handlerContexts;
      }
  
      /**
       * Clear handler contexts
       */
      public void clearHandlerContexts() {
          this.handlerContexts.clear();
      }
  
      /**
       * toString()
       */
      public String toString() {
          return "authentication-Handler " + this.name;
      }
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/components/ApplicationHandler.java
  
  Index: ApplicationHandler.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.components;
  
  import java.io.IOException;
  import java.util.*;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.connector.*;
  import org.xml.sax.SAXException;
  
  /**
   * This object stores information about an application configuration
   * inside a handler configuration.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ApplicationHandler.java,v 1.5 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class ApplicationHandler
  implements java.io.Serializable {
  
      /** The unique name of the handler */
      private String name;
  
      /** The load resource (optional) */
      private Resource loadResource;
  
      /** The save resource (optional) */
      private Resource saveResource;
  
      /** Is the application loaded on demand */
      private boolean loadOnDemand = false;
  
      /** Is the application loaded ? */
      private boolean isLoaded = false;
  
      /** The corresponding handler */
      private Handler handler;
  
      /** The configuration fragments */
      private Map configurations;
  
      /**
       * Construct a new application handler
       */
      public ApplicationHandler(Handler handler, String name)
      throws ProcessingException {
          this.handler = handler;
          this.name = name;
          if (name.indexOf('_') != -1
              || name.indexOf(':') != -1
              || name.indexOf('/') != -1) {
             throw new ProcessingException("application name must not contain one of the characters ':','_' or '/'.");
          }
          this.configurations = new HashMap(3, 2);
      }
  
      /**
       * Make a copy
       */
      public ApplicationHandler copy(Handler handler) {
          try {
              final ApplicationHandler ah = new ApplicationHandler(handler, this.name);
              ah.loadOnDemand = this.loadOnDemand;
              ah.loadResource = this.loadResource;
              ah.saveResource = this.saveResource;
              ah.configurations = this.configurations;
              return ah;
          } catch (ProcessingException pe) {
              // ignore it and keep the compiler happy
              return null;
          }
      }
  
      /**
       * Configure an application
       */
      public void configure(SourceResolver resolver, Configuration appconf)
      throws ProcessingException, SAXException, IOException, ConfigurationException {
          Configuration child = null;
          String        uri       = null;
          String        classname = null;
  
          // test for loadondemand attribute
          this.loadOnDemand = appconf.getAttributeAsBoolean("loadondemand", false);
  
          // get load resource (optinal)
          child = appconf.getChild("load", false);
          if (child != null) {
              this.loadResource = new Resource(resolver, child.getAttribute("uri"));
              this.loadResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get save resource (optional)
          child =  appconf.getChild("save", false);
          if (child != null) {
              this.saveResource = new Resource(resolver, child.getAttribute("uri"));
              this.saveResource.setResourceParameters(SourceParameters.create(child));
          }
  
          // get configurations (optional)
          Configuration[] configurations = appconf.getChildren("configuration");
          if (configurations != null) {
              for(int i = 0; i < configurations.length; i++) {
                  child = configurations[i];
                  String value = child.getAttribute("name");
                  if (this.getConfiguration(value) != null) {
                      throw new ConfigurationException("Configuration names must be unique for application " + this.name + ": " + value);
                  }
                  this.configurations.put(value, child);
              }
          }
      }
  
      /**
       * Get the application name.
       */
      public String getName() { return name; }
  
      /**
       * Get the handler
       */
      public Handler getHandler() { return handler; }
  
      /**
       * Get the load resource
       */
      public Resource getLoadResource() {
          return this.loadResource;
      }
  
      /**
       * Get the save resource
       */
      public Resource getSaveResource() {
          return this.saveResource;
      }
  
  
      public boolean getIsLoaded()
      throws ProcessingException {
          if (this.loadResource == null) {
              return true;
          } else {
              return this.isLoaded;
          }
      }
  
      public void setIsLoaded(boolean value)
      throws ProcessingException {
          this.isLoaded = value;
      }
  
      public boolean getLoadOnDemand() { return loadOnDemand; }
  
      /**
       * Get the configuration
       */
      public Configuration getConfiguration(String name) {
          return (Configuration)this.configurations.get(name);
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/components/HandlerManager.java
  
  Index: HandlerManager.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.components;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import java.util.*;
  
  
  /**
   *  This is a utility class managing the authentication handlers
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: HandlerManager.java,v 1.8 2002/08/15 14:51:27 cziegeler Exp $
  */
  public final class HandlerManager {
  
      /** The name of the session attribute storing the handler configuration */
      public final static String SESSION_ATTRIBUTE_HANDLERS = "org.apache.cocoon.webapps.authentication.Handlers";
  
      public HandlerManager() {}
  
      /** All configured configurations */
      protected static List configuredConfigurations = new ArrayList(3);
  
      /** All configured handlers */
      protected static Map configuredHandlers = new HashMap(4);
  
      /** The available handlers for the current request */
      protected Map availableHandlers = new HashMap(4);
  
      /** The handlers of the current user */
      protected Map userHandlers;
  
      /**
       * Add new configurations to the pool
       */
      public void addConfiguration(Configuration  conf,
                                   SourceResolver resolver,
                                   Request        request)
      throws ConfigurationException {
          if (null != conf &&
              !configuredConfigurations.contains(conf)) {
              synchronized (configuredConfigurations) {
                  if (!configuredConfigurations.contains(conf)) {
                      configuredConfigurations.add( conf );
  
                      // test for handlers
                      Configuration handlersWrapper = conf.getChild("handlers", false);
                      if ( null != handlersWrapper ) {
                          Configuration[] handlers = handlersWrapper.getChildren("handler");
                          if ( null != handlers ) {
                              ArrayList al = new ArrayList(4);
                              for(int i=0; i<handlers.length;i++) {
                                  // check unique name
                                  final String name = handlers[i].getAttribute("name");
                                  if ( al.contains(name) ) {
                                      throw new ConfigurationException("Handler names must be unique: " + name);
                                  }
                                  al.add( name );
                                  this.addHandler( handlers[i], resolver, request);
                              }
                          }
                      }
                  }
              }
          }
      }
  
      /**
       * Add one handler configuration
       */
      protected void addHandler(Configuration  configuration,
                                SourceResolver resolver,
                                Request        request)
      throws ConfigurationException {
          // get handler name
          final String name = configuration.getAttribute("name");
  
          // create handler
          Handler currentHandler = new Handler(name);
  
          // store handler
          configuredHandlers.put(name, currentHandler);
  
          try {
              currentHandler.configure(resolver,request, configuration);
          } catch (ProcessingException se) {
              throw new ConfigurationException("Exception during configuration of handler: " + name, se);
          } catch (org.xml.sax.SAXException se) {
              throw new ConfigurationException("Exception during configuration of handler: " + name, se);
          } catch (java.io.IOException se) {
              throw new ConfigurationException("Exception during configuration of handler: " + name, se);
          }
      }
  
      /**
       * Clear all
       */
      public void clearConfigurations() {
          configuredConfigurations.clear();
          configuredHandlers.clear();
      }
  
      /**
       * Clear available handlers
       */
      public void clearAvailableHandlers() {
          this.availableHandlers.clear();
          this.userHandlers = null;
      }
  
      /**
       * Add to available handlers
       */
      public void addAvailableHandlers(Configuration  conf)
      throws ConfigurationException {
          if ( null != conf ) {
              final Configuration handlersConf = conf.getChild("handlers", false);
              if ( null != handlersConf ) {
                  Configuration[] handlers = handlersConf.getChildren("handler");
                  if ( null != handlers ) {
                      for(int i=0; i < handlers.length; i++) {
                          final String name = handlers[i].getAttribute("name");
                          final Object o = this.configuredHandlers.get(name);
                          if ( null == o)
                              throw new ConfigurationException("Handler " + name + " is missing in configuration.");
                          this.availableHandlers.put(name, o);
                      }
                  }
              }
          }
      }
  
      /**
       * Get the handler of the current user
       */
      public Handler getHandler(String handlerName,
                                Request request) {
          if ( null == handlerName) return null;
          if ( null == this.userHandlers) {
              final Session session = request.getSession(false);
              if ( null != session) {
                  this.userHandlers = (Map)session.getAttribute(SESSION_ATTRIBUTE_HANDLERS);
              }
          }
          Handler handler = null;
          if ( null != this.userHandlers) {
              handler = (Handler)this.userHandlers.get(handlerName);
          }
          if ( null == handler ) {
              handler = (Handler)this.availableHandlers.get(handlerName);
          }
          return handler;
      }
  
      /**
       * Create a handler copy for the user and return it!
       */
      public Handler storeUserHandler(Handler handler,
                                      Request request) {
          final Session session = request.getSession();
          if ( null == this.userHandlers) {
              this.userHandlers = (Map)session.getAttribute(SESSION_ATTRIBUTE_HANDLERS);
          }
          if ( null == this.userHandlers ) {
              this.userHandlers = new HashMap(3);
          }
          handler = handler.copy();
          this.userHandlers.put(handler.getName(), handler);
          // value did change, update attributes
          session.setAttribute(SESSION_ATTRIBUTE_HANDLERS, this.userHandlers);
  
          return handler;
      }
  
      /**
       * Remove from user handler
       */
      public void removeUserHandler(Handler handler, Request request) {
          final Session session = request.getSession();
          if ( null == this.userHandlers) {
              this.userHandlers = (Map)session.getAttribute(SESSION_ATTRIBUTE_HANDLERS);
          }
          if ( null != this.userHandlers) {
              this.userHandlers.remove( handler.getName() );
              // value did change, update attributes
              session.setAttribute(SESSION_ATTRIBUTE_HANDLERS, this.userHandlers);
          }
      }
  
      /**
       * Check, if a user handler is available (= is authenticated)
       */
      public boolean hasUserHandler(String name, Request request) {
          if ( null == this.userHandlers) {
              final Session session = request.getSession(false);
              if ( null != session) {
                  this.userHandlers = (Map)session.getAttribute(SESSION_ATTRIBUTE_HANDLERS);
              }
          }
          if ( null != this.userHandlers) {
              return this.userHandlers.containsKey( name );
          }
          return false;
      }
      
      /**
       * Check, if any handler is available
       */
      public boolean hasUserHandler(Request request) {
          if ( null == this.userHandlers) {
              final Session session = request.getSession(false);
              if ( null != session) {
                  this.userHandlers = (Map)session.getAttribute(SESSION_ATTRIBUTE_HANDLERS);
              }
          }
          if ( null != this.userHandlers) {
              return !this.userHandlers.isEmpty();
          }
          return false;
      }
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/components/AuthenticationManager.java
  
  Index: AuthenticationManager.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.components;
  
  import java.io.IOException;
  import java.util.*;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.excalibur.source.SourceUtil;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.acting.AbstractAction;
  import org.apache.cocoon.components.SitemapConfigurable;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import org.apache.cocoon.webapps.authentication.context.SessionContextImpl;
  import org.apache.cocoon.webapps.authentication.context.SessionContextProviderImpl;
  import org.apache.cocoon.webapps.session.components.AbstractSessionComponent;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.context.SessionContextProvider;
  import org.apache.cocoon.webapps.session.context.SimpleSessionContext;
  import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.XMLUtils;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.Text;
  
  /**
   *  This is the basis authentication component.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AuthenticationManager.java,v 1.15 2002/09/05 06:23:30 cziegeler Exp $
  */
  public final class AuthenticationManager
  extends AbstractSessionComponent
  implements Configurable, SitemapConfigurable {
  
      /** The Avalon Role */
      public static final String ROLE = AuthenticationManager.class.getName();
  
      /** Request parameter */
      public static final String REQ_PARAMETER_STATE = "authstate";
      public static final String REQ_PARAMETER_ROLE  = "authrole";
      public static final String REQ_PARAMETER_ID    = "authid";
      public static final String REQ_PARAMETER_USER  = "authuser";
  
      private static final String SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE = "org.apache.cocoon.webapps.authentication.adminrole";
  
      /** The handler manager */
      private HandlerManager handlerManager = new HandlerManager();
  
      /** The application name of the current resource */
      private String applicationName;
  
      /** The application */
      private ApplicationHandler application;
  
      /** The handler name of the current resource */
      private String handlerName;
  
      /** The handler of the current resource */
      private Handler handler;
  
      /** The media Types */
      private MediaType[] allMediaTypes;
      private String      defaultMediaType;
      private String[]    mediaTypeNames;
  
      /** media type */
      private String mediaType;
  
      /** The context provider */
      private static SessionContextProviderImpl contextProvider;
  
      /** Init the class,
       *  add the provider for the authentication context
       */
      static {
          // add the provider for the authentication context
          contextProvider = new SessionContextProviderImpl();
          try {
              SessionManager.addSessionContextProvider(contextProvider, AuthenticationConstants.SESSION_CONTEXT_NAME);
          } catch (ProcessingException local) {
              throw new RuntimeException("Unable to register provider for authentication context.");
          }
      }
  
      /**
       * Recyclable
       */
      public void recycle() {
          super.recycle();
          this.applicationName = null;
          this.application = null;
          this.handler = null;
          this.handlerName = null;
  
          // clear handlers
          this.handlerManager.clearAvailableHandlers();
      }
  
      /**
       * Set the <code>Configuration</code>.
       */
      public void setSitemapConfiguration(Configuration config)
      throws ConfigurationException {
          this.handlerManager.addConfiguration( config, this.resolver, this.request );
          this.handlerManager.addAvailableHandlers( config );
      }
  
      /**
       * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
       * used to process the request.
       *  This method is automatically called for each request. Do not invoke
       *  this method by hand.
       */
      public void setup(SourceResolver resolver, Map objectModel)
      throws ProcessingException, SAXException, IOException {
          super.setup(resolver, objectModel);
  
          // get the media of the current request
          String useragent = request.getHeader("User-Agent");
          MediaType media = null;
          if (useragent != null) {
              int i, l;
              i = 0;
              l = this.allMediaTypes.length;
              while (i < l && media == null) {
                  if (useragent.indexOf(this.allMediaTypes[i].useragent) == -1) {
                      i++;
                  } else {
                      media = this.allMediaTypes[i];
                  }
              }
          }
          this.mediaType = (media == null ? this.defaultMediaType : media.name);
          this.request.setAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE, this.mediaType);
      }
  
      /**
       * Configurable interface.
       */
      public void configure(Configuration myConfiguration)
      throws ConfigurationException {
          // no sync required
          Configuration mediaConf = myConfiguration.getChild("mediatypes", false);
          if (mediaConf == null) {
              // default configuration
              this.defaultMediaType = "html";
          } else {
              this.defaultMediaType = mediaConf.getAttribute("default", "html");
          }
          this.mediaTypeNames = new String[1];
          this.mediaTypeNames[0] = this.defaultMediaType;
          boolean found;
          int     i;
          String  name;
  
          Configuration[] childs = mediaConf.getChildren("media");
          MediaType[] array = new MediaType[0];
          MediaType[] copy;
          Configuration current;
          if (childs != null) {
              for(int x = 0; x < childs.length; x++) {
                  current = childs[x];
                  copy = new MediaType[array.length + 1];
                  System.arraycopy(array, 0, copy, 0, array.length);
                  array = copy;
                  name = current.getAttribute("name");
                  array[array.length-1] = new MediaType(name, current.getAttribute("useragent"));
                  found = false;
                  i = 0;
                  while ( i < this.mediaTypeNames.length && found == false) {
                      found = this.mediaTypeNames[i].equals(name);
                      i++;
                  }
                  if (found == false) {
                      String[] newStrings = new String[this.mediaTypeNames.length + 1];
                      System.arraycopy(this.mediaTypeNames, 0, newStrings, 0, this.mediaTypeNames.length);
                      newStrings[newStrings.length-1] = name;
                      this.mediaTypeNames = newStrings;
                  }
              }
          }
          this.allMediaTypes = array;
      }
  
      /**
       * Test if the media of the current request is the given value
       */
      public boolean testMedia(Map objectModel, String value) {
          // synchronized
          Request req = ObjectModelHelper.getRequest( objectModel );
          boolean result = false;
  
          if (req != null) {
              String useragent = request.getHeader("User-Agent");
              MediaType theMedia = null;
              int i, l;
              i = 0;
              l = this.allMediaTypes.length;
              while (i < l && theMedia == null) {
                  if (useragent.indexOf(this.allMediaTypes[i].useragent) == -1) {
                      i++;
                  } else {
                      theMedia = this.allMediaTypes[i];
                  }
              }
              if (theMedia != null) {
                  result = theMedia.name.equals(value);
              } else {
                  result = this.defaultMediaType.equals(value);
              }
          }
          return result;
      }
  
      public String[] getMediaTypes() {
          // synchronized
          return this.mediaTypeNames;
      }
  
      /**
       * Return the current handler
       */
      public Handler getHandler() {
          return this.handler;
      }
  
      /**
       * Show the configuration for the admin.
       * If <code>src</code> is "admin" or null the admin configuration is shown.
       * If <code>src</code> is "user" the configuration of the current user
       * is shown.
       */
      public void showConfiguration(XMLConsumer consumer,
                                    String      src)
      throws ProcessingException, SAXException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN showConfiguration consumer=" + consumer + ", src="+src);
          }
          boolean isAdmin = (src == null || src.equals("admin"));
  
          // now start producing xml:
          AttributesImpl attr = new AttributesImpl();
          consumer.startElement("", "configuration", "configuration", attr);
  
          // set the conf uri:
          // This is a bug in the servlet 2.2 API!!!
          // It does not contain the context:  String uri = HttpUtils.getRequestURL(this.request).toString();
          // So: ABSOLUTELY USELESS
          String uri = this.response.encodeURL(this.request.getRequestURI());
          consumer.startElement("", "uri", "uri", attr);
          consumer.characters(uri.toCharArray(), 0, uri.length());
          consumer.endElement("", "uri", "uri");
  
          if (isAdmin == true) {
              // build the menue
              consumer.startElement("", "menue", "menue", attr);
  
              if (this.handler != null) {
                  if (this.handler.getNewRoleResource() != null) {
                      consumer.startElement("", "addrole", "addrole", attr);
                      consumer.endElement("", "addrole", "addrole");
                  }
                  if (this.handler.getDeleteRoleResource() != null) {
                      consumer.startElement("", "delrole", "delrole", attr);
                      consumer.endElement("", "delrole", "delrole");
                  }
              }
              consumer.endElement("", "menue", "menue");
          }
  
          SessionContext context = this.getAuthenticationSessionContext(true);
  
          synchronized (context) {
  
              String state = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_STATE);
              if (state == null) {
                  state = (isAdmin == true ? "main" : "seluser");
              }
  
              if (state.equals("addrole") == true) {
                  String role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                  if (role != null && role.trim().length() > 0) {
                      SourceParameters pars = new SourceParameters();
                      // first include all request parameters
                      Enumeration requestParameters = this.request.getParameterNames();
                      String current;
                      while (requestParameters.hasMoreElements() == true) {
                          current = (String)requestParameters.nextElement();
                          pars.setParameter(current, this.request.getParameter(current));
                      }
                      this.addRole(role, pars);
                  } else {
                      role = null;
                  }
                  context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, null);
              }
  
              if (state.equals("delrole") == true) {
                  try {
                      String role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                      if (role != null) {
                          // first delete user
                          DocumentFragment userDF = this.getUsers(role, null);
                          NodeList         users   = null;
                          if (userDF != null) users = DOMUtil.selectNodeList(userDF, "users/user");
                          if (users != null) {
                              for(int i = 0; i < users.getLength(); i++) {
                                  this.deleteUser(role, DOMUtil.getValueOf(users.item(i), "ID"), null);
                              }
                          }
                          this.deleteRole(role, null);
                      }
                      context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, null);
                  } catch (javax.xml.transform.TransformerException local) {
                      throw new ProcessingException("TransformerException: " + local, local);
                  }
              }
  
  
              if (state.equals("chguser") == true) {
                  String role;
                  String id;
                  String user;
  
                  if (isAdmin == false) {
                      SourceParameters pars = this.createParameters(null);
                      id = pars.getParameter("ID", null);
                      role = pars.getParameter("role", null);
                      user = "old";
                  } else {
                      role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                      id   = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ID);
                      user = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_USER);
                  }
  
                  boolean addingNewUserFailed = false;
                  if (role != null && id != null && user != null) {
                      if (user.equals("new") == true) {
                          SourceParameters pars = new SourceParameters();
                          // first include all request parameters
                          Enumeration requestParameters = this.request.getParameterNames();
                          String current;
                          while (requestParameters.hasMoreElements() == true) {
                              current = (String)requestParameters.nextElement();
                              pars.setParameter(current, this.request.getParameter(current));
                          }
                          addingNewUserFailed = !this.addUser(role, id, pars);
                          if (addingNewUserFailed == false) {
                              consumer.startElement("", "addeduser", "addeduser", attr);
                              consumer.characters(id.toCharArray(), 0, id.length());
                              consumer.endElement("", "addeduser", "addeduser");
                          }
                      } else {
                          String delete = this.request.getParameter("authdeluser");
                          if (delete != null && delete.equals("true") == true) {
                              this.deleteUser(role, id, null);
                          } else {
                              SourceParameters pars = new SourceParameters();
                              // first include all request parameters
                              Enumeration requestParameters = this.request.getParameterNames();
                              String current;
                              while (requestParameters.hasMoreElements() == true) {
                                  current = (String)requestParameters.nextElement();
                                  pars.setParameter(current, this.request.getParameter(current));
                              }
                              this.changeUser(role, id, pars);
                          }
                      }
                      context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, null);
                  }
                  if (addingNewUserFailed == false) {
                      state = (isAdmin == true ? "adduser" : "seluser");
                  } else {
                      state = "erruser";
                  }
              }
  
              if (state.equals("seluser") == true) {
                  String role;
                  String id;
  
                  if (isAdmin == false) {
                      SourceParameters pars = this.createParameters(null);
                      id = pars.getParameter("ID", null);
                      role = pars.getParameter("role", null);
                  } else {
                      role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                      id   = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ID);
                  }
                  if (role != null && id != null) {
                      context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);
  
                      // include users
                      DocumentFragment userDF = this.getUsers(role, id);
                      Element          users   = null;
                      try {
                          if (userDF != null) users = (Element)DOMUtil.getSingleNode(userDF, "users/user");
                      } catch (javax.xml.transform.TransformerException local) {
                          throw new ProcessingException("TransformerException: " + local, local);
                      }
                      consumer.startElement("", "uservalues", "uservalues", attr);
                      if (users != null && users.hasChildNodes() == true) {
                          NodeList childs = users.getChildNodes();
                          for(int i = 0; i < childs.getLength(); i++) {
                              if (childs.item(i).getNodeType() == Node.ELEMENT_NODE)
                                  IncludeXMLConsumer.includeNode(childs.item(i), consumer, consumer);
                          }
                      }
                      consumer.endElement("", "uservalues", "uservalues");
                  }
                  consumer.startElement("", "user", "user", attr);
                  consumer.characters("old".toCharArray(), 0, 3);
                  consumer.endElement("", "user", "user");
                  if (isAdmin == false) {
                      consumer.startElement("", "role", "role", attr);
                      consumer.characters(role.toCharArray(), 0, role.length());
                      consumer.endElement("", "role", "role");
                 }
              }
  
              if (state.equals("erruser") == true) {
                  String role;
                  String id;
  
                  if (isAdmin == false) {
                      SourceParameters pars = this.createParameters(null);
                      id = pars.getParameter("ID", null);
                      role = pars.getParameter("role", null);
                  } else {
                      role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                      id   = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ID);
                  }
                  if (role != null && id != null) {
                      context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);
  
                      // include users
                      DocumentFragment userDF = this.getUsers(role, id);
                      Element          users   = null;
                      try {
                          if (userDF != null) users = (Element)DOMUtil.getSingleNode(userDF, "users/user");
                      } catch (javax.xml.transform.TransformerException local) {
                          throw new ProcessingException("TransformerException: " + local, local);
                      }
                      consumer.startElement("", "uservalues", "uservalues", attr);
                      if (users != null && users.hasChildNodes() == true) {
                          NodeList childs = users.getChildNodes();
                          for(int i = 0; i < childs.getLength(); i++) {
                              if (childs.item(i).getNodeType() == Node.ELEMENT_NODE)
                                  IncludeXMLConsumer.includeNode(childs.item(i), consumer, consumer);
                          }
                      }
                      consumer.endElement("", "uservalues", "uservalues");
                  }
                  consumer.startElement("", "user", "user", attr);
                  consumer.characters("error".toCharArray(), 0, 5);
                  consumer.endElement("", "user", "user");
                  if (isAdmin == false) {
                      consumer.startElement("", "role", "role", attr);
                      consumer.characters(role.toCharArray(), 0, role.length());
                      consumer.endElement("", "role", "role");
                 }
              }
  
              if (state.equals("adduser") == true) {
                  consumer.startElement("", "user", "user", attr);
                  consumer.characters("new".toCharArray(), 0, 3);
                  consumer.endElement("", "user", "user");
              }
  
              if (state.equals("selrole") == true) {
                  String role = this.request.getParameter(AuthenticationManager.REQ_PARAMETER_ROLE);
                  context.setAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);
                  // include users
                  DocumentFragment userDF = this.getUsers(role, null);
                  Node             users   = null;
                  try {
                      if (userDF != null) users = DOMUtil.getSingleNode(userDF, "users");
                  } catch (javax.xml.transform.TransformerException local) {
                      throw new ProcessingException("TransformerException: " + local, local);
                  }
                  IncludeXMLConsumer.includeNode(users, consumer, consumer);
              }
  
              if (isAdmin == true) {
                  // include roles
                  DocumentFragment rolesDF = this.getRoles();
                  Node             roles   = null;
                  try {
                      if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles");
                  } catch (javax.xml.transform.TransformerException local) {
                      throw new ProcessingException("TransformerException: " + local, local);
                  }
                  IncludeXMLConsumer.includeNode(roles, consumer, consumer);
  
                  // include selected role
                  String role = (String)context.getAttribute(AuthenticationManager.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE);
                  if (role != null) {
                      consumer.startElement("", "role", "role", attr);
                      consumer.characters(role.toCharArray(), 0, role.length());
                      consumer.endElement("", "role", "role");
                  }
              }
          } // end synchronized(context)
  
          consumer.endElement("", "configuration", "configuration");
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END showConfiguration");
          }
      }
  
      /**
       * Is the current user authenticated for the given handler?
       */
      public boolean isAuthenticated()
      throws IOException, ProcessingException {
          return this.isAuthenticated(this.handlerName);
      }
  
      /**
       * Is the current user authenticated for the given handler?
       */
      public boolean isAuthenticated(String name)
      throws IOException, ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN isAuthenticated handler=" + name);
          }
          boolean isAuthenticated = true;
  
          // if no handler: authenticated
          if (name != null) {
              isAuthenticated = this.handlerManager.hasUserHandler( name, this.request );
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END isAuthenticated authenticated=" + isAuthenticated);
          }
          return isAuthenticated;
      }
  
      /**
       * Checks authentication and generates a redirect, if not authenticated
       */
      public boolean checkAuthentication(Redirector redirector, boolean loadingResource)
      throws IOException, ProcessingException {
          // synchronized not needed
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN checkAuthentication");
          }
          boolean isAuthenticated = true;
  
          // set the configuration for the handler
          final String newHandlerName = (String)this.request.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME);
          final String newAppName     = (String)this.request.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME);
          if (this.handlerName == null) this.handlerName = "";
          if (this.applicationName == null) this.applicationName = "";
          if (this.handlerName.equals(newHandlerName) == false
              || this.applicationName.equals(newAppName) == false) {
              this.handlerName = newHandlerName;
              this.applicationName = newAppName;
              this.handler = null;
              this.application = null;
  
              if (this.handlerName != null) {
                  this.handler = this.getHandler(this.handlerName);
  
                  if (this.handler == null) {
                      throw new ProcessingException("Handler not found: " + this.handlerName);
                  }
                  if (this.applicationName != null) {
                      this.application = (ApplicationHandler)this.handler.getApplications().get(this.applicationName);
                      if (this.application == null) {
                          throw new ProcessingException("Application not found: " + this.applicationName);
                      }
                  }
              } else {
                  throw new ProcessingException("Handler information not found.");
              }
          } else {
              if (this.handlerName.equals("")) this.handlerName = null;
              if (this.applicationName.equals("")) this.applicationName = null;
          }
  
          if (this.handler != null) {
              isAuthenticated = this.isAuthenticated(this.handlerName);
  
              if (isAuthenticated == false) {
                  // create parameters
                  SourceParameters parameters = handler.getRedirectParameters();
                  if (parameters == null) parameters = new SourceParameters();
                  String resource = this.request.getRequestURI();
                  if (this.request.getQueryString() != null) {
                      resource += '?' + this.request.getQueryString();
                  }
  
                  parameters.setSingleParameterValue("resource", resource);
                  final String redirectURI = handler.getRedirectURI();
                  redirector.globalRedirect(false, SourceUtil.appendParameters(redirectURI, parameters));
              } else {
                  if (loadingResource == true) {
                      // load application data if we are not inside a resource loading of authentication
                      this.checkLoaded((SessionContextImpl)this.getSessionManager().getContext(AuthenticationConstants.SESSION_CONTEXT_NAME),
                                       "/");
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END checkAuthentication authenticated=" + isAuthenticated);
          }
          return isAuthenticated;
      }
  
      /**
       * Get the handler
       */
      private Handler getHandler(String name) {
          // synchronized
          return this.handlerManager.getHandler( name, this.request);
      }
  
      /**
       * Authenticate
       * If the authentication is successful, <code>null</code> is returned.
       * If not an element "failed" is return. If handler specific error
       * information is available this is also returned.
       */
      public DocumentFragment authenticate(String              loginHandlerName,
                                           SourceParameters    parameters)
      throws ProcessingException, IOException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN authenticate handler=" + loginHandlerName +
                                     ", parameters="+parameters);
          }
  
          DocumentFragment authenticationFragment = null;
          boolean          isValid                = false;
  
          Handler myHandler = this.getHandler(loginHandlerName);
          if (this.getLogger().isInfoEnabled() == true) {
              this.getLogger().info("AuthenticationManager: Trying to authenticate using handler '" + loginHandlerName +"'");
          }
          if (myHandler != null) {
              String           exceptionMsg     = null;
  
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("start authentication");
              }
  
              final Resource authenticationResource = myHandler.getAuthenticationResource();
              final String   authenticationResourceName = authenticationResource.getResourceIdentifier();
              final int      authenticationResourceType = authenticationResource.getResourceType();
              final SourceParameters authenticationParameters = authenticationResource.getResourceParameters();
              if (parameters != null) {
                  parameters.add(authenticationParameters);
              } else {
                  parameters = authenticationParameters;
              }
  
              try {
                  if (this.getLogger().isDebugEnabled() == true) {
                      this.getLogger().debug("start invoking auth resource");
                  }
                  authenticationFragment = this.getResourceConnector().loadXML(authenticationResourceType, null,
                                                                               authenticationResourceName, parameters);
                  if (this.getLogger().isDebugEnabled() == true) {
                      this.getLogger().debug("end invoking auth resource");
                  }
              } catch (ProcessingException local) {
                  this.getLogger().error("authenticate", local);
                  exceptionMsg = local.getMessage();
              }
  
              // test if authentication was successful
              if (authenticationFragment != null) {
                  isValid = this.isValidAuthenticationFragment(authenticationFragment);
  
                  if (isValid == true) {
                      if (this.getLogger().isInfoEnabled() == true) {
                          this.getLogger().info("AuthenticationManager: User authenticated using handler '" + myHandler.getName()+"'");
                      }
                      // create session object if necessary, context etc and get it
                      if (this.getLogger().isDebugEnabled() == true) {
                          this.getLogger().debug("creating session");
                      }
                      SessionContext context = this.getAuthenticationSessionContext(true);
                      if (this.getLogger().isDebugEnabled() == true) {
                          this.getLogger().debug("session created");
                      }
  
                      myHandler = this.handlerManager.storeUserHandler(myHandler,
                                                                       this.request);
  
                      synchronized(context) {
                          // add special nodes to the authentication block:
                          // useragent, type and media
                          Element specialElement;
                          Text    specialValue;
                          Element authNode;
  
                          authNode = (Element)authenticationFragment.getFirstChild();
                          specialElement = authenticationFragment.getOwnerDocument().createElementNS(null, "useragent");
                          specialValue = authenticationFragment.getOwnerDocument().createTextNode(request.getHeader("User-Agent"));
                          specialElement.appendChild(specialValue);
                          authNode.appendChild(specialElement);
  
                          specialElement = authenticationFragment.getOwnerDocument().createElementNS(null, "type");
                          specialValue = authenticationFragment.getOwnerDocument().createTextNode("cocoon.authentication");
                          specialElement.appendChild(specialValue);
                          authNode.appendChild(specialElement);
  
                          specialElement = authenticationFragment.getOwnerDocument().createElementNS(null, "media");
                          specialValue = authenticationFragment.getOwnerDocument().createTextNode(this.mediaType);
                          specialElement.appendChild(specialValue);
                          authNode.appendChild(specialElement);
  
                          // store the authentication data in the context
                          context.setXML("/" + myHandler.getName(), authenticationFragment);
  
                          // Now create the return value for this method:
                          // <code>null</code>
                          authenticationFragment = null;
  
                          // And now load applications
                          boolean loaded = true;
                          Iterator applications = myHandler.getApplications().values().iterator();
                          ApplicationHandler appHandler;
  
                          while (applications.hasNext() == true) {
                              appHandler = (ApplicationHandler)applications.next();
                              if (appHandler.getLoadOnDemand() == false) {
                                  this.loadApplicationXML((SessionContextImpl)this.getSessionManager().getContext(AuthenticationConstants.SESSION_CONTEXT_NAME),
                                                          appHandler, "/");
                              } else {
                                  loaded = appHandler.getIsLoaded();
                              }
                          }
                          myHandler.setApplicationsLoaded(loaded);
  
                      } // end sync
                  }
              }
              if (isValid == false) {
                  if (this.getLogger().isInfoEnabled() == true) {
                      this.getLogger().info("AuthenticationManager: Failed authentication using handler '" +  myHandler.getName()+"'");
                  }
                  // get the /authentication/data Node if available
                  Node data = null;
  
                  if (authenticationFragment != null) {
                      data = DOMUtil.getFirstNodeFromPath(authenticationFragment, new String[] {"authentication","data"}, false);
                  }
  
                  // now create the following xml:
                  // <failed/>
                  // if data is available data is included, otherwise:
                  // <data>No information</data>
                  // If exception message contains info, it is included into failed
                  Document       doc = DOMUtil.createDocument();
                  authenticationFragment = doc.createDocumentFragment();
  
                  Element      element = doc.createElementNS(null, "failed");
                  authenticationFragment.appendChild(element);
  
                  if (exceptionMsg != null) {
                      Text text = doc.createTextNode(exceptionMsg);
                      element.appendChild(text);
                  }
  
                  if (data == null) {
                      element = doc.createElementNS(null, "data");
                      authenticationFragment.appendChild(element);
                      Text text = doc.createTextNode("No information");
                      element.appendChild(text);
                  } else {
                      authenticationFragment.appendChild(doc.importNode(data, true));
                  }
  
              }
              if (this.getLogger().isDebugEnabled() == true) {
                  this.getLogger().debug("end authentication");
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END authenticate fragment="+authenticationFragment);
          }
          return authenticationFragment;
      }
  
      /**
       * Check the fragment if it is valid
       */
      private boolean isValidAuthenticationFragment(DocumentFragment authenticationFragment) {
          // calling method is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN isValidAuthenticationFragment fragment=" + authenticationFragment);
          }
          boolean isValid = false;
  
          // authenticationFragment must only have exactly one child with
          // the name authentication
          if (authenticationFragment.hasChildNodes() == true
              && authenticationFragment.getChildNodes().getLength() == 1) {
              Node child = authenticationFragment.getFirstChild();
  
              if (child.getNodeType() == Node.ELEMENT_NODE
                  && child.getNodeName().equals("authentication") == true) {
  
                  // now authentication must have one child ID
                  if (child.hasChildNodes() == true) {
                      NodeList children = child.getChildNodes();
                      boolean  found = false;
                      int      i = 0;
                      int      l = children.getLength();
  
                      while (found == false && i < l) {
                          child = children.item(i);
                          if (child.getNodeType() == Node.ELEMENT_NODE
                              && child.getNodeName().equals("ID") == true) {
                              found = true;
                          } else {
                              i++;
                          }
                      }
  
                      // now the last check: ID must have a TEXT child
                      if (found == true) {
                          child.normalize(); // join text nodes
                          if (child.hasChildNodes() == true &&
                              child.getChildNodes().getLength() == 1 &&
                              child.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE) {
                              String value = child.getChildNodes().item(0).getNodeValue().trim();
                              if (value.length() > 0) isValid = true;
                          }
                      }
                  }
  
              }
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END isValidAuthenticationFragment valid="+isValid);
          }
          return isValid;
      }
  
      /**
       * Get the private SessionContext
       */
      private SessionContext getAuthenticationSessionContext(boolean create)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getAuthenticationSessionContext create=" + create);
          }
          SessionContext context = null;
  
          Session session = this.getSessionManager().getSession(create);
          if (session != null) {
              synchronized(session) {
                  context = (SessionContext)session.getAttribute(AuthenticationConstants.SESSION_ATTRIBUTE_CONTEXT_NAME);
                  if (context == null && create == true) {
                      context = new SimpleSessionContext();
                      context.setup(AuthenticationConstants.SESSION_CONTEXT_NAME, null, null);
                      session.setAttribute(AuthenticationConstants.SESSION_ATTRIBUTE_CONTEXT_NAME, context);
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getAuthenticationSessionContext context=" + context);
          }
          return context;
      }
  
      /**
       * Logout from the given handler and eventually terminate session.
       * @param logoutHandlerName The authentication handler
       * @param mode              This mode defines how the termination of
       *                           the session is handled.
       */
      public void logout(String  logoutHandlerName,
                          int     mode)
      throws ProcessingException {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() ) {
              this.getLogger().debug("BEGIN logout handler=" + logoutHandlerName +
                                     ", mode="+mode);
          }
          SessionContext context = this.getAuthenticationSessionContext(false);
  
          if (context != null && logoutHandlerName != null) {
  
              // remove context
              context.removeXML(logoutHandlerName);
              // FIXME (CZ): The sessionContextImpl should not be null, but
              //             it is sometimes. Why?
              SessionContextImpl sessionContextImpl = (SessionContextImpl)
                          (this.getSessionManager().getContext(AuthenticationConstants.SESSION_CONTEXT_NAME));
              if (sessionContextImpl != null) {
                  sessionContextImpl.cleanParametersCache(logoutHandlerName);
              } else if (this.getLogger().isWarnEnabled()) {
                  this.getLogger().warn("AuthenticationManager:logout() - sessionContextImpl is null");
              }
              Handler logoutHandler = (Handler)this.getHandler(logoutHandlerName);
  
              final List handlerContexts = logoutHandler.getHandlerContexts();
              final Iterator iter = handlerContexts.iterator();
              while ( iter.hasNext() ) {
                  final SessionContext deleteContext = (SessionContext) iter.next();
                  this.getSessionManager().deleteContext( deleteContext.getName() );
              }
              logoutHandler.clearHandlerContexts();
              this.handlerManager.removeUserHandler( logoutHandler, this.request );
              if (logoutHandlerName.equals(this.handlerName)) {
                  this.handlerName = null;
                  this.handler = null;
                  this.applicationName = null;
                  this.application = null;
              }
          }
  
          if ( mode == AuthenticationConstants.LOGOUT_MODE_IMMEDIATELY ) {
              this.getSessionManager().terminateSession(true);
          } else if (!this.handlerManager.hasUserHandler( this.request )) {
              if (mode == AuthenticationConstants.LOGOUT_MODE_IF_UNUSED) {
                  this.getSessionManager().terminateSession(false);
              } else {
                  this.getSessionManager().terminateSession(true);
              }
          }
  
          if (this.getLogger().isDebugEnabled() ) {
              this.getLogger().debug("END logout");
          }
      }
  
      /**
       * Get the configuration if available
       */
      public Configuration getModuleConfiguration(String name)
      throws ProcessingException  {
          // synchronized not needed
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getModuleConfiguration module="+name);
          }
          Configuration conf = null;
  
          if (this.handler != null && this.application != null) {
              conf = this.application.getConfiguration(name);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getModuleConfiguration conf="+conf);
          }
          return conf;
      }
  
      /**
       * Create Application Context.
       * This context is destroyed when the user logs out of the handler
       */
      public SessionContext createHandlerContext(String name,
                                                 String loadURI,
                                                 String saveURI)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN createHandlerContext name="+name);
          }
  
          SessionContext context = null;
  
          if (this.handler != null) {
  
              final Session session = this.getSessionManager().getSession(false);
              synchronized(session) {
  
                  try {
                      // create new context
                      context = this.getSessionManager().createContext(name, loadURI, saveURI);
                      this.handler.addHandlerContext( context );
                  } catch (IOException ioe) {
                      throw new ProcessingException("Unable to create session context.", ioe);
                  } catch (SAXException saxe) {
                      throw new ProcessingException("Unable to create session context.", saxe);
                  }
  
              } // end synchronized
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END createHandlerContext context="+context);
          }
          return context;
      }
  
      /**
       * Get all users in a document fragment with the following children:
       * <users>
       *     <user>
       *         <ID>...</ID>
       *         <role>...</role> <!-- optional -->
       *         <data>
       *         ...
       *         </data>
       *     </user>
       *     ....
       * </users>
       * The document fragment might contain further nodes at the root!
       * If <code>role</code> is <code>null</code> all users are fetched,
       * otherwise only the users for this role.
       * If also ID is not null only the single user is fetched.
       */
      public DocumentFragment getUsers(String role, String ID)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getUsers role="+role+", ID="+ID);
          }
          DocumentFragment frag = null;
  
          if (this.handler != null && this.handler.getLoadUsersResource() != null) {
              final Resource loadUsersResource = this.handler.getLoadUsersResource();
              final SourceParameters loadParameters = loadUsersResource.getResourceParameters();
              SourceParameters parameters = (loadParameters == null) ? new SourceParameters()
                                                                       : (SourceParameters)loadParameters.clone();
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              if (ID != null) {
                  parameters.setSingleParameterValue("type", "user");
                  parameters.setSingleParameterValue("ID", ID);
              } else {
                  parameters.setSingleParameterValue("type", "users");
              }
              if (role != null) parameters.setSingleParameterValue("role", role);
              frag = this.getResourceConnector().loadXML(loadUsersResource.getResourceType(), null,
                                                         loadUsersResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getUsers fragment="+(frag == null ? "null" : XMLUtils.serializeNodeToXML(frag)));
          }
          return frag;
      }
  
      /**
       * Get all roles in a document fragment with the following children:
       * <roles>
       *     <role>...</role>
       *     ....
       * </roles>
       * The document fragment might contain further nodes at the root!
       */
      public DocumentFragment getRoles()
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getRoles");
          }
          DocumentFragment frag = null;
  
          if (this.handler != null && this.handler.getLoadRolesResource() != null) {
              final Resource loadRolesResource = this.handler.getLoadRolesResource();
              final SourceParameters loadParameters = loadRolesResource.getResourceParameters();
              SourceParameters parameters = (loadParameters == null) ? new SourceParameters()
                                                                       : (SourceParameters)loadParameters.clone();
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              parameters.setSingleParameterValue("type", "roles");
              frag = this.getResourceConnector().loadXML(loadRolesResource.getResourceType(), null,
                                                         loadRolesResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getRoles fragment="+frag);
          }
          return frag;
      }
  
      /**
       * Add a role
       */
      private void addRole(String name, SourceParameters parameters)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN addRole role="+name+", parameters="+parameters);
          }
          if (this.handler != null && this.handler.getNewRoleResource() != null) {
              final Resource newRoleResource = this.handler.getNewRoleResource();
              final SourceParameters handlerPars = newRoleResource.getResourceParameters();
              if (parameters == null) parameters = new SourceParameters();
              parameters.add(handlerPars);
  
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              parameters.setSingleParameterValue("type", "role");
              parameters.setSingleParameterValue("role", name);
  
              this.getResourceConnector().loadXML(newRoleResource.getResourceType(), null,
                                                  newRoleResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END addRole");
          }
      }
  
      /**
       * Add a user.
       * @return If a user with ID already exists <code>false</code> is returned.
       */
      public boolean addUser(String role, String ID, SourceParameters parameters)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN addUser role="+role+", ID="+ID+", parameters="+parameters);
          }
          boolean result = false;
  
          if (this.handler != null
              && this.handler.getNewUserResource() != null
              && ID != null
              && ID.trim().length() > 0) {
              // first test if a user with this ID already exists
              DocumentFragment user = this.getUsers(null, null);
              Node node = null;
              if (user != null) {
                  try {
                      node = DOMUtil.getSingleNode(user, "users/user/ID[text()='"+ID+"']");
                  } catch (javax.xml.transform.TransformerException local) {
                      throw new ProcessingException("Transformer exception: " + local, local);
                  }
              }
              if (user == null || node == null) {
                  final Resource newUserResource = this.handler.getNewUserResource();
                  final SourceParameters newUsersPars = newUserResource.getResourceParameters();
                  if (parameters == null) parameters = new SourceParameters();
                  parameters.add(newUsersPars);
  
                  if (this.applicationName != null)
                      parameters.setSingleParameterValue("application", this.applicationName);
                  parameters.setSingleParameterValue("type", "user");
                  parameters.setSingleParameterValue("role", role);
                  parameters.setSingleParameterValue("ID", ID);
  
                  this.getResourceConnector().loadXML(newUserResource.getResourceType(), null,
                                                      newUserResource.getResourceIdentifier(), parameters);
                  result = true;
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END addUser success="+result);
          }
          return result;
      }
  
      /**
       * Delete a role
       */
      private void deleteRole(String name, SourceParameters parameters)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN deleteRole role="+name+", parameters="+parameters);
          }
          if (this.handler != null && this.handler.getDeleteRoleResource() != null) {
              final Resource deleteRoleResource = this.handler.getDeleteRoleResource();
              final SourceParameters handlerPars = deleteRoleResource.getResourceParameters();
              if (parameters == null) parameters = new SourceParameters();
              parameters.add(handlerPars);
  
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              parameters.setSingleParameterValue("type", "role");
              parameters.setSingleParameterValue("role", name);
  
              this.getResourceConnector().loadXML(deleteRoleResource.getResourceType(), null,
                                                  deleteRoleResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END deleteRole");
          }
      }
  
      /**
       * Delete a user
       */
      private void deleteUser(String role, String name, SourceParameters parameters)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN deleteUser role="+role+", ID="+name+", parameters="+parameters);
          }
          if (this.handler != null && this.handler.getDeleteUserResource() != null) {
              final Resource deleteUserResource = this.handler.getDeleteUserResource();
              final SourceParameters handlerPars = deleteUserResource.getResourceParameters();
              if (parameters == null) parameters = new SourceParameters();
              parameters.add(handlerPars);
  
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              parameters.setSingleParameterValue("type", "user");
              parameters.setSingleParameterValue("role", role);
              parameters.setSingleParameterValue("ID", name);
  
              this.getResourceConnector().loadXML(deleteUserResource.getResourceType(), null,
                                                  deleteUserResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END deleteUser");
          }
      }
  
      /**
       * Change a user
       */
      private void changeUser(String role, String name, SourceParameters parameters)
      throws ProcessingException {
          // calling method is syned
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN changeUser role="+role+", ID="+name+", parameters="+parameters);
          }
          if (this.handler != null && this.handler.getChangeUserResource() != null) {
              final Resource changeUserResource = this.handler.getChangeUserResource();
              final SourceParameters handlerPars = changeUserResource.getResourceParameters();
              if (parameters == null) parameters = new SourceParameters();
              parameters.add(handlerPars);
  
              if (this.applicationName != null)
                  parameters.setSingleParameterValue("application", this.applicationName);
              parameters.setSingleParameterValue("type", "user");
              parameters.setSingleParameterValue("role", role);
              parameters.setSingleParameterValue("ID", name);
  
              this.getResourceConnector().loadXML(changeUserResource.getResourceType(), null,
                                                  changeUserResource.getResourceIdentifier(), parameters);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END changeUser");
          }
      }
  
      /**
       * Load XML of an application
       */
      private void loadApplicationXML(SessionContextImpl context,
                                      ApplicationHandler appHandler,
                                      String path)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN loadApplicationXML application=" + appHandler.getName() + ", path="+path);
          }
          Object o = this.getSessionManager().getSession(true);
          synchronized(o) {
  
              if (appHandler.getIsLoaded() == false) {
  
                  final Resource loadResource     = appHandler.getLoadResource();
                  final String   loadResourceName = loadResource.getResourceIdentifier();
                  final int      loadResourceType = loadResource.getResourceType();
                  SourceParameters parameters = loadResource.getResourceParameters();
                  if (parameters != null) parameters = (SourceParameters)parameters.clone();
                  parameters = this.createParameters(parameters,
                                                     appHandler.getHandler().getName(),
                                                     path,
                                                     appHandler.getName());
                  DocumentFragment fragment;
  
                  fragment = this.getResourceConnector().loadXML(loadResourceType, null,
                                                                 loadResourceName, parameters);
  
                  appHandler.setIsLoaded(true);
  
                  context.setApplicationXML(appHandler.getHandler().getName(),
                                            appHandler.getName(),
                                            path,
                                            fragment);
  
                  // now test handler if all applications are loaded
                  Iterator applications = appHandler.getHandler().getApplications().values().iterator();
                  boolean     allLoaded = true;
                  while (allLoaded == true && applications.hasNext() == true) {
                      allLoaded = ((ApplicationHandler)applications.next()).getIsLoaded();
                  }
                  appHandler.getHandler().setApplicationsLoaded(allLoaded);
              }
  
          } // end synchronized
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END loadApplicationXML");
          }
      }
  
      /**
       * Check if application for path is loaded
       */
      private void checkLoaded(SessionContextImpl context,
                               String             path)
      throws ProcessingException {
          // synchronized as loadApplicationXML is synced
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN checkLoaded path="+path);
          }
          if (path.equals("/") == true || path.startsWith("/application") == true) {
              if (this.application != null) {
                  this.loadApplicationXML(context, this.application, "/");
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END checkLoaded");
          }
      }
  
      /**
       * Build parameters for loading and saving of application data
       */
      public SourceParameters createParameters(String path)
      throws ProcessingException {
          // synchronized
          if (this.handler == null) {
              return new SourceParameters();
          }
          if (path == null) {
              SessionContext context = this.getAuthenticationSessionContext(false);
              SourceParameters pars = (SourceParameters)context.getAttribute("cachedparameters_" + this.handler.getName());
              if (pars == null) {
                   pars = this.createParameters(null, this.handlerName, path, this.applicationName);
                   context.setAttribute("cachedparameters_" + this.handler.getName(), pars);
              }
              return pars;
          }
          return this.createParameters(null, this.handlerName, path, this.applicationName);
      }
  
      protected static final Map EMPTY_MAP = Collections.unmodifiableMap(new TreeMap());
  
      /**
       * Create a map for the actions
       * The result is cached!
       */
      public Map createMap()
      throws ProcessingException {
          if (this.handler == null) {
              // this is only a fallback
              return EMPTY_MAP;
          }
          SessionContext context = this.getAuthenticationSessionContext(false);
          Map map = (Map)context.getAttribute("cachedmap_" + this.handler.getName());
          if (map == null) {
              map = new HashMap();
              Parameters pars = this.createParameters(null).getFirstParameters();
              String[] names = pars.getNames();
              if (names != null) {
                  String key;
                  String value;
                  for(int i=0;i<names.length;i++) {
                      key = names[i];
                      value = pars.getParameter(key, null);
                      if (value != null) map.put(key, value);
                  }
              }
              context.setAttribute("cachedmap_" + this.handler.getName(), map);
          }
          return map;
      }
  
      /**
       * Build parameters for loading and saving of application data
       */
      private SourceParameters createParameters(SourceParameters parameters,
                                                  String             myHandler,
                                                  String             path,
                                                  String             appName)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN createParameters handler=" + myHandler +
                                ", path="+path+ ", application=" + appName);
          }
  
          SessionContextImpl context;
          context = (SessionContextImpl)contextProvider.getSessionContext(AuthenticationConstants.SESSION_CONTEXT_NAME,
                                                        this.objectModel,
                                                        this.resolver,
                                                        this.manager);
          parameters = context.createParameters(parameters, myHandler, path, appName);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END createParameters parameters="+parameters);
          }
          return parameters;
      }
  
  }
  
  
  /**
   * This class stores the media type configuration
   */
  final class MediaType {
  
      String name;
      String useragent;
  
      MediaType(String name, String useragent) {
          this.name = name;
          this.useragent = useragent;
      }
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/xml/NodeListImpl.java
  
  Index: NodeListImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.xml;
  
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  /**
   *  Implementation of the <code>NodeList</code> interface.<P>
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: NodeListImpl.java,v 1.1 2002/04/17 08:43:59 cziegeler Exp $
  */
  public class NodeListImpl implements NodeList {
  
      private Node[] nodelist;
  
      /**
       * Construct a NodeList by copying.
       */
      public NodeListImpl(NodeList list) {
        if (list == null || list.getLength() == 0) {
          nodelist = null;
        } else {
          nodelist = new Node[list.getLength()];
          for(int i = 0; i < list.getLength(); i++) {
            nodelist[i] = list.item(i).cloneNode(true);
          }
        }
      }
  
      /**
       * Constructor
       */
      public NodeListImpl(Node[] nodes) {
          this.nodelist = nodes;
      }
  
      /**
       * Constructor
       */
      public NodeListImpl() {}
  
      /**
       * Construct a NodeList by copying.
       */
      public NodeListImpl(DocumentFragment fragment, String rootName) {
        if (fragment != null) {
          Element root = fragment.getOwnerDocument().createElementNS(null, rootName);
          Node    current;
          while (fragment.hasChildNodes() == true) {
            current = fragment.getFirstChild();
            fragment.removeChild(current);
            root.appendChild(current);
          }
          nodelist = new Node[1];
          nodelist[0] = root;
        }
      }
  
      /**
       * Add a node to list
       */
      public void addNode(Node node) {
          if (this.nodelist == null) {
              this.nodelist = new Node[1];
              this.nodelist[0] = node;
          } else {
              Node[] copy = new Node[this.nodelist.length+1];
              System.arraycopy(this.nodelist, 0, copy, 0, this.nodelist.length);
              copy[copy.length-1] = node;
              this.nodelist = copy;
          }
      }
  
      /**
       *  Returns the <code>index</code> th item in the collection. If
       * <code>index</code> is greater than or equal to the number of nodes in
       * the list, this returns <code>null</code> .
       * @param index  Index into the collection.
       * @return  The node at the <code>index</code> th position in the
       *   <code>NodeList</code> , or <code>null</code> if that is not a valid
       *   index.
       */
      public Node item(int index) {
        if (nodelist == null || index >= nodelist.length) {
          return null;
        } else {
          return nodelist[index];
        }
      }
  
      /**
       *  The number of nodes in the list. The range of valid child node indices
       * is 0 to <code>length-1</code> inclusive.
       */
      public int getLength() {
        return (nodelist == null ? 0 : nodelist.length);
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/xml/XMLUtil.java
  
  Index: XMLUtil.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.xml;
  
  import java.io.*;
  import java.util.Properties;
  
  import org.apache.avalon.excalibur.xml.Parser;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.xml.dom.DOMBuilder;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.xpath.XPathAPI;
  import org.w3c.dom.*;
  import org.w3c.dom.traversal.NodeIterator;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.helpers.AttributesImpl;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  import javax.xml.parsers.SAXParser;
  import javax.xml.parsers.SAXParserFactory;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerException;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.OutputKeys;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.sax.TransformerHandler;
  import javax.xml.transform.dom.DOMSource;
  
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  
  /**
   *  This class is an utitity class for miscellanous XML functions, like creating
   *  DOM documents, searching nodes via XPath and changing nodes using XPath.
   *
   *  This class should be separated into several other ones. The XPath support should
   *  go to the XPath component etc. So this class will not be supported anymore...
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: XMLUtil.java,v 1.7 2002/08/30 08:38:44 stephan Exp $
  */
  public final class XMLUtil {
  
      /*
       * As these methods are invoked often they do not trace anything for
       * performances reasons. Also they don't follow the guidelines
       * for the same reason.
      */
  
  
      /**
       * Convert umlaute to entities
       */
      public static String encode(String value) {
          StringBuffer buffer = new StringBuffer(value);
          for(int i = 0; i < buffer.length(); i++) {
              if (buffer.charAt(i) > 127) {
                  buffer.replace(i, i+1, "__"+((int)buffer.charAt(i))+";");
              }
          }
          return buffer.toString();
      }
  
      /**
       * Convert entities to umlaute
       */
      public static String decode(String value) {
          StringBuffer buffer = new StringBuffer(value);
          int pos;
          boolean found;
          for(int i = 0; i < buffer.length(); i++) {
              if (buffer.charAt(i) == '_' &&
                  buffer.charAt(i+1) == '_') {
                  pos = i + 2;
                  found = false;
                  while (buffer.charAt(pos) >= '0'
                         && buffer.charAt(pos) <= '9') {
                      found = true;
                      pos++;
                  }
                  if (found == true
                      && pos > i + 2
                      && buffer.charAt(pos) == ';') {
                      int ent = new Integer(buffer.substring(i+2, pos)).intValue();
                      buffer.replace(i, pos+1, ""+ (char)ent);
                  }
              }
          }
          return buffer.toString();
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/conf/session-tran.xmap
  
  Index: session-tran.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/transformers"
        unless="transformer[@name='session']">
  
      <map:transformer name="session"
                       src="org.apache.cocoon.webapps.session.transformation.SessionTransformer"
                       pool-max="32" pool-min="8" pool-grow="4"/>
      <map:transformer name="session-pre"
                       src="org.apache.cocoon.webapps.session.transformation.SessionPreTransformer"
                       pool-max="32" pool-min="8" pool-grow="4"/>
      <map:transformer name="session-post"
                       src="org.apache.cocoon.webapps.session.transformation.SessionPostTransformer"
                       pool-max="32" pool-min="8" pool-grow="4"/>
  </xmap>
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/conf/session-act.xmap
  
  Index: session-act.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/actions"
        unless="action[@name='session']">
  
      <map:action name="session"
                  src="org.apache.cocoon.webapps.session.acting.SessionAction"/>
  
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/conf/session.xconf
  
  Index: session.xconf
  ===================================================================
  <?xml version="1.0"?>
  
  <xconf xpath="/cocoon" unless="session-manager">
  
    <session-manager logger="core.session-manager"
                     pool-max="32" pool-min="8" pool-grow="4"/>
  
  </xconf>
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/conf/session.xroles
  
  Index: session.xroles
  ===================================================================
  <?xml version="1.0"?>
  
  <xroles xpath="/role-list" unless="role [@name='org.apache.cocoon.webapps.session.components.SessionManager']">
  
    <role name="org.apache.cocoon.webapps.session.components.SessionManager"
          shorthand="session-manager"
          default-class="org.apache.cocoon.webapps.session.components.SessionManager"/>
  
    <role name="org.apache.cocoon.webapps.session.connector.ResourceConnector"
          shorthand="resource-connector"
          default-class="org.apache.cocoon.webapps.session.connector.ResourceConnectorImpl"/>
  
  </xroles>
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector/XMLSaver.java
  
  Index: XMLSaver.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.connector;
  
  import java.util.Map;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.w3c.dom.DocumentFragment;
  
  import org.apache.cocoon.ProcessingException;
  
  /**
   * Interface for saving xml - NOT USED YET
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: XMLSaver.java,v 1.2 2002/04/19 11:02:58 cziegeler Exp $
  */
  public interface XMLSaver {
  
      /**
       * Save a DocumentFragment
       */
      void save(DocumentFragment   fragment,
                Map                session,
                SourceParameters parameter)
      throws ProcessingException;
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector/ResourceConnector.java
  
  Index: ResourceConnector.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.connector;
  
  import java.io.IOException;
  
  import org.w3c.dom.DocumentFragment;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  
  /**
   *  The Component for loading and saving xml to external resources.
   *
   *  An external resource is specified by a type and an identifier. The type
   *  gives the connection information (file, http etc) and the identifier
   *  identifies the resource itself (filename, http-address etc).
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ResourceConnector.java,v 1.4 2002/05/21 14:14:51 cziegeler Exp $
  */
  public interface ResourceConnector
  extends Component {
  
      /** Role name */
      static public final String ROLE = ResourceConnector.class.getName();
  
      /** No type information specified. */
      static public final int RESOURCE_TYPE_NONE  = 0;
  
      /**
       *  Resource is an URI.
       *  The resource is specified by an uri, local or remote. If it is a
       *  remote resource the http protocol is used. For local resources the
       *  internal pipelines are invoked.
       *  The <code>typeParameter</code> "method" specifies the http method (POST,
       *  GET etc) - standard is POST if parameters are used, without parameters
       *  it is GET.
       *  URLRewriting can be turned on by specifying the parameters defined
       *  for the <code>URLRewriter</code>.
       *  If an URI is saved (e.g. saveXML) this is the same as loading from
       *  this URI and specifying a resource parameter named "content" with
       *  the document fragment as a string.
       */
      static public final int RESOURCE_TYPE_URI   = 1;
      /**
       * Resource is a class.
       * The class must conform to the XMLLoader or the XMLSaver interface.
       */
      static public final int RESOURCE_TYPE_CLASS = 2;
      /**
       * Resource is a file.
       */
      static public final int RESOURCE_TYPE_FILE  = 3;
  
      /**
       * Load an XML Fragment from a resource.
       *
       * @param resourceType        The type of the connection.
       * @param typeParameters      Connection Parameters.
       * @param resourceIdentifier  The resource name (filename, http address etc)
       * @param resourceParameters  Parameters for the resource.
       *
       * @return The loaded data.
       */
      public DocumentFragment loadXML(int                resourceType,
                                      Parameters         typeParameters,
                                      String             resourceIdentifier,
                                      SourceParameters   resourceParameters)
      throws ProcessingException;
  
      /**
       * Save an XML Fragment to a resource.
       *
       * @param resourceType        The type of the connection.
       * @param typeParameters      Connection Parameters.
       * @param resourceIdentifier  The resource name (filename, http address etc)
       * @param resourceParameters  Parameters for the resource.
       * @param fragment            The data to be saved.
       */
      public void saveXML(int                resourceType,
                          Parameters         typeParameters,
                          String             resourceIdentifier,
                          SourceParameters   resourceParameters,
                          DocumentFragment   fragment)
      throws ProcessingException;
  
      /**
       * Stream an XML resource.
       * This is like loading the resource and then streaming it, but without
       * the Resource->SAX->DOM->SAX transformation, its simply: Resource->SAX
       * All SAX events are send except of the startDocument() and
       * endDocument() event.
       *
       * @param resourceType        The type of the connection.
       * @param typeParameters      Connection Parameters.
       * @param resourceIdentifier  The resource name (filename, http address etc)
       * @param resourceParameters  Parameters for the resource.
       * @param contentHandler      The SAX ContentHandler receiving the events.
       * @param lexicalHandler      The SAX LexicalHandler receiving the events.
       */
      public void streamXML(int                resourceType,
                            Parameters         typeParameters,
                            String             resourceIdentifier,
                            SourceParameters   resourceParameters,
                            ContentHandler     contentHandler,
                            LexicalHandler     lexicalHandler)
      throws ProcessingException;
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector/ResourceConnectorImpl.java
  
  Index: ResourceConnectorImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.connector;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  import org.apache.avalon.excalibur.pool.Recyclable;
  import org.apache.excalibur.source.Source;
  import org.apache.excalibur.source.SourceException;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.excalibur.source.SourceUtil;
  import org.apache.excalibur.source.impl.URLSource;
  import org.apache.avalon.excalibur.xml.Parser;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentSelector;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.activity.Disposable;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.Processor;
  import org.apache.cocoon.ResourceNotFoundException;
  import org.apache.cocoon.components.RequestLifecycleComponent;
  import org.apache.cocoon.components.source.URLRewriter;
  import org.apache.cocoon.environment.Context;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.dom.DOMBuilder;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.XMLUtils;
  
  import org.w3c.dom.*;
  
  import org.xml.sax.*;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.helpers.*;
  
  /**
   * The Component for loading and saving xml to external resource connectors.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ResourceConnectorImpl.java,v 1.7 2002/09/25 11:45:34 cziegeler Exp $
  */
  public final class ResourceConnectorImpl extends AbstractLogEnabled
      implements Recyclable, ResourceConnector,
                 Composable, RequestLifecycleComponent {
  
      /** The <code>ComponentManager</code> */
      protected ComponentManager manager;
  
      /** Empty attributes */
      protected Attributes emptyAttributes = new AttributesImpl();
  
      protected Map objectModel;
  
      protected SourceResolver resolver;
  
      /**
       * Composer
       */
      public void compose(ComponentManager manager)
      throws ComponentException {
          this.manager = manager;
      }
  
      /**
       * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
       * used to process the request.
       *  This method is automatically called for each request. Do not invoke
       *  this method by hand.
       */
      public void setup(SourceResolver resolver, Map objectModel)
      throws ProcessingException, SAXException, IOException {
          this.objectModel = objectModel;
          this.resolver = resolver;
      }
  
      /**
       * Recycle
       */
      public void recycle() {
          this.objectModel = null;
          this.resolver = null;
      }
  
      private static String[] outputKeys = new String[] {
          javax.xml.transform.OutputKeys.CDATA_SECTION_ELEMENTS,
          javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC,
          javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM,
          javax.xml.transform.OutputKeys.ENCODING,
          javax.xml.transform.OutputKeys.INDENT,
          javax.xml.transform.OutputKeys.MEDIA_TYPE,
          javax.xml.transform.OutputKeys.METHOD,
          javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION,
          javax.xml.transform.OutputKeys.STANDALONE,
          javax.xml.transform.OutputKeys.VERSION};
  
      /**
       * Set OutputKeys from parameters
       */
      private void setOutputKeys(Properties properties, Parameters parameters) {
          if (properties != null && parameters != null) {
              for(int i = 0; i < outputKeys.length; i++) {
                  final String value = parameters.getParameter(outputKeys[i], null);
                  if (value != null) {
                      properties.setProperty(outputKeys[i], value);
                  }
              }
          }
      }
  
      /**
       * Load XML
       */
      private DocumentFragment loadXMLFromURI(Parameters        typeParameters,
                                             String             uri,
                                             SourceParameters resourceParameters)
      throws IOException, SAXException, SourceException, ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN loadXMLFromURI uri=" + uri +
                                ", typeParams="+typeParameters+
                                ", parameters="+resourceParameters);
          }
          if (uri == null || uri.trim().length() == 0) {
              throw new IllegalArgumentException("loadXMLFromURI: URI is required");
          }
  
          long startTime = System.currentTimeMillis();
  
          DocumentFragment recordedDocFrag = null;
          DOMBuilder       builder;
  
          builder = new DOMBuilder();
          builder.startDocument();
          builder.startElement("", "cocoon", "cocoon", this.emptyAttributes);
  
          IncludeXMLConsumer filter;
          // Test for url rewriting
          if (typeParameters != null
              && typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null) != null) {
              XMLConsumer consumer = new URLRewriter(typeParameters,
                                                     builder,
                                                     builder);
              filter = new IncludeXMLConsumer(consumer, consumer);
          } else {
              filter = new IncludeXMLConsumer(builder, builder);
          }
          Source input = null;
          try {
              input = org.apache.cocoon.components.source.SourceUtil.getSource(uri, typeParameters, resourceParameters, this.resolver, this.objectModel);
  
              if (input != null) {
                  this.resolver.toSAX(input, filter);
              }
          } finally {
              this.resolver.release(input);
              input = null;
          }
  
          builder.endElement("", "cocoon", "cocoon");
          builder.endDocument();
  
          // Create Document Fragment
          final Document doc = builder.getDocument();
          recordedDocFrag = doc.createDocumentFragment();
          final Node root = doc.getDocumentElement();
          Node child;
          while (root.hasChildNodes() == true) {
              child = root.getFirstChild();
              child.normalize();
              root.removeChild(child);
              recordedDocFrag.appendChild(child);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END loadXMLFromURI fragment="+(recordedDocFrag == null ? "null" : XMLUtils.serializeNodeToXML(recordedDocFrag)));
          }
          return recordedDocFrag;
      }
  
      /**
       * Save XML to an URI. The fragment is passed to the resource as the value
       * of the parameter "content".
       */
      private void saveXMLToURI(Parameters        typeParameters,
                                String             uri,
                                SourceParameters resourceParameters,
                                DocumentFragment   fragment)
      throws IOException, SAXException, SourceException, ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN saveXMLToURI fragment="+(fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
                                ", typeParams="+typeParameters+
                                ", uri=" + uri +
                                ", parameters="+resourceParameters);
          }
          if (uri == null || uri.trim().length() == 0) {
              throw new IllegalArgumentException("saveXMLToURI: URI is required");
          }
  
          Properties format = XMLUtils.defaultSerializeToXMLFormat(true);
          this.setOutputKeys(format, typeParameters);
          String content = XMLUtils.serializeNode(fragment, format);
          if (resourceParameters == null) {
              resourceParameters = new SourceParameters();
          } else {
              resourceParameters = (SourceParameters)resourceParameters.clone();
          }
          resourceParameters.setSingleParameterValue("content", content);
  
          // The trick here is that we do a simple loadXML and ignore the result
          this.loadXMLFromURI(typeParameters, uri, resourceParameters);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END saveXMLToURI");
          }
      }
  
      /**
       * Load XML by using an XMLLoader
       */
      private DocumentFragment loadXMLFromClass(Parameters         typeParameters,
                                               String             className,
                                               SourceParameters resourceParameters)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN loadXMLFromClass class=" + className+
                                ", typeParams="+typeParameters+
                                ", parameters="+resourceParameters);
          }
          DocumentFragment frag;
  
          try {
              Class loaderClass = Class.forName(className);
              XMLLoader loader = (XMLLoader)loaderClass.newInstance();
  
              frag = loader.load(this.objectModel, resourceParameters);
          } catch (ClassNotFoundException cnfException) {
              throw new ProcessingException("loadXMLFromClass: Class not found: " + className, cnfException);
          } catch (IllegalAccessException iaException) {
              throw new ProcessingException("loadXMLFromClass: Illegal Access: " + className, iaException);
          } catch (InstantiationException iException) {
              throw new ProcessingException("loadXMLFromClass: Instantion exception: " + className, iException);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END loadXMLFromClass fragment="+(frag == null ? "null" : XMLUtils.serializeNodeToXML(frag)));
          }
          return frag;
      }
  
      /**
       * Save XML by using an XMLSaver
       */
      private void saveXMLToClass(Parameters         typeParameters,
                                 String             className,
                                 SourceParameters resourceParameters,
                                 DocumentFragment   fragment)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN saveXMLToClass fragment="+(fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
                                ", typeParams="+typeParameters+
                                ", class=" + className+
                                ", params="+resourceParameters);
          }
          try {
              Class saverClass = Class.forName(className);
              XMLSaver saver = (XMLSaver)saverClass.newInstance();
  
              saver.save(fragment, this.objectModel, resourceParameters);
          } catch (ClassNotFoundException cnfException) {
              throw new ProcessingException("saveXMLToClass: Class not found: " + className, cnfException);
          } catch (IllegalAccessException iaException) {
              throw new ProcessingException("saveXMLToClass: Illegal Access: " + className, iaException);
          } catch (InstantiationException iException) {
              throw new ProcessingException("saveXMLToClass: Instantion exception: " + className, iException);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END saveXMLToClass");
          }
      }
  
      /**
       * Load XML from a file
       */
      private DocumentFragment loadXMLFromFile(Parameters         typeParameters,
                                              String             fileName,
                                              SourceParameters resourceParameters)
      throws ProcessingException, IOException, SourceException, SAXException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN loadXMLFromFile fileName=" + fileName+
                                ", typeParams="+typeParameters+
                                ", parameters="+resourceParameters);
          }
          DocumentFragment frag = null;
  
          long startTime = System.currentTimeMillis();
  
          Source input = null;
          try {
              input = this.resolver.resolveURI(fileName);
  
              DOMBuilder builder = new DOMBuilder();
              builder.startDocument();
              builder.startElement("", "cocoon", "cocoon", this.emptyAttributes);
  
              IncludeXMLConsumer filter = new IncludeXMLConsumer(builder, builder);
              this.resolver.toSAX( input, filter );
  
              builder.endElement("", "cocoon", "cocoon");
              builder.endDocument();
  
              // Create Document Fragment
              final Document doc = builder.getDocument();
              frag = doc.createDocumentFragment();
              final Node root = doc.getDocumentElement();
              Node child;
              while (root.hasChildNodes() == true) {
                  child = root.getFirstChild();
                  child.normalize();
                  root.removeChild(child);
                  frag.appendChild(child);
              }
          } finally {
              this.resolver.release(input);
              input = null;
          }
  
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END loadXMLFromFile fragment="+(frag == null ? "null" : XMLUtils.serializeNodeToXML(frag)));
          }
          return frag;
      }
  
      /**
       * Save XML to a file
       */
      private void saveXMLToFile(Parameters         typeParameters,
                                String             fileName,
                                SourceParameters resourceParameters,
                                DocumentFragment   fragment)
      throws SAXException, IOException, SourceException, ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN saveXMLToFile fragment="+(fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
                                ", typeParams="+typeParameters+
                                ", file=" + fileName +
                                ", params="+resourceParameters);
          }
          try {
              // cleanup fragment
              NodeList childs = fragment.getChildNodes();
              if (childs != null) {
                  Node[] list = new Node[childs.getLength()];
                  for(int i = 0; i < childs.getLength(); i++) {
                      list[i] = childs.item(i);
                  }
  
                  for(int i = 0; i < list.length; i++) {
                      if (list[i].getNodeType() == Node.TEXT_NODE) {
                          String value = list[i].getNodeValue();
                          if (value == null
                              || value.length() == 0
                              || value.trim().length() == 0) {
                              list[i].getParentNode().removeChild(list[i]);
                          }
                      }
                  }
              }
  
              Source input = null;
              try {
                  Properties format = XMLUtils.defaultSerializeToXMLFormat(false);
                  this.setOutputKeys(format, typeParameters);
                  input = this.resolver.resolveURI(fileName);
                  String absolutePath = input.getSystemId();
                  if (absolutePath.startsWith("file:") == false) {
                      throw new ProcessingException("Saving to " + fileName + " is not possible.");
                  }
                  File file = new File(absolutePath.substring("file:".length()));
                  if (file.exists() == false) {
                      File directory = file.getParentFile();
                      if (directory.exists() == false) {
                          directory.mkdirs();
                      }
                      file.createNewFile();
                  }
                  String xml = XMLUtils.serializeNode(fragment, format);
                  Writer writer = new BufferedWriter(new FileWriter(file));;
                  writer.write(xml);
                  writer.flush();
                  writer.close();
                  writer = null;
              } finally {
                  this.resolver.release(input);
                  input = null;
              }
  
          } catch (IOException ioe) {
              throw new ProcessingException("saveXMLToFile: IOException: " + ioe, ioe);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END saveXMLToFile");
          }
      }
  
  
      /**
       * Load an XML Fragment from a resource
       */
      public DocumentFragment loadXML(int                resourceType,
                                      Parameters         typeParameters,
                                      String             resourceIdentifier,
                                      SourceParameters resourceParameters)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("start loading '"+resourceIdentifier+"'");
          }
          DocumentFragment frag = null;
          try {
              switch (resourceType) {
                  case ResourceConnector.RESOURCE_TYPE_URI: frag = this.loadXMLFromURI(typeParameters,
                      resourceIdentifier, resourceParameters);
                      break;
                 case ResourceConnector.RESOURCE_TYPE_CLASS: frag = this.loadXMLFromClass(typeParameters,
                      resourceIdentifier, resourceParameters);
                      break;
                 case ResourceConnector.RESOURCE_TYPE_FILE: frag = this.loadXMLFromFile(typeParameters,
                      resourceIdentifier, resourceParameters);
                      break;
                 default: throw new ProcessingException("ResourceConnector: type " +
                            resourceType + " not supported.");
              }
          } catch (SourceException se) {
              throw org.apache.cocoon.components.source.SourceUtil.handle(se);
          } catch (SAXException ioe) {
              throw new ProcessingException("SAXException: " + ioe, ioe);
          } catch (IOException ioe) {
              throw new ProcessingException("IOException: " + ioe, ioe);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("finished loading '"+resourceIdentifier+"'");
          }
          return frag;
      }
  
      /**
       * Save an XML Fragment to a resource
       */
      public void saveXML(int                resourceType,
                          Parameters         typeParameters,
                          String             resourceIdentifier,
                          SourceParameters resourceParameters,
                          DocumentFragment   fragment)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("start saving '"+resourceIdentifier+"'");
          }
          try {
              switch (resourceType) {
                  case ResourceConnector.RESOURCE_TYPE_URI: this.saveXMLToURI(typeParameters,
                             resourceIdentifier, resourceParameters, fragment);
                         break;
                  case ResourceConnector.RESOURCE_TYPE_CLASS: this.saveXMLToClass(typeParameters,
                             resourceIdentifier, resourceParameters, fragment);
                         break;
                  case ResourceConnector.RESOURCE_TYPE_FILE: this.saveXMLToFile(typeParameters,
                             resourceIdentifier, resourceParameters, fragment);
                         break;
                  default: throw new ProcessingException("ResourceConnector: type " +
                             resourceType + " not supported.");
              }
          } catch (SourceException se) {
              throw org.apache.cocoon.components.source.SourceUtil.handle(se);
          } catch (SAXException ioe) {
              throw new ProcessingException("SAXException: " + ioe, ioe);
          } catch (IOException ioe) {
              throw new ProcessingException("IOException: " + ioe, ioe);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("finished saving '"+resourceIdentifier+"'");
          }
      }
  
      /**
       * Stream XML from a file
       */
      private void streamXMLFromFile(Parameters         typeParameters,
                                     String             fileName,
                                     SourceParameters resourceParameters,
                                     org.xml.sax.ContentHandler contentHandler,
                                     LexicalHandler             lexicalHandler)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN streamXMLFromFile fileName=" + fileName +
                                ", typeParams="+typeParameters+
                                ", parameters="+resourceParameters);
          }
          long startTime = System.currentTimeMillis();
          Source input = null;
          try {
              input = this.resolver.resolveURI(fileName);
  
              IncludeXMLConsumer filter = new IncludeXMLConsumer(contentHandler, lexicalHandler);
              this.resolver.toSAX( input, filter );
  
          } catch (SourceException se) {
              throw org.apache.cocoon.components.source.SourceUtil.handle(se);
          } catch (SAXException sax) {
              throw new ProcessingException("SAXException: " + sax, sax);
          } catch (IOException ioe) {
              throw new ProcessingException("IOException: " + ioe, ioe);
          } finally {
              this.resolver.release(input);
              input = null;
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END streamXMLFromFile");
          }
      }
  
      /**
       * Stream XML
       */
      private void streamXMLFromURI(Parameters         typeParameters,
                                    String             uri,
                                    SourceParameters resourceParameters,
                                    org.xml.sax.ContentHandler contentHandler,
                                    LexicalHandler             lexicalHandler)
      throws IOException, SAXException, SourceException, ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
             this.getLogger().debug("BEGIN streamXMLFromURI uri=" + uri +
                               ", typeParams="+typeParameters+
                               ", parameters="+resourceParameters+
                               ", contentHandler="+contentHandler+
                               ", lexicalHandler="+lexicalHandler);
          }
  
          if (uri == null || uri.trim().length() == 0) {
              throw new IllegalArgumentException("streamXMLFromURI: URI is required");
          }
  
          long startTime = System.currentTimeMillis();
          // Test for url rewriting
          if (typeParameters != null
              && typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null) != null) {
              XMLConsumer consumer = new URLRewriter(typeParameters,
                                                     contentHandler,
                                                     lexicalHandler);
              contentHandler = consumer;
              lexicalHandler = consumer;
          }
          IncludeXMLConsumer filter = new IncludeXMLConsumer(contentHandler, lexicalHandler);
  
          Source input = null;
          try {
              input = org.apache.cocoon.components.source.SourceUtil.getSource(uri, typeParameters, resourceParameters, this.resolver, this.objectModel);
              this.resolver.toSAX( input, filter );
          } finally {
              this.resolver.release(input);
              input = null;
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END streamXMLFromURI");
          }
      }
  
      /**
       * Stream an XML resource.
       * This is like loading the resource and then streaming it, but without
       * the Resource->SAX->DOM->SAX transformation, its simply: Resource->SAX
       */
      public void streamXML(int                resourceType,
                            Parameters         typeParameters,
                            String             resourceIdentifier,
                            SourceParameters resourceParameters,
                            org.xml.sax.ContentHandler contentHandler,
                            LexicalHandler             lexicalHandler)
      throws ProcessingException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("start streaming '"+resourceIdentifier+"'");
          }
          try {
              switch (resourceType) {
              case ResourceConnector.RESOURCE_TYPE_URI: this.streamXMLFromURI(typeParameters,
                 resourceIdentifier, resourceParameters, contentHandler, lexicalHandler);
                 break;
              case ResourceConnector.RESOURCE_TYPE_CLASS:
                   throw new ProcessingException("streamXML: Type class not implemented");
                   // break;
              case ResourceConnector.RESOURCE_TYPE_FILE: this.streamXMLFromFile(typeParameters,
                 resourceIdentifier, resourceParameters, contentHandler, lexicalHandler);
                 break;
  
              default: throw new ProcessingException("ResourceConnector: type " +
                 resourceType + " not supported.");
              }
          } catch (SourceException se) {
              throw org.apache.cocoon.components.source.SourceUtil.handle(se);
          } catch (SAXException ioe) {
              throw new ProcessingException("SAXException: " + ioe, ioe);
          } catch (IOException ioe) {
              throw new ProcessingException("IOException: " + ioe, ioe);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("finished streaming '"+resourceIdentifier+"'");
          }
      }
  
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector/XMLLoader.java
  
  Index: XMLLoader.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.connector;
  
  import java.util.Map;
  import org.apache.excalibur.source.SourceParameters;
  import org.w3c.dom.DocumentFragment;
  
  import org.apache.cocoon.ProcessingException;
  
  /**
   * Interface for loading xml - NOT USED YET
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: XMLLoader.java,v 1.2 2002/04/19 11:02:58 cziegeler Exp $
  */
  public interface XMLLoader {
  
    /**
     * Load a DocumentFragment
     */
    DocumentFragment load(Map                objectModel,
                          SourceParameters parameters)
    throws ProcessingException;
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/connector/Resource.java
  
  Index: Resource.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.connector;
  
  import java.io.IOException;
  import java.io.Serializable;
  import org.apache.excalibur.source.Source;
  import org.apache.excalibur.source.SourceException;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.source.SourceUtil;
  import org.xml.sax.SAXException;
  
  /**
   * This is a resource. It consists of a name and a type and possibly some
   * parameters.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: Resource.java,v 1.7 2002/08/21 13:36:11 cziegeler Exp $
  */
  public final class Resource
  implements Serializable {
  
      /** The resource type, e.g. file */
      private int resourceType;
  
      /** The resource identifier, e.g. file name */
      private String resourceIdentifier;
  
      /** The resource parameters (or null) */
      private SourceParameters parameters;
  
      /**
       * Construct a new resource
       */
      public Resource(SourceResolver resolver,
                      String identifier)
      throws ProcessingException, SAXException, IOException {
          // check for relative cocoon:/ protocol
          if (identifier.startsWith("cocoon:") ) {
              this.resourceType = ResourceConnector.RESOURCE_TYPE_URI;
              this.resourceIdentifier = identifier;
          } else if ( identifier.startsWith("class://") ) {
              this.resourceType = ResourceConnector.RESOURCE_TYPE_CLASS;
              this.resourceIdentifier = identifier.substring("class://".length());
          } else {
              // resolve it first
              Source source = null;
              try {
                  source = resolver.resolveURI(identifier);
                  identifier = source.getSystemId();
                  if ( identifier.startsWith("file:") ) {
                      this.resourceType = ResourceConnector.RESOURCE_TYPE_FILE;
                      this.resourceIdentifier = identifier.substring("file:".length());
                  } else {
                      this.resourceType = ResourceConnector.RESOURCE_TYPE_URI;
                      this.resourceIdentifier = identifier;
                  }
              } catch (SourceException se) {
                  throw SourceUtil.handle("Unable to resolve " + identifier, se);
              } finally {
                  resolver.release( source );
              }
          }
      }
  
      /**
       * Get the resource type
       */
      public int getResourceType() {
          return this.resourceType;
      }
  
      /**
       * Get the resource identifier
       */
      public String getResourceIdentifier() {
          return this.resourceIdentifier;
      }
  
      /**
       * Set some parameters
       */
      public void setResourceParameters(SourceParameters pars) {
          this.parameters = pars;
      }
  
      /**
       * Get the parameters
       */
      public SourceParameters getResourceParameters() {
          return this.parameters;
      }
  
      /**
       * PP for debugging
       */
      public String toString() {
          return Resource.class.getName() +
                 this.resourceIdentifier +
                 " (" + this.resourceType + ")";
      }
  }
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/conf/portal.xroles
  
  Index: portal.xroles
  ===================================================================
  <?xml version="1.0"?>
  
  <xroles xpath="/role-list" unless="role[@name='org.apache.cocoon.webapps.portal.components.PortalManager']">
  
    <role name="org.apache.cocoon.webapps.portal.components.PortalManager"
          shorthand="portal-manager"
          default-class="org.apache.cocoon.webapps.portal.components.PortalManager"/>
  
  </xroles>
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/conf/portal.xconf
  
  Index: portal.xconf
  ===================================================================
  <?xml version="1.0"?>
  
  <xconf xpath="/cocoon" unless="portal-manager">
  
    <portal-manager logger="core.portal-manager"
                    pool-max="32" pool-min="8" pool-grow="4"/>
  
  </xconf>
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/conf/portal-gen.xmap
  
  Index: portal-gen.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/generators"
        unless="generator[@name='portal']">
  
      <map:generator name="portal"
                     src="org.apache.cocoon.webapps.portal.generation.PortalGenerator"
                     label="content,data"/>
      <map:generator name="portal-conf"
                     src="org.apache.cocoon.webapps.portal.generation.ConfigurationGenerator"
                     label="content,data"/>
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/conf/portal-act.xmap
  
  Index: portal-act.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/actions"
        unless="action[@name='portal-auth']">
  
      <map:action name="portal-auth"
                  src="org.apache.cocoon.webapps.portal.acting.AuthAction"/>
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/conf/authentication.xroles
  
  Index: authentication.xroles
  ===================================================================
  <?xml version="1.0"?>
  
  <xroles xpath="/role-list" unless="role[@name='org.apache.cocoon.webapps.authentication.components.AuthenticationManager']">
  
    <role name="org.apache.cocoon.webapps.authentication.components.AuthenticationManager"
          shorthand="authentication-manager"
          default-class="org.apache.cocoon.webapps.authentication.components.AuthenticationManager"/>
  
  </xroles>
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/conf/authentication-sel.xmap
  
  Index: authentication-sel.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/selectors"
        unless="selector[@name='auth-media']">
  
      <map:selector name="auth-media"
                    src="org.apache.cocoon.webapps.authentication.selection.MediaSelector"/>
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/conf/authentication.xconf
  
  Index: authentication.xconf
  ===================================================================
  <?xml version="1.0"?>
  
  <xconf xpath="/cocoon" unless="authentication-manager">
  
      <authentication-manager logger="core.authentication-manager"
                              pool-max="32" pool-min="8" pool-grow="4">
        <mediatypes default="html">
          <media name="wap" useragent="Nokia"/>
          <media name="wap" useragent="UP"/>
          <media name="wap" useragent="Wapalizer"/>
        </mediatypes>
      </authentication-manager>
  </xconf>
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/conf/authentication-gen.xmap
  
  Index: authentication-gen.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/generators"
        unless="generator[@name='auth-conf']">
  
      <map:generator name="auth-conf"
                     src="org.apache.cocoon.webapps.authentication.generation.ConfigurationGenerator"
                     label="content,data"/>
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/conf/authentication-act.xmap
  
  Index: authentication-act.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <xmap xpath="/sitemap/components/actions"
        unless="action[@name='auth-protect']">
  
      <map:action name="auth-protect"
                  src="org.apache.cocoon.webapps.authentication.acting.AuthAction"/>
      <map:action name="auth-login"
                  src="org.apache.cocoon.webapps.authentication.acting.LoginAction"/>
      <map:action name="auth-logout"
                  src="org.apache.cocoon.webapps.authentication.acting.LogoutAction"/>
      <map:action name="auth-loggedIn"
                  src="org.apache.cocoon.webapps.authentication.acting.LoggedInAction"/>
  </xmap>
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/SimpleSessionContext.java
  
  Index: SimpleSessionContext.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.io.IOException;
  import java.util.*;
  
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  
  import org.apache.xpath.XPathContext;
  import org.apache.xpath.XPath;
  import org.apache.xpath.XPathContext;
  import org.apache.xml.utils.PrefixResolverDefault;
  import org.apache.xpath.objects.XObject;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.xml.dom.*;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  
  /**
   *  This is a simple implementation of the session context.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SimpleSessionContext.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class SimpleSessionContext
  implements SessionContext {
  
      /** Context name */
      private String   name;
  
      /** The content of the context */
      private Document data;
  
      /** The attributes */
      private Map attributes = new HashMap();
  
      /** load resource */
      private Resource loadResource;
  
      /** save resource */
      private Resource saveResource;
  
      // Refactoring of Xpath Functions.
      private XPathContext xpathSupport;
      private PrefixResolverDefault prefixResolver;
      private Map XpathTable;
  
      public SimpleSessionContext()
      throws ProcessingException {
          data = DOMUtil.createDocument();
          data.appendChild(data.createElementNS(null, "context"));
  
          // Refactoring of Xpath Functions.
          xpathSupport = null;
          prefixResolver = null;
          XpathTable = new HashMap();
      }
  
      /**
       * Get the name of the context
       */
      public String getName() {
          return this.name;
      }
  
      /**
       * doXPath
       */
      private XObject doXPath(String path)
      throws javax.xml.transform.TransformerException {
          // If not there - create or else reset().
          if (xpathSupport == null) xpathSupport = new XPathContext();
          else xpathSupport.reset();
  
          Node namespaceNode = (Node)data;
  
          if (prefixResolver == null) prefixResolver = new PrefixResolverDefault(
            (namespaceNode.getNodeType() == Node.DOCUMENT_NODE) ? ((Document) namespaceNode).getDocumentElement() : namespaceNode);
  
          // Create the XPath object.
          XPath xpath = (XPath)XpathTable.get(path);
          if (xpath == null) {
            xpath = new XPath(path, null, prefixResolver, XPath.SELECT, null);
            XpathTable.put(path,xpath);
          }
  
          // Execute the XPath, and have it return the result
          int ctxtNode = xpathSupport.getDTMHandleFromNode(data);
          return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
      }
  
      public void setup(String value, Resource load, Resource save) {
          this.name = value;
          this.loadResource = load;
          this.saveResource = save;
      }
  
      public synchronized DocumentFragment getXML(String path)
      throws ProcessingException {
          DocumentFragment result = null;
          NodeList list;
          path = this.createPath(path);
  
          try {
              String[] pathComponents = DOMUtil.buildPathArray(path);
              if (pathComponents == null) {
                  //list = DOMUtil.selectNodeList(data, path);
                  list = doXPath(path).nodelist();
              } else {
                  list = DOMUtil.getNodeListFromPath(data, pathComponents);
              }
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("Transforming exception during selectSingleNode with path: '"+path+"'. Exception: " + localException, localException);
          }
  
          if (list != null && list.getLength() > 0) {
              Document doc = DOMUtil.createDocument();
              result = doc.createDocumentFragment();
  
              for(int i = 0; i < list.getLength(); i++) {
  
                  // the found node is either an attribute or an element
                  if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
                      // if it is an attribute simple create a new text node with the value of the attribute
                      result.appendChild(doc.createTextNode(list.item(i).getNodeValue()));
                  } else {
                      // now we have an element
                      // copy all children of this element in the resulting tree
                      NodeList childs = list.item(i).getChildNodes();
                      if (childs != null) {
                          for(int m = 0; m < childs.getLength(); m++) {
                              result.appendChild(doc.importNode(childs.item(m), true));
                          }
                      }
                  }
              }
          }
  
          return result;
      }
  
  
      public synchronized void setXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          path = this.createPath(path);
          Node node = DOMUtil.selectSingleNode(data, path);
          if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
              // now we have to serialize the fragment to a string and insert this
              Attr attr = (Attr)node;
              attr.setNodeValue(DOMUtil.getValueOfNode(fragment));
  
          } else {
  
              // remove old childs
              while (node.hasChildNodes() == true) {
                  node.removeChild(node.getFirstChild());
              }
  
              // Insert new childs
              NodeList childs = fragment.getChildNodes();
              if (childs != null && childs.getLength() > 0) {
                  for(int i = 0; i < childs.getLength(); i++) {
                      Node n = data.importNode(childs.item(i), true);
                      node.appendChild(n);
                  }
              }
          }
      }
  
      /**
       * Append a document fragment at the given path. The implementation of this
       * method is context specific.
       * Usually the children of the fragment are appended as new children of the
       * node specified by the path.
       * If the path is not existent it is created.
       */
      public synchronized void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          path = this.createPath(path);
          Node node = DOMUtil.selectSingleNode(data, path);
          if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
              Attr attr;
  
              if (node.getNodeValue() != null || node.getNodeValue().trim().length() > 0) {
                  // this is an existing attr, create a new one
                  attr = node.getOwnerDocument().createAttributeNS(null, node.getNodeName());
                  node.getParentNode().appendChild(attr);
              } else {
                  attr = (Attr)node;
              }
  
              // now we have to serialize the fragment to a string and insert this
              attr.setNodeValue(DOMUtil.getValueOfNode(fragment));
          } else {
  
              // Insert new childs
              NodeList childs = fragment.getChildNodes();
              if (childs != null && childs.getLength() > 0) {
                  for(int i = 0; i < childs.getLength(); i++) {
                      Node n = data.importNode(childs.item(i), true);
                      node.appendChild(n);
                  }
              }
          }
      }
  
      /**
       * Build path
       */
      private String createPath(String path) {
          if (path == null) path ="/";
          if (path.startsWith("/") == false) path = "/" + path;
          path = "context" + path;
          if (path.endsWith("/") == true) path = path.substring(0, path.length() - 1);
          return path;
      }
  
      /**
       * Remove nodes
       */
      public synchronized void removeXML(String path)
      throws ProcessingException {
          NodeList list;
          path = this.createPath(path);
  
          try {
              String[] pathComponents = DOMUtil.buildPathArray(path);
              if (pathComponents == null) {
                  //list = DOMUtil.selectNodeList(data, path);
                  list = doXPath(path).nodelist();
              } else {
                  list = DOMUtil.getNodeListFromPath(data, pathComponents);
              }
          } catch (javax.xml.transform.TransformerException localException) {
              list = null;
          }
          if (list != null && list.getLength() > 0) {
              int  len = list.getLength();
              Node child;
              for(int i = 0; i < len; i++) {
                  child = list.item(len - 1 -i);
                  child.getParentNode().removeChild(child);
              }
          }
      }
  
      /**
       * Get a copy the first node specified by the path.
       */
      public synchronized Node getSingleNode(String path)
      throws ProcessingException {
          Node result = null;
  
          path = this.createPath(path);
  
          try {
              result = DOMUtil.getSingleNode(data, path);
              if (result != null) result = result.cloneNode(true);
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("TransformerException: " + localException, localException);
          }
  
          return result;
      }
  
      /**
       * Get a copy all the nodes specified by the path.
       */
      public synchronized NodeList getNodeList(String path)
      throws ProcessingException {
          NodeList result = null;
  
          path = this.createPath(path);
  
          try {
              String[] pathComponents = DOMUtil.buildPathArray(path);
              if (pathComponents == null) {
                  //result = DOMUtil.selectNodeList(data, path);
                  result = doXPath(path).nodelist();
              } else {
                  result = DOMUtil.getNodeListFromPath(data, pathComponents);
              }
              // clone list
              if (result != null) {
                  result = new NodeListImpl(result);
              }
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("TransformerException: " + localException, localException);
          }
  
          return result;
      }
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      public synchronized void setNode(String path, Node node)
      throws ProcessingException {
          if (path != null && path.equals("/") == true) {
              throw new ProcessingException("Not a valid path for setNode(): " + path);
          }
  
          path = this.createPath(path);
          Node removeNode = DOMUtil.selectSingleNode(data, path);
          removeNode.getParentNode().replaceChild(data.importNode(node, true), removeNode);
      }
  
  
      /**
       * Set a context attribute. If value is null the attribute is removed.
       */
      public synchronized void setAttribute(String key, Object value) {
          if (value == null) {
              attributes.remove(key);
          } else {
              attributes.put(key, value);
          }
      }
  
      /**
       * Get a context attribute. If the attribute is not available return null
       */
      public synchronized Object getAttribute(String key) {
          return attributes.get(key);
      }
  
      /**
       * Get a context attribute. If the attribute is not available the defaultObject is returned
       */
      public synchronized Object getAttribute(String key, Object defaultObject) {
          Object value = attributes.get(key);
          if (value == null) value = defaultObject;
          return value;
      }
  
      /**
       * Get the value of this node. This is similiar to the xsl:value-of
       * function. If the node does not exist, <code>null</code> is returned.
       */
      public synchronized String getValueOfNode(String path)
      throws ProcessingException {
          String value = null;
  
          path = this.createPath(path); // correct path
          value = DOMUtil.getValueOf(data, path);
  
          return value;
      }
  
      /**
       * Set the value of a node.
       */
      public synchronized void setValueOfNode(String path, String value)
      throws ProcessingException {
          path = this.createPath(path); // correct path
  
          Node node = DOMUtil.selectSingleNode(data, path);
          if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
              Attr attr = (Attr)node;
              attr.setNodeValue(value);
  
          } else {
  
              // remove old childs
              while (node.hasChildNodes() == true) {
                  node.removeChild(node.getFirstChild());
              }
  
              node.appendChild(node.getOwnerDocument().createTextNode(value));
          }
      }
  
      /**
       * Stream the XML directly to the handler. This streams the contents of getXML()
       * to the given handler without creating a DocumentFragment containing a copy
       * of the data
       */
      public synchronized boolean streamXML(String path, ContentHandler contentHandler,
                             LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException {
          NodeList list;
          boolean  streamed = false;
          path = this.createPath(path);
  
          try {
              String[] pathComponents = DOMUtil.buildPathArray(path);
              if (pathComponents == null) {
                  //list = DOMUtil.selectNodeList(data, path);
                  list = doXPath(path).nodelist();
              } else {
                  list = DOMUtil.getNodeListFromPath(data, pathComponents);
              }
          } catch (javax.xml.transform.TransformerException local) {
              throw new ProcessingException("TransformerException: " + local, local);
          }
          if (list != null && list.getLength() > 0) {
              streamed = true;
              for(int i = 0; i < list.getLength(); i++) {
  
                  // the found node is either an attribute or an element
                  if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
                      // if it is an attribute simple create a new text node with the value of the attribute
                      String value = list.item(i).getNodeValue();
                      contentHandler.characters(value.toCharArray(), 0, value.length());
                  } else {
                      // now we have an element
                      // stream all children of this element to the resulting tree
                      NodeList childs = list.item(i).getChildNodes();
                      if (childs != null) {
                          for(int m = 0; m < childs.getLength(); m++) {
                              IncludeXMLConsumer.includeNode(childs.item(m), contentHandler, lexicalHandler);
                          }
                      }
                  }
              }
           }
  
          return streamed;
      }
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      public void loadXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          if (this.loadResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support loading.");
          }
          ResourceConnector connector = null;
          try {
              if (parameters != null) {
                  parameters = (SourceParameters)parameters.clone();
                  parameters.add(this.loadResource.getResourceParameters());
              } else {
                  parameters = this.loadResource.getResourceParameters();
              }
              connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
              DocumentFragment df = connector.loadXML(this.loadResource.getResourceType(), null,
                                                      this.loadResource.getResourceIdentifier(), parameters);
              if (df != null) this.setXML(path, df);
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup the resource connector.", ce);
          } finally {
              manager.release( connector );
          }
      }
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      public void saveXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          if (this.saveResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support saving.");
          }
          ResourceConnector connector = null;
          try {
              if (parameters != null) {
                  parameters = (SourceParameters)parameters.clone();
                  parameters.add(this.saveResource.getResourceParameters());
              } else {
                  parameters = this.saveResource.getResourceParameters();
              }
              DocumentFragment frag = this.getXML(path);
              if (frag == null) {
                  // create empty fake document
                  frag = DOMUtil.createDocument().createDocumentFragment();
              }
              connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
              connector.saveXML(this.saveResource.getResourceType(), null,
                                this.saveResource.getResourceIdentifier(), parameters,
                                frag);
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup the resource connector.", ce);
          } finally {
              manager.release( connector );
          }
      }
  
  }
  
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/RequestSessionContext.java
  
  Index: RequestSessionContext.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.io.*;
  import java.util.*;
  
  import org.apache.avalon.excalibur.xml.Parser;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.Cookie;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.transformation.CIncludeTransformer;
  import org.apache.cocoon.webapps.session.SessionConstants;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.Text;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  
  /**
   * A SessionContext which encapsulates the current Request object.
   *
   * It is not allowed to change this context.
   * The following paths are valid:
   * /parameter                  - lists all parameters, parameter names build the
   *                               elements with the value of the first parameter with
   *                               this name as text node childs
   * /parameter/<parameter_name> - one text node containing the value of the first
   *                               parameter with this name
   * /querystring                - the querystring with a leading '?' or null (the querystring is only for GET)
   *
   * /parametervalues            - same as /parameter but values are listed as described
   *                               below and each value of a parameter is listed.
   *                               <cinclude:parameters>
   *                                      <cinclude:parameter>
   *                                              <cinclude:name>parameter name</cinclude:name>
   *                                              <cinclude:value>parameter value</cinclude:value>
   *                                      </cinclude:parameter>
   *                                       ...
   *                                      <cinclude:parameter>
   *                                              <cinclude:name>parameter name</cinclude:name>
   *                                              <cinclude:value>parameter value</cinclude:value>
   *                                      </session:parameter>
   *                               </cinclude:parameters>
   *                               If a parameter has more than one value for each value a
   *                               <cinclude:parameter/> block is generated.
   *                               This output has the namespace of the CIncludeTransformer
   *                               to use it as input for a <cinclude:includexml> command.
   * /attributes - lists all attributes, attribute names build the elements
   *               with the values as childs
   * /headers    - lists all headers, header names build the elements
   *               with the values as text node childs
   * /cookies ----- <cookie name="...">
   *                   <comment/>
   *                   <domain/>
   *                   <maxAge/>
   *                   <name/>
   *                   <path/>
   *                   <secure/>
   *                   <value/>
   *                   <version/>
   * /characterEncoding
   * /contentLength
   * /contentType
   * /protocol
   * /remoteAddress
   * /remoteHost
   * /scheme
   * /serverName
   * /serverPort
   * /method
   * /contextPath
   * /pathInfo
   * /pathTranslated
   * /remoteUser
   * /requestedSessionId
   * /requestURI
   * /servletPath
   * /isRequestedSessionIdFromCookie
   * /isRequestedSessionIdFromCookie
   * /isRequestedSessionIdValid
   *
   *  The following attributes of the servlet api 2.2 are missing:
   *  - getUserPrincipal()
   *  - getLocale()
   *  - getLocales()
   *  - getAuthType()
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: RequestSessionContext.java,v 1.7 2002/09/26 06:52:23 cziegeler Exp $
  */
  public final class RequestSessionContext
  implements SessionContext {
  
      private static final String PARAMETERS_ELEMENT = "cinclude:" + CIncludeTransformer.CINCLUDE_PARAMETERS_ELEMENT;
      private static final String PARAMETER_ELEMENT  = "cinclude:" + CIncludeTransformer.CINCLUDE_PARAMETER_ELEMENT;
      private static final String NAME_ELEMENT       = "cinclude:" + CIncludeTransformer.CINCLUDE_NAME_ELEMENT;
      private static final String VALUE_ELEMENT      = "cinclude:" + CIncludeTransformer.CINCLUDE_VALUE_ELEMENT;
  
      /** Name of this context */
      private String    name;
  
      /** The current {@link org.apache.cocoon.environment.Request} */
      transient private Request          request;
  
      /** The content of this context */
      private Document  contextData;
  
      /**
       * Setup this context
       */
      public void setup(String value, Resource load, Resource save) {
          this.name = value;
      }
  
      /**
       * Set the Request
       */
      public void setup(Map objectModel, ComponentManager manager)
      throws ProcessingException {
          this.request = ObjectModelHelper.getRequest(objectModel);
  
          contextData = DOMUtil.createDocument();
          contextData.appendChild(contextData.createElementNS(null, "context"));
  
          Element root = contextData.getDocumentElement();
  
          Parser parser = null;
          try {
              parser = (Parser) manager.lookup( Parser.ROLE );
              this.buildParameterXML(root, parser);
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup parser.", ce);
          } finally {
              manager.release( parser );
          }
          this.buildAttributesXML(root);
          this.buildMiscXML(root);
          this.buildCookiesXML(root);
          this.buildHeadersXML(root);
      }
  
      /**
       * Get the name of the context
       */
      public String getName() {
          return this.name;
      }
  
      /**
       * Build path
       */
      private String createPath(String path) {
          if (path == null) path = "/";
          if (path.startsWith("/") == false) path = "/" + path;
          path = "/context" + path;
          if (path.endsWith("/") == true) path = path.substring(0, path.length() - 1);
          return path;
      }
  
      private Node createTextNode(Document doc, String value) {
          return doc.createTextNode(value != null ? value : "");
      }
  
      /**
       * Build attributes XML
       */
      private void buildMiscXML(Element root)
      throws ProcessingException {
          Document doc = root.getOwnerDocument();
  
          Element node;
  
          node = doc.createElementNS(null, "characterEncoding");
          node.appendChild(this.createTextNode(doc, this.request.getCharacterEncoding()));
          root.appendChild(node);
          node = doc.createElementNS(null, "contentLength");
          node.appendChild(this.createTextNode(doc, "" + this.request.getContentLength()));
          root.appendChild(node);
          node = doc.createElementNS(null, "contentType");
          node.appendChild(this.createTextNode(doc, this.request.getContentType()));
          root.appendChild(node);
          node = doc.createElementNS(null, "protocol");
          node.appendChild(this.createTextNode(doc, this.request.getProtocol()));
          root.appendChild(node);
          node = doc.createElementNS(null, "remoteAddress");
          node.appendChild(this.createTextNode(doc, this.request.getRemoteAddr()));
          root.appendChild(node);
          node = doc.createElementNS(null, "remoteHost");
          node.appendChild(this.createTextNode(doc, this.request.getRemoteHost()));
          root.appendChild(node);
          node = doc.createElementNS(null, "scheme");
          node.appendChild(this.createTextNode(doc, this.request.getScheme()));
          root.appendChild(node);
          node = doc.createElementNS(null, "serverName");
          node.appendChild(this.createTextNode(doc, this.request.getServerName()));
          root.appendChild(node);
          node = doc.createElementNS(null, "serverPort");
          node.appendChild(this.createTextNode(doc, ""+this.request.getServerPort()));
          root.appendChild(node);
          node = doc.createElementNS(null, "method");
          node.appendChild(this.createTextNode(doc, this.request.getMethod()));
          root.appendChild(node);
          node = doc.createElementNS(null, "contextPath");
          node.appendChild(this.createTextNode(doc, this.request.getContextPath()));
          root.appendChild(node);
          node = doc.createElementNS(null, "pathInfo");
          node.appendChild(this.createTextNode(doc, this.request.getPathInfo()));
          root.appendChild(node);
          node = doc.createElementNS(null, "pathTranslated");
          node.appendChild(this.createTextNode(doc, this.request.getPathTranslated()));
          root.appendChild(node);
          node = doc.createElementNS(null, "remoteUser");
          node.appendChild(this.createTextNode(doc, this.request.getRemoteUser()));
          root.appendChild(node);
          node = doc.createElementNS(null, "requestedSessionId");
          node.appendChild(this.createTextNode(doc, this.request.getRequestedSessionId()));
          root.appendChild(node);
          node = doc.createElementNS(null, "requestURI");
          node.appendChild(this.createTextNode(doc, this.request.getRequestURI()));
          root.appendChild(node);
          node = doc.createElementNS(null, "servletPath");
          node.appendChild(this.createTextNode(doc, this.request.getServletPath()));
          root.appendChild(node);
          node = doc.createElementNS(null, "isRequestedSessionIdFromCookie");
          node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdFromCookie() ? "true" : "false"));
          root.appendChild(node);
          node = doc.createElementNS(null, "isRequestedSessionIdFromURL");
          node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdFromURL() ? "true" : "false"));
          root.appendChild(node);
          node = doc.createElementNS(null, "isRequestedSessionIdValid");
          node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdValid() ? "true" : "false"));
          root.appendChild(node);
      }
  
      /**
       * Build attributes XML
       */
      private void buildAttributesXML(Element root)
      throws ProcessingException {
          Document doc = root.getOwnerDocument();
          Element attrElement = doc.createElementNS(null, "attributes");
          String attrName;
          Element attr;
  
          root.appendChild(attrElement);
          Enumeration all = this.request.getAttributeNames();
          while (all.hasMoreElements() == true) {
              attrName = (String) all.nextElement();
              attr = doc.createElementNS(null, attrName);
              attrElement.appendChild(attr);
              DOMUtil.valueOf(attr, this.request.getAttribute(attrName));
          }
      }
  
      /**
       * Build cookies XML
       */
      private void buildCookiesXML(Element root)
      throws ProcessingException {
          Document doc = root.getOwnerDocument();
  
          Element cookiesElement = doc.createElementNS(null, "cookies");
          root.appendChild(cookiesElement);
  
          Cookie[] cookies = this.request.getCookies();
          if (cookies != null) {
              Cookie current;
              Element node;
              Element parent;
              for(int i = 0; i < cookies.length; i++) {
                  current = cookies[i];
                  parent = doc.createElementNS(null, "cookie");
                  parent.setAttributeNS(null, "name", current.getName());
                  cookiesElement.appendChild(parent);
                  node = doc.createElementNS(null, "comment");
                  node.appendChild(this.createTextNode(doc, current.getComment()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "domain");
                  node.appendChild(this.createTextNode(doc, current.getDomain()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "maxAge");
                  node.appendChild(this.createTextNode(doc, ""+current.getMaxAge()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "name");
                  node.appendChild(this.createTextNode(doc, current.getName()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "path");
                  node.appendChild(this.createTextNode(doc, current.getPath()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "secure");
                  node.appendChild(doc.createTextNode(current.getSecure() ? "true" : "false"));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "value");
                  node.appendChild(this.createTextNode(doc, current.getValue()));
                  parent.appendChild(node);
                  node = doc.createElementNS(null, "version");
                  node.appendChild(this.createTextNode(doc, ""+current.getVersion()));
                  parent.appendChild(node);
              }
          }
      }
  
      /**
       * Build headers XML
       */
      private void buildHeadersXML(Element root)
      throws ProcessingException {
          Document doc = root.getOwnerDocument();
          Element headersElement = doc.createElementNS(null, "headers");
          String headerName;
          Element header;
  
          root.appendChild(headersElement);
          Enumeration all = this.request.getHeaderNames();
          while (all.hasMoreElements() == true) {
              headerName = (String) all.nextElement();
              header = doc.createElementNS(null, headerName);
              headersElement.appendChild(header);
              header.appendChild(this.createTextNode(doc, this.request.getHeader(headerName)));
          }
      }
  
      /**
       * Build parameter XML
       */
      private void buildParameterXML(Element root, Parser parser)
      throws ProcessingException {
          Document doc = root.getOwnerDocument();
          // include all parameters
          // process "/parameter" and "/parametervalues" at the same time
          Element     parameterElement = doc.createElementNS(null, "parameter");
          Element     parameterValuesElement = doc.createElementNS(null, "parametervalues");
          root.appendChild(parameterElement);
          root.appendChild(parameterValuesElement);
          String      parameterName = null;
          Enumeration pars = this.request.getParameterNames();
          Element     parameter;
          Element     element;
          Node        valueNode;
          String[]    values;
          String      parValue;
  
          element = doc.createElementNS(CIncludeTransformer.CINCLUDE_NAMESPACE_URI, PARAMETERS_ELEMENT);
          parameterValuesElement.appendChild(element);
          parameterValuesElement = element;
  
          while (pars.hasMoreElements() == true) {
              parameterName = (String)pars.nextElement();
              values = this.request.getParameterValues(parameterName);
  
              for(int i = 0; i < values.length; i++) {
  
                  // this is a fast test, if the parameter value contains xml!
                  parValue = values[i].trim();
                  if (parValue.length() > 0 && parValue.charAt(0) == '<') {
                      try {
                          valueNode = DOMUtil.getDocumentFragment(parser, new StringReader(parValue));
                          valueNode = doc.importNode(valueNode, true);
                      } catch (Exception noXMLException) {
                          valueNode = doc.createTextNode(parValue);
                      }
                  } else {
                      valueNode = doc.createTextNode(parValue);
                  }
                  // create "/parameter" entry for first value
                  if (i == 0) {
                      try {
                          parameter = doc.createElementNS(null, parameterName);
                          parameter.appendChild(valueNode);
                          parameterElement.appendChild(parameter);
                      } catch (Exception local) {
                          // the exception is ignored and only this parameters is ignored
                      }
                  }
  
                  try {
                      // create "/parametervalues" entry
                      element = doc.createElementNS(CIncludeTransformer.CINCLUDE_NAMESPACE_URI, PARAMETER_ELEMENT);
                      parameterValuesElement.appendChild(element);
                      parameter = element;
                      element = doc.createElementNS(CIncludeTransformer.CINCLUDE_NAMESPACE_URI, NAME_ELEMENT);
                      parameter.appendChild(element);
                      element.appendChild(doc.createTextNode(parameterName));
                      element = doc.createElementNS(CIncludeTransformer.CINCLUDE_NAMESPACE_URI, VALUE_ELEMENT);
                      parameter.appendChild(element);
                      element.appendChild(valueNode.cloneNode(true));
                  } catch (Exception local) {
                      // the exception is ignored and only this parameters is ignored
                  }
              }
          }
          // and now the query string
          element = doc.createElementNS(null, "querystring");
          root.appendChild(element);
          String value = request.getQueryString();
          if (value != null) {
              element.appendChild(doc.createTextNode('?' + value));
          }
      }
  
      /**
       * Get the XML from the request object
       */
      public DocumentFragment getXML(String path)
      throws ProcessingException {
          if (path == null || path.charAt(0) != '/') {
              throw new ProcessingException("Not a valid XPath: " + path);
          }
          path = this.createPath(path);
          DocumentFragment result = null;
          NodeList list;
  
          try {
              list = DOMUtil.selectNodeList(this.contextData, path);
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("Exception: " + localException, localException);
          }
          if (list != null && list.getLength() > 0) {
              result = DOMUtil.getOwnerDocument(contextData).createDocumentFragment();
              for(int i = 0; i < list.getLength(); i++) {
  
                  // the found node is either an attribute or an element
                  if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
                      // if it is an attribute simple create a new text node with the value of the attribute
                      result.appendChild(DOMUtil.getOwnerDocument(contextData).createTextNode(list.item(i).getNodeValue()));
                  } else {
                      // now we have an element
                      // copy all children of this element in the resulting tree
                      NodeList childs = list.item(i).getChildNodes();
                      if (childs != null) {
                          for(int m = 0; m < childs.getLength(); m++) {
                              result.appendChild(DOMUtil.getOwnerDocument(contextData).importNode(childs.item(m), true));
                          }
                      }
                  }
              }
          }
  
          return result;
      }
  
      /**
       * Setting of xml is not possible for the request context
       */
      public void setXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          throw new ProcessingException("RequestSessionContext: Setting of xml not allowed");
      }
  
      /**
       * Setting of xml is not possible for the request context
       */
      public void setValueOfNode(String path, String value)
      throws ProcessingException {
          throw new ProcessingException("RequestSessionContext: Setting of xml not allowed");
      }
  
      /**
       * Append a document fragment is not possible for the request context.
       */
      public void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          throw new ProcessingException("RequestSessionContext: Appending of xml not allowed");
      }
  
      /**
       * Removing is not possible for the request context.
       */
      public void removeXML(String path)
      throws ProcessingException {
          throw new ProcessingException("RequestSessionContext: Removing of xml not allowed");
      }
  
      /**
       * Set a context attribute. If value is null the attribute is removed.
       */
      public void setAttribute(String key, Object value)
      throws ProcessingException {
          if (value == null) {
              this.request.removeAttribute(key);
          } else {
              this.request.setAttribute(key, value);
          }
      }
  
      /**
       * Get a context attribute. If the attribute is not available return null
       */
      public Object getAttribute(String key)
      throws ProcessingException {
          return this.request.getAttribute(key);
      }
  
      /**
       * Get a context attribute. If the attribute is not available the defaultObject is returned
       */
      public Object getAttribute(String key, Object defaultObject)
      throws ProcessingException {
          Object obj = this.getAttribute(key);
          return (obj != null ? obj : defaultObject);
      }
  
      /**
       * Get a copy the first node specified by the path.
       */
      public Node getSingleNode(String path)
      throws ProcessingException {
          path = this.createPath(path);
          Node node = null;
  
          try {
              node = DOMUtil.getSingleNode(this.contextData, path);
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("Exception: " + localException, localException);
          }
          return node;
      }
  
      /**
       * Get a copy all the nodes specified by the path.
       */
      public NodeList getNodeList(String path)
      throws ProcessingException {
          path = this.createPath(path);
          NodeList list = null;
  
          try {
              list = DOMUtil.selectNodeList(this.contextData, path);
          } catch (javax.xml.transform.TransformerException localException) {
              throw new ProcessingException("Exception: " + localException, localException);
          }
          return list;
      }
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      public void setNode(String path, Node node)
      throws ProcessingException {
          throw new ProcessingException("RequestSessionContext: Setting of XML not allowed");
      }
  
      /**
       * Get the value of this node. This is similiar to the xsl:value-of
       * function. If the node does not exist, <code>null</code> is returned.
       */
      public String getValueOfNode(String path)
      throws ProcessingException {
          String value = null;
          Node node = this.getSingleNode(path);
          if (node != null) {
              value = DOMUtil.getValueOfNode(node);
          }
  
          return value;
      }
  
      /**
       * Stream the XML directly to the handler. This streams the contents of getXML()
       * to the given handler without creating a DocumentFragment containing a copy
       * of the data
       */
      public boolean streamXML(String path,
                               ContentHandler contentHandler,
                               LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException {
          boolean result = false;
          NodeList list;
  
          try {
              list = DOMUtil.selectNodeList(this.contextData, this.createPath(path));
          } catch (javax.xml.transform.TransformerException local) {
              throw new ProcessingException("TransformerException: " + local, local);
          }
          if (list != null && list.getLength() > 0) {
              result = true;
              for(int i = 0; i < list.getLength(); i++) {
  
                  // the found node is either an attribute or an element
                  if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
                      // if it is an attribute simple create a new text node with the value of the attribute
                      String value = list.item(i).getNodeValue();
                      contentHandler.characters(value.toCharArray(), 0, value.length());
                  } else {
                      // now we have an element
                      // stream all children of this element to the resulting tree
                      NodeList childs = list.item(i).getChildNodes();
                      if (childs != null) {
                          for(int m = 0; m < childs.getLength(); m++) {
                              IncludeXMLConsumer.includeNode(childs.item(m), contentHandler, lexicalHandler);
                          }
                      }
                  }
              }
          }
  
          return result;
      }
  
      /**
       * Get the request parameter as xml
       */
      public DocumentFragment getParameterAsXML(final String parameterName)
      throws ProcessingException {
          return this.getXML("/parameter/"+parameterName);
      }
  
      /**
       * Get the request parameter as a String
       */
      public String getParameter(final String parameterName)
      throws ProcessingException {
          return this.request.getParameter(parameterName);
      }
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      public void loadXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support loading.");
      }
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      public void saveXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support saving.");
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/StandardSessionContextProvider.java
  
  Index: StandardSessionContextProvider.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.SessionConstants;
  
  /**
   *  Context provider for the temporarily context, the request and the
   *  response context.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: StandardSessionContextProvider.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class StandardSessionContextProvider
  implements SessionContextProvider {
  
      /**
       * Get the context
       * @param name The name of the context
       * @param objectModel The objectModel of the current request.
       * @param resolver    The source resolver
       * @param componentManager manager
       * @return The context
       * @throws ProcessingException If the context is not available.
       */
      public SessionContext getSessionContext(String           name,
                                              Map              objectModel,
                                              SourceResolver   resolver,
                                              ComponentManager manager)
      throws ProcessingException {
          SessionContext context = null;
          if ( name.equals(SessionConstants.TEMPORARY_CONTEXT) ) {
              context = new SimpleSessionContext();
              context.setup(name, null, null);
          } else if ( name.equals(SessionConstants.REQUEST_CONTEXT) ) {
              context = new RequestSessionContext();
              context.setup(name, null, null);
              ((RequestSessionContext)context).setup( objectModel, manager );
          } else if ( name.equals(SessionConstants.RESPONSE_CONTEXT) ) {
              context = new ResponseSessionContext();
              context.setup(name, null, null);
              ((ResponseSessionContext)context).setup( objectModel );
          }
          return context;
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/SessionContextProvider.java
  
  Index: SessionContextProvider.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  
  /**
   *  Interface for a context provider.
   *  Objects of this class provide special context, e.g. authentication or portal.
   *  The context is (if used) got once by the <code>SessionManager</code> component
   *  for each request.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContextProvider.java,v 1.4 2002/07/12 11:25:58 cziegeler Exp $
  */
  public interface SessionContextProvider {
  
      /**
       * Get the context
       * @param name The name of the context
       * @param objectModel The objectModel of the current request.
       * @param resolver    The source resolver
       * @param componentManager manager
       * @return The context
       * @throws ProcessingException If the context is not available.
       */
      SessionContext getSessionContext(String           name,
                                       Map              objectModel,
                                       SourceResolver   resolver,
                                       ComponentManager manager)
      throws ProcessingException;
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/SessionContext.java
  
  Index: SessionContext.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.Map;
  
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.connector.Resource;
  
  /**
   *  Interface for a SessionContext.
   *  This interface describes a SessionContext. The SessionContext is a data
   *  container containing structured XML which can be retrieved/set by the
   *  session transformer.
   *  This interface does not specify how the session context stores the data.
   *  This is left to the implementation itself, but actually this interface
   *  is build in the DOM model.
   *  As this context is used in a web context, all methods must be synchronized.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContext.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public interface SessionContext
  extends Serializable {
  
      /** Set the name of the context.
       *  This method must be invoked in the init phase.
       *  In addition a load and a save resource can be provided.
       */
      void setup(String value, Resource load, Resource save);
  
      /**
       * Get the name of the context
       */
      String getName();
  
      /**
       *  Get a document fragment.
       *  If the node specified by the path exist, its content is returned
       *  as a DocumentFragment.
       *  If the node does not exists, <CODE>null</CODE> is returned.
       */
      DocumentFragment getXML(String path)
      throws ProcessingException ;
  
      /**
       *  Set a document fragment at the given path.
       *  The implementation of this method is context specific.
       *  Usually all children of the node specified by the path are removed
       *  and the children of the fragment are inserted as new children.
       *  If the path is not existent it is created.
       */
      void setXML(String path, DocumentFragment fragment)
      throws ProcessingException;
  
      /**
       * Append a document fragment at the given path.
       * The implementation of this method is context specific.
       * Usually the children of the fragment are appended as new children of the
       * node specified by the path.
       * If the path is not existent it is created and this method should work
       * in the same way as setXML.
       */
      void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException;
  
      /**
       * Remove some content from the context.
       * The implementation of this method is context specific.
       * Usually this method should remove all children of the node specified
       * by the path.
       */
      void removeXML(String path)
      throws ProcessingException;
  
      /**
       * Set a context attribute.
       * Attributes over a means to store any data (object) in a session
       * context. If <CODE>value</CODE> is <CODE>null</CODE> the attribute is
       * removed. If already an attribute exists with the same key, the value
       * is overwritten with the new one.
       */
      void setAttribute(String key, Object value)
      throws ProcessingException;
  
      /**
       * Get the value of a context attribute.
       * If the attribute is not available return <CODE>null</CODE>.
       */
      Object getAttribute(String key)
      throws ProcessingException;
  
      /**
       * Get the value of a context attribute.
       * If the attribute is not available the return the
       * <CODE>defaultObject</CODE>.
       */
      Object getAttribute(String key, Object defaultObject)
      throws ProcessingException;
  
      /**
       * Get a copy of the first node specified by the path.
       * If the node does not exist, <CODE>null</CODE> is returned.
       */
      Node getSingleNode(String path)
      throws ProcessingException;
  
      /**
       * Get a copy of all nodes specified by the path.
       */
      NodeList getNodeList(String path)
      throws ProcessingException;
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      void setNode(String path, Node node)
      throws ProcessingException;
  
      /**
       * Get the value of this node.
       * This is similiar to the xsl:value-of function.
       * If the node does not exist, <code>null</code> is returned.
       */
      String getValueOfNode(String path)
      throws ProcessingException;
  
      /**
       * Set the value of a node.
       * All children of the node are removed beforehand and one single text
       * node with the given value is appended to the node.
       */
      void setValueOfNode(String path, String value)
      throws ProcessingException;
  
      /**
       * Stream the XML directly to the handler.
       * This streams the contents of getXML() to the given handler without
       * creating a DocumentFragment containing a copy of the data.
       * If no data is available (if the path does not exist) <code>false</code> is
       * returned, otherwise <code>true</code>.
       */
      boolean streamXML(String path,
                        ContentHandler contentHandler,
                        LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException;
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      void loadXML(String path,
                   SourceParameters parameters,
                   Map                objectModel,
                   SourceResolver     resolver,
                   ComponentManager   manager)
      throws SAXException, ProcessingException, IOException;
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      void saveXML(String path,
                   SourceParameters parameters,
                   Map                objectModel,
                   SourceResolver     resolver,
                   ComponentManager   manager)
      throws SAXException, ProcessingException, IOException;
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/context/ResponseSessionContext.java
  
  Index: ResponseSessionContext.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.context;
  
  import java.io.IOException;
  import java.util.Map;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.Cookie;
  import org.apache.cocoon.environment.Response;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  
  
  /**
   * A SessionContext which encapsulates the current Response object.
   *
   * The following XML for setXML and appendXML is allowed:
   * /header/<headername> - The content is the value of the header
   * /cookie              - The content is the cookie:
   *                <name>gsdgsdg</name>  - name of the cookie
   *                <value>gdgdgdgs</value> - cookie value
   *               optional:
   *                <domain/>
   *                <path/>
   *                <secure>true or false</secure>
   *                <comment/>
   *                <version/>
   *                <maxAge/>
   *
   * Using setXML uses setHeader() and appendXML uses addHeader. Despite this they
   * both have the same effect.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ResponseSessionContext.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class ResponseSessionContext
  implements SessionContext {
  
      private String             name;
      transient private Response response;
  
      public void setup(String value, Resource load, Resource save) {
          name = value;
      }
  
      public void setup(Map objectModel) {
          this.response = ObjectModelHelper.getResponse(objectModel);
      }
  
      /**
       * Get the name of the context
       */
      public String getName() {
          return this.name;
      }
  
      /**
       * Build the cookie
       */
      private Cookie createCookie(SourceParameters par) {
          Cookie cookie = this.response.createCookie(par.getParameter("name"),
                                     par.getParameter("value"));
          String value;
  
          value = par.getParameter("comment");
          if (value != null) cookie.setComment(value);
          value = par.getParameter("domain");
          if (value != null) cookie.setDomain(value);
          value = par.getParameter("path");
          if (value != null) cookie.setPath(value);
          if (par.containsParameter("maxAge") == true) {
              cookie.setMaxAge(par.getParameterAsInteger("maxAge", 0));
          }
          if (par.containsParameter("version") == true) {
              cookie.setVersion(par.getParameterAsInteger("version", 0));
          }
          if (par.containsParameter("secure") == true) {
              cookie.setSecure(par.getParameterAsBoolean("secure", true));
          }
          return cookie;
      }
  
      /**
       * Get the XML from the response object
       */
      public DocumentFragment getXML(String path)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of xml not allowed.");
      }
  
      public void setXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          if (this.response == null) {
              throw new ProcessingException("Response Object missing");
          }
          if (path != null) {
              if (path.startsWith("/header/") == true) {
                  String name = path.substring(8);
                  this.response.setHeader(name, DOMUtil.createText(fragment));
              } else if (path.equals("/cookie") == true) {
                  this.response.addCookie(this.createCookie(DOMUtil.createParameters(fragment, null)));
              } else {
                  throw new ProcessingException("Invalid response path '"+path+"'");
              }
          }
      }
  
      /**
       * Append a document fragment at the given path. The implementation of this
       * method is context specific.
       */
      public void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          if (this.response == null) {
              throw new ProcessingException("Response Object missing");
          }
          if (path != null) {
              if (path.startsWith("/header/") == true) {
                  String name = path.substring(8);
                  this.response.addHeader(name, DOMUtil.createText(fragment));
              } else if (path.equals("/cookie") == true) {
                  this.response.addCookie(this.createCookie(DOMUtil.createParameters(fragment, null)));
              } else {
                  throw new ProcessingException("Invalid response path '"+path+"'");
              }
          }
  
      }
  
      public void removeXML(String path)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Removing of xml not allowed");
      }
  
      /**
       * Set a context attribute.
       */
      public void setAttribute(String key, Object value)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Setting of attributes not allowed");
      }
  
      /**
       * Get a context attribute.
       */
      public Object getAttribute(String key)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of attributes not allowed");
      }
  
      /**
       * Get a context attribute.
       */
      public Object getAttribute(String key, Object defaultObject)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of attributes not allowed");
      }
  
      /**
       * Get a copy the first node specified by the path.
       */
      public Node getSingleNode(String path)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of xml not allowed");
      }
  
      /**
       * Get a copy all the nodes specified by the path.
       */
      public NodeList getNodeList(String path)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of xml not allowed");
      }
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      public void setNode(String path, Node node)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Setting of XML not allowed");
      }
  
      /**
       * Get the value of this node. This is similiar to the xsl:value-of
       * function. If the node does not exist, <code>null</code> is returned.
       */
      public String getValueOfNode(String path)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of xml not allowed");
      }
  
      /**
       * Set the value of this node.
       */
      public void setValueOfNode(String path, String value)
      throws ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Setting of xml not allowed");
      }
  
      /**
       * Stream the XML directly to the handler. This streams the contents of getXML()
       * to the given handler without creating a DocumentFragment containing a copy
       * of the data
       */
      public boolean streamXML(String path,
                               ContentHandler contentHandler,
                               LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException {
          throw new ProcessingException("ResponseSessionContext: Getting of xml not allowed");
      }
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      public void loadXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support loading.");
      }
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      public void saveXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support saving.");
      }
  
  }
  
  
  1.6       +3 -0      xml-cocoon2/properties.xml
  
  Index: properties.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/properties.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- properties.xml	25 Sep 2002 09:02:50 -0000	1.5
  +++ properties.xml	27 Sep 2002 09:05:16 -0000	1.6
  @@ -106,6 +106,9 @@
           <chaperon include="true"/>
           <jfor include="true"/>
           <swf include="true"/>
  +        <session-fw include="true"/>
  +        <authentication-fw include="true"/>
  +        <portal-fw include="true"/>
         </blocks>
   
      </cocoon>
  
  
  
  1.7       +50 -0     xml-cocoon2/module.xml
  
  Index: module.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/module.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- module.xml	26 Sep 2002 10:55:35 -0000	1.6
  +++ module.xml	27 Sep 2002 09:05:16 -0000	1.7
  @@ -185,4 +185,54 @@
       <jar name="jisp_1_0_2.jar"/>
     </project>
     
  +  <project name="session-fw-block">
  +    <package>org.apache.cocoon</package>
  +    
  +    <ant target="block">
  +      <property name="block-name" value="session-fw"/>
  +    </ant>
  +    
  +    <depend project="xml-cocoon2"/>
  +    
  +    <work nested="tools/anttasks"/>
  +    <home nested="build/cocoon"/>
  +    
  +    <jar name="session-fw-block.jar"/>
  +    
  +  </project>
  +    
  +  <project name="authentication-fw-block">
  +    <package>org.apache.cocoon</package>
  +    
  +    <ant target="block">
  +      <property name="block-name" value="authentication-fw"/>
  +    </ant>
  +    
  +    <depend project="xml-cocoon2"/>
  +    <depend project="session-fw-block"/>
  +    
  +    <work nested="tools/anttasks"/>
  +    <home nested="build/cocoon"/>
  +    
  +    <jar name="authentication-fw-block.jar"/>
  +    
  +  </project>
  +
  +  <project name="portal-fw-block">
  +    <package>org.apache.cocoon</package>
  +    
  +    <ant target="block">
  +      <property name="block-name" value="portal-fw"/>
  +    </ant>
  +    
  +    <depend project="xml-cocoon2"/>
  +    <depend project="session-fw-block"/>
  +    <depend project="authentication-fw-block"/>
  +    
  +    <work nested="tools/anttasks"/>
  +    <home nested="build/cocoon"/>
  +    
  +    <jar name="portal-fw-block.jar"/>
  +    
  +  </project>
   </module>
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/generation/PortalGenerator.java
  
  Index: PortalGenerator.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.generation;
  
  import java.io.IOException;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.generation.ComposerGenerator;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.webapps.portal.components.PortalManager;
  
  import org.xml.sax.SAXException;
  
  /**
   * This generator generates the portal for the current user.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: PortalGenerator.java,v 1.1 2002/04/17 12:39:19 cziegeler Exp $
  */
  public final class PortalGenerator
  extends ComposerGenerator {
  
      public void generate()
      throws IOException, SAXException, ProcessingException {
  
          PortalManager portal = null;
          try {
              portal = (PortalManager) this.manager.lookup(PortalManager.ROLE);
              this.xmlConsumer.startDocument();
  
              Request request = ObjectModelHelper.getRequest(this.objectModel);
              if (request.getSession(false) != null) {
                  portal.showPortal(this.xmlConsumer, false, false);
              }
              this.xmlConsumer.endDocument();
          } catch (ComponentException ce) {
              throw new ProcessingException("Lookup of PortalManager failed.", ce);
          } finally {
              this.manager.release(portal);
          }
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/generation/ConfigurationGenerator.java
  
  Index: ConfigurationGenerator.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.generation;
  
  import java.io.IOException;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.generation.ComposerGenerator;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.webapps.portal.components.PortalManager;
  
  import org.xml.sax.SAXException;
  
  /**
   * This generator generates the configuration of the portal
   * for the current user.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ConfigurationGenerator.java,v 1.1 2002/04/17 12:39:19 cziegeler Exp $
  */
  public final class ConfigurationGenerator
  extends ComposerGenerator {
  
      public void generate()
      throws IOException, SAXException, ProcessingException {
  
          PortalManager portal = null;
          try {
              portal = (PortalManager) this.manager.lookup(PortalManager.ROLE);
              this.xmlConsumer.startDocument();
  
              Request request = ObjectModelHelper.getRequest(this.objectModel);
              if (request.getSession(false) != null) {
                  if (this.source == null
                      || this.source.equals("")
                      || this.source.equals("user") == true) {
                      portal.showPortal(this.xmlConsumer, true, false);
                  } else {
                      portal.showAdminConf(this.xmlConsumer);
                  }
              }
  
              this.xmlConsumer.endDocument();
          } catch (ComponentException ce) {
              throw new ProcessingException("Lookup of portal failed.", ce);
          } finally {
              this.manager.release(portal);
          }
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/SessionPostTransformer.java
  
  Index: SessionPostTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.transformation;
  
  import java.io.IOException;
  import java.util.Map;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.webapps.session.SessionConstants;
  import org.apache.cocoon.webapps.session.connector.*;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  import org.w3c.dom.DocumentFragment;
  
  /**
   * This is the session post transformer. It does all the setting and
   * destroying. Thus it should be the last transformer (before the xsl) in
   * the pipeline.
   * For performance and simplicity reasons this transformer inherits from
   * the SessionPreTransformer, although this is not needed (But then the
   * implementation of the SessionTransformer would be very unperformant.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionPostTransformer.java,v 1.2 2002/04/19 11:02:59 cziegeler Exp $
  */
  public class SessionPostTransformer
  extends SessionPreTransformer {
  
      public static final String DELETECONTEXT_ELEMENT = "deletecontext";
      public static final String DELETECONTEXT_NAME_ATTRIBUTE = "name";
  
      public static final String SETXML_ELEMENT = "setxml";
      public static final String SETXML_CONTEXT_ATTRIBUTE = "context";
      public static final String SETXML_PATH_ATTRIBUTE = "path";
  
      public static final String APPENDXML_ELEMENT = "appendxml";
      public static final String APPENDXML_CONTEXT_ATTRIBUTE = "context";
      public static final String APPENDXML_PATH_ATTRIBUTE = "path";
  
      public static final String REMOVEXML_ELEMENT = "removexml";
      public static final String REMOVEXML_CONTEXT_ATTRIBUTE = "context";
      public static final String REMOVEXML_PATH_ATTRIBUTE = "path";
  
      public static final String MERGEXML_ELEMENT = "mergexml";
      public static final String MERGEXML_CONTEXT_ATTRIBUTE = "context";
      public static final String MERGEXML_PATH_ATTRIBUTE = "path";
  
      public static final String SAVECONTEXT_ELEMENT = "savexml";
      public static final String SAVECONTEXT_CONTEXT_ATTRIBUTE = "context";
      public static final String SAVECONTEXT_PATH_ATTRIBUTE = "path"; // optional
  
      public static final String INPUTXML_ELEMENT = "inputxml";
      public static final String INPUTXML_CONTEXT_ATTRIBUTE = "context";
      public static final String INPUTXML_PATH_ATTRIBUTE = "path";
      public static final String INPUTXML_NAME_ATTRIBUTE = "name";
      public static final String INPUTXML_TYPE_ATTRIBUTE = "type"; // optional
  
      /** The form element */
      public static final String FORM_ELEMENT = "form";
  
      /** The form action element */
      public static final String FORM_ACTION_ELEMENT = "action";
  
      /** The form content element */
      public static final String FORM_CONTENT_ELEMENT = "content";
  
      /** State: no element parsed */
      private static final int STATE_OUTSIDE   = 0;
      /** State: form element */
      private static final int STATE_FORM      = 1;
  
      /** The current state */
      private int state;
  
      /** The current form name */
      private String formName;
  
      /** The unique form number */
      private static int currentFormNumber = 0;
  
      public void setupTransforming()
      throws ProcessingException, SAXException, IOException {
          super.setupTransforming();
          this.state = STATE_OUTSIDE;
          this.formName = null;
      }
  
      /**
       * This is the real implementation of the startElement event
       * for the transformer
       * The event is checked for a valid element and the corresponding command
       * is executed.
       */
      public void startTransformingElement(String uri,
                                           String name,
                                           String raw,
                                           Attributes attr)
      throws ProcessingException, IOException, SAXException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN startTransformingElement uri=" + uri +
                                     ", name=" + name + ", raw=" + raw + ", attr=" + attr);
          }
          if (name.equals(DELETECONTEXT_ELEMENT) == true) {
              this.getSessionManager().deleteContext(attr.getValue(DELETECONTEXT_NAME_ATTRIBUTE));
  
          } else if (name.equals(SETXML_ELEMENT) == true) {
              this.startRecording();
              stack.push(attr.getValue(SETXML_CONTEXT_ATTRIBUTE));
              stack.push(attr.getValue(SETXML_PATH_ATTRIBUTE));
  
          // Element: mergexml
          } else if (name.equals(MERGEXML_ELEMENT) == true) {
              this.startRecording();
              stack.push(attr.getValue(MERGEXML_CONTEXT_ATTRIBUTE));
              stack.push(attr.getValue(MERGEXML_PATH_ATTRIBUTE));
  
          // Element: appendxml
          } else if (name.equals(APPENDXML_ELEMENT) == true) {
              this.startRecording();
              stack.push(attr.getValue(APPENDXML_CONTEXT_ATTRIBUTE));
              stack.push(attr.getValue(APPENDXML_PATH_ATTRIBUTE));
  
          // Element: removexml
          } else if (name.equals(REMOVEXML_ELEMENT) == true) {
              this.startTextRecording();
              stack.push(attr.getValue(REMOVEXML_CONTEXT_ATTRIBUTE));
              stack.push(attr.getValue(REMOVEXML_PATH_ATTRIBUTE));
  
          } else if (name.equals(SAVECONTEXT_ELEMENT) == true) {
              this.startParametersRecording();
              stack.push(attr.getValue(SAVECONTEXT_CONTEXT_ATTRIBUTE));
              if (attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE) != null) {
                  stack.push(attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE));
              } else {
                  stack.push("/");
              }
  
          // Element: inputxml
          } else if (name.equals(INPUTXML_ELEMENT) == true) {
              stack.push(attr.getValue(INPUTXML_CONTEXT_ATTRIBUTE));
              String fieldname = attr.getValue(INPUTXML_NAME_ATTRIBUTE);
              stack.push(fieldname);
              stack.push(attr.getValue(INPUTXML_PATH_ATTRIBUTE));
  
              AttributesImpl newattr = new AttributesImpl();
              newattr.addAttribute("", INPUTXML_NAME_ATTRIBUTE, INPUTXML_NAME_ATTRIBUTE, "CDATA", fieldname);
              if (attr.getValue(INPUTXML_TYPE_ATTRIBUTE) != null) {
                  newattr.addAttribute("",
                                       INPUTXML_TYPE_ATTRIBUTE,
                                       INPUTXML_TYPE_ATTRIBUTE,
                                       "CDATA", attr.getValue(INPUTXML_TYPE_ATTRIBUTE));
              }
  
              super.startTransformingElement("", name, name, newattr); // remove namespace
              this.startRecording();
  
          // Element form
          } else if (name.equals(FORM_ELEMENT) == true
                     && this.state == STATE_OUTSIDE) {
              String formName = attr.getValue("name");
              if (formName == null) {
                  throw new ProcessingException("The name attribute of the form element is required.");
              }
              this.stack.push(new Integer(this.state));
              this.state = STATE_FORM;
              this.stack.push(new AttributesImpl(attr));
  
          // Element form action
          } else if (name.equals(FORM_ACTION_ELEMENT) == true
                     && this.state == STATE_FORM) {
              this.startTextRecording();
  
          // Element form content
          } else if (name.equals(FORM_CONTENT_ELEMENT) == true
                     && this.state == STATE_FORM) {
              // ignore this
  
          } else {
              super.startTransformingElement(uri, name, raw, attr);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END startTransformingElement");
          }
      }
  
      public void endTransformingElement(String uri,
                                         String name,
                                         String raw)
      throws ProcessingException ,IOException, SAXException {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw);
          }
          if (name.equals(DELETECONTEXT_ELEMENT) == true) {
              // do nothing, the context was destroyed on the startElement event
  
              // Element: setxml
          } else if (name.equals(SETXML_ELEMENT) == true) {
              String path        = (String)stack.pop();
              String contextName = (String)stack.pop();
              this.getSessionManager().setContextFragment(contextName, path, this.endRecording());
  
          // Element: mergexml
          } else if (name.equals(MERGEXML_ELEMENT) == true) {
              String path        = (String)stack.pop();
              String contextName = (String)stack.pop();
              this.getSessionManager().mergeContextFragment(contextName, path, this.endRecording());
  
          // Element: appendxml
          } else if (name.equals(APPENDXML_ELEMENT) == true) {
              String path        = (String)stack.pop();
              String contextName = (String)stack.pop();
              this.getSessionManager().appendContextFragment(contextName, path, this.endRecording());
  
          // Element: removexml
          } else if (name.equals(REMOVEXML_ELEMENT) == true) {
              String path        = (String)stack.pop();
              String contextName = (String)stack.pop();
              String text = this.endTextRecording(); //this is ignored
              this.getSessionManager().removeContextFragment(contextName, path);
  
          // Element: savexml
          } else if (name.equals(SAVECONTEXT_ELEMENT) == true) {
              String path        = (String)stack.pop();
              String contextName = (String)stack.pop();
              SourceParameters pars = this.endParametersRecording((SourceParameters)null);
              pars.setSingleParameterValue("contextname", contextName);
              pars.setSingleParameterValue("path", path);
  
              this.getSessionManager().getContext(contextName).saveXML(path,
                                                                          pars,
                                                                          this.objectModel,
                                                                          this.resolver,
                                                                          this.manager);
  
          // Element: inputxml
          } else if (name.equals(INPUTXML_ELEMENT) == true) {
              String path = (String)this.stack.pop();
              String fieldname = (String)this.stack.pop();
              String contextname = (String)this.stack.pop();
              DocumentFragment defaultFragment = this.endRecording();
  
              if (this.formName == null) {
                  throw new ProcessingException("The inputxml must be contained inside a form.");
              }
              DocumentFragment value = this.getSessionManager().registerInputField(contextname, path, fieldname, formName);
              if (value == null) value = defaultFragment;
              this.sendEvents(value);
              super.endTransformingElement("", name, name);
  
          // Element form
          } else if (name.equals(FORM_ELEMENT) == true
                     && this.state == STATE_FORM) {
              this.state = ((Integer)this.stack.pop()).intValue();
              this.sendEndElementEvent("form");
              this.formName = null;
  
          // Element form action
          } else if (name.equals(FORM_ACTION_ELEMENT) == true
                     && this.state == STATE_FORM) {
              String action = this.endTextRecording();
              AttributesImpl a = (AttributesImpl)this.stack.pop();
              // append a unique number to the form
              synchronized (this.getClass()) {
                  this.formName = a.getValue("name") + '_' + currentFormNumber;
                  currentFormNumber++;
                  if (currentFormNumber > 99999) currentFormNumber = 0;
              }
              boolean hasPars = (action.indexOf("?") != -1);
              action = this.response.encodeURL(action + (hasPars ? '&' : '?') + SessionConstants.SESSION_FORM_PARAMETER+'='+this.formName);
              a.addAttribute("", "action", "action", "CDATA", action);
              if (a.getValue("method") == null) {
                  a.addAttribute("", "method", "method", "CDATA", "POST");
              }
              this.sendStartElementEvent("form", a);
  
          // Element form content
          } else if (name.equals(FORM_CONTENT_ELEMENT) == true
                     && this.state == STATE_FORM) {
              // ignore this
  
          } else {
              super.endTransformingElement(uri, name, raw);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END endTransformingElement");
          }
      }
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/SessionPreTransformer.java
  
  Index: SessionPreTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.transformation;
  
  import java.io.IOException;
  import java.util.Map;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.session.SessionConstants;
  import org.apache.cocoon.webapps.session.connector.*;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  import org.w3c.dom.DocumentFragment;
  
  /**
   * This is the session pre transformer. It does all the getting
   * and creation commands. This transformer should be the first in the
   * pipeline.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionPreTransformer.java,v 1.4 2002/09/25 13:48:40 cziegeler Exp $
  */
  public class SessionPreTransformer
  extends AbstractSessionTransformer {
  
      /*
       * The XML commands
       */
      public static final String CREATECONTEXT_ELEMENT = "createcontext";
      public static final String CREATECONTEXT_NAME_ATTRIBUTE = "name";
      public static final String CREATECONTEXT_SAVE_ATTRIBUTE = "save"; // optional
      public static final String CREATECONTEXT_LOAD_ATTRIBUTE = "load"; // optional
  
      public static final String GETXML_ELEMENT = "getxml";
      public static final String GETXML_CONTEXT_ATTRIBUTE = "context";
      public static final String GETXML_PATH_ATTRIBUTE = "path";
  
      public static final String LOADCONTEXT_ELEMENT = "loadxml";
      public static final String LOADCONTEXT_CONTEXT_ATTRIBUTE = "context";
      public static final String LOADCONTEXT_PATH_ATTRIBUTE = "path"; // optional
  
      /** The contexturl element.
       */
      public static final String CONTEXT_URL_ELEMENT = "contexturl";
  
      /** Are we inside a getxml? */
      protected int processingGetXML;
  
      public SessionPreTransformer() {
          this.namespaceURI = SessionConstants.SESSION_NAMESPACE_URI;
      }
  
      /**
       * Setup the next round.
       * The instance variables are initialised.
       * @param resolver The current SourceResolver
       * @param objectModel The objectModel of the environment.
       * @param src The value of the src attribute in the sitemap.
       * @param par The parameters from the sitemap.
       */
      public void setup(SourceResolver resolver,
                        Map            objectModel,
                        String         src,
                        Parameters     par)
      throws ProcessingException,
             SAXException,
             IOException {
          super.setup(resolver, objectModel, src, par);
          this.processingGetXML = 0;
      }
  
      /**
       * Process the SAX event.
       * The namespace of the event is checked. If it is the defined namespace
       * for this transformer the endTransformingElement() hook is called.
       */
      public void endElement(String uri, String name, String raw) throws SAXException {
          super.endElement(uri, name, raw);
          if (uri != null
              && namespaceURI != null
              && uri.equals(namespaceURI) == true
              && this.processingGetXML > 0
              && name.equals(GETXML_ELEMENT) == true) {
              this.processingGetXML--;
              this.ignoreEventsCount--;
              this.ignoreHooksCount--;
          }
      }
  
      /**
       * Process the SAX event.
       * The namespace of the event is checked. If it is the defined namespace
       * for this transformer the endTransformingElement() hook is called.
       */
      public void startElement(String uri,
                               String name,
                               String raw,
                               Attributes attr)
      throws SAXException {
          if (uri != null
              && namespaceURI != null
              && uri.equals(namespaceURI) == true
              && this.processingGetXML > 0
              && name.equals(GETXML_ELEMENT) == true) {
              this.processingGetXML++;
              this.ignoreEventsCount++;
              this.ignoreHooksCount++;
          }
          super.startElement(uri, name, raw, attr);
      }
  
      /**
       * This is the real implementation of the startElement event for the transformer
       * The event is checked for a valid element and the corresponding command
       * is executed.
       */
      public void startTransformingElement(String uri,
                                         String name,
                                         String raw,
                                         Attributes attr)
      throws ProcessingException, IOException, SAXException {
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN startTransformingElement uri=" + uri +
                                ", name=" + name +
                                ", raw=" + raw +
                                ", attr=" + attr);
          }
          if (name.equals(CREATECONTEXT_ELEMENT) == true) {
              this.getSessionManager().createContext(attr.getValue(CREATECONTEXT_NAME_ATTRIBUTE),
                                                        attr.getValue(CREATECONTEXT_LOAD_ATTRIBUTE),
                                                        attr.getValue(CREATECONTEXT_SAVE_ATTRIBUTE));
  
          } else if (name.equals(GETXML_ELEMENT) == true) {
              final String path        = attr.getValue(GETXML_PATH_ATTRIBUTE);
              final String contextName = attr.getValue(GETXML_CONTEXT_ATTRIBUTE);
  
              if (this.getSessionManager().streamContextFragment(contextName,
                                                       path,
                                                       this) == true) {
                  this.ignoreEventsCount++;
                  this.ignoreHooksCount++;
                  this.processingGetXML++;
              }
  
          } else if (name.equals(LOADCONTEXT_ELEMENT) == true) {
              this.startParametersRecording();
              stack.push(attr.getValue(LOADCONTEXT_CONTEXT_ATTRIBUTE));
              if (attr.getValue(LOADCONTEXT_PATH_ATTRIBUTE) != null) {
                  stack.push(attr.getValue(LOADCONTEXT_PATH_ATTRIBUTE));
              } else {
                  stack.push("/");
              }
  
          // Element context url
          } else if (name.equals(SessionPreTransformer.CONTEXT_URL_ELEMENT) == true) {
              this.ignoreEventsCount++;
  
          // DEFAULT
          } else {
              super.startTransformingElement(uri, name, raw, attr);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
             this.getLogger().debug("END startTransformingElement");
          }
      }
  
      public void endTransformingElement(String uri,
                                         String name,
                                         String raw)
      throws ProcessingException ,IOException, SAXException {
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw);
          }
          if (name.equals(CREATECONTEXT_ELEMENT) == true) {
              // do nothing, the context was created on the startElement event
  
          } else if (name.equals(GETXML_ELEMENT) == true) {
              // do nothing
  
          // Element: loadxml
          } else if (name.equals(LOADCONTEXT_ELEMENT) == true) {
              String path       = (String)stack.pop();
              String contextName = (String)stack.pop();
              SourceParameters pars = this.endParametersRecording((SourceParameters)null);
              pars.setSingleParameterValue("contextname", contextName);
              pars.setSingleParameterValue("path", path);
  
              DocumentFragment frag = null;
              this.getSessionManager().getContext(contextName).loadXML(path,
                                                                          pars,
                                                                          this.objectModel,
                                                                          this.resolver,
                                                                          this.manager);
          // Element context url
          } else if (name.equals(SessionPreTransformer.CONTEXT_URL_ELEMENT) == true) {
              this.ignoreEventsCount--;
              String contextUrl = this.request.getScheme() + "://" +
                                  this.request.getServerName() + ":" +
                                  this.request.getServerPort() +
                                  this.request.getContextPath();
              this.sendTextEvent(contextUrl);
  
  
          // DEFAULT
          } else {
              super.endTransformingElement(uri, name, raw);
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END endTransformingElement");
          }
      }
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/SessionTransformer.java
  
  Index: SessionTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.transformation;
  
  /**
   * This is the session transformer which is only for compatibility.
   * It inherits from the ConnectTransformer which inherits from
   * the SessionPostTransformer whicb inherits from the SessionPreTransformer.
   * So those three do all the work
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionTransformer.java,v 1.1 2002/04/17 08:43:57 cziegeler Exp $
  */
  public class SessionTransformer
  extends SessionPostTransformer {
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/AbstractSessionTransformer.java
  
  Index: AbstractSessionTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.transformation;
  
  import java.io.*;
  import java.util.*;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.excalibur.pool.Recyclable;
  
  import org.apache.cocoon.components.parser.Parser;
  import org.apache.cocoon.environment.Context;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.transformation.AbstractSAXTransformer;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.connector.*;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.XMLConsumer;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.Locator;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  
  /**
   *  This class is the basis for all session transformers.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AbstractSessionTransformer.java,v 1.2 2002/04/19 11:02:59 cziegeler Exp $
  */
  public abstract class AbstractSessionTransformer
  extends AbstractSAXTransformer {
  
      private SessionManager     sessionManager;
      /** The Resource Connector */
      private ResourceConnector  resourceConnector;
      /** The SourceResolver for this request */
  
      /**
       * Get the SessionManager component
       */
      protected SessionManager getSessionManager()
      throws ProcessingException {
          if (this.sessionManager == null) {
              try {
                  this.sessionManager = (SessionManager)this.manager.lookup(SessionManager.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of SessionManager component.", ce);
              }
          }
          return this.sessionManager;
      }
  
      /**
       * Get the resource connector
       */
      protected ResourceConnector getResourceConnector()
      throws ProcessingException {
          if (this.resourceConnector == null) {
              try {
                  this.resourceConnector = (ResourceConnector)this.manager.lookup(ResourceConnector.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of resource connector.", ce);
              }
          }
          return this.resourceConnector;
      }
  
      /**
       *  Recycle this component.
       */
      public void recycle() {
          super.recycle();
          this.manager.release(this.resourceConnector);
          this.manager.release(this.sessionManager);
          this.resourceConnector = null;
          this.sessionManager = null;
      }
  
      /**
       * Get the current session if available or return <code>null</code>.
       * @return The Session object or null.
       */
      public Session getSession()
      throws ProcessingException {
          return this.getSessionManager().getSession(false);
      }
  
  }
  
  
  
  1.3       +2 -5      xml-cocoon2/tools/src/blocks-build.xsl
  
  Index: blocks-build.xsl
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/tools/src/blocks-build.xsl,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- blocks-build.xsl	16 Sep 2002 15:34:36 -0000	1.2
  +++ blocks-build.xsl	27 Sep 2002 09:05:16 -0000	1.3
  @@ -35,7 +35,7 @@
                  <xsl:attribute name="dir">${build.dir}</xsl:attribute>
   
                  <include>
  -                  <xsl:attribute name="name">${name}*.jar</xsl:attribute>
  +                  <xsl:attribute name="name">*.jar</xsl:attribute>
                  </include>
               </fileset>
            </path>
  @@ -160,10 +160,7 @@
         <target name="{$current-project-target}" if="cocoon.blocks.{$block-name}.include">
   <!-- if there is a dependency... -->
            <xsl:if test="depend">
  -            <xsl:attribute name="depends">cocoon-core
  -            <xsl:for-each select="depend[not(@version)]">,
  -            <xsl:value-of select="@project" />
  -            </xsl:for-each>
  +            <xsl:attribute name="depends">cocoon-core<xsl:for-each select="depend[not(@version)]">, <xsl:value-of select="@project" /></xsl:for-each>
               </xsl:attribute>
            </xsl:if>
   
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/selection/MediaSelector.java
  
  Index: MediaSelector.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.selection;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.selection.Selector;
  
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  
  /**
   *  This selector uses the authentication media management.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: MediaSelector.java,v 1.1 2002/04/17 10:04:52 cziegeler Exp $
  */
  public final class MediaSelector
  implements Composable, Selector, ThreadSafe {
  
      private ComponentManager manager;
  
      /**
       * Composable
       */
      public void compose(ComponentManager manager) {
          this.manager = manager;
      }
  
      /**
       * Selector
       */
      public boolean select (String expression, Map objectModel, Parameters parameters) {
          AuthenticationManager authManager = null;
          boolean result;
          try {
              authManager = (AuthenticationManager) this.manager.lookup( AuthenticationManager.ROLE );
              result = authManager.testMedia(objectModel, expression);
          } catch (Exception local) {
              // ignore me
              result = false;
          } finally {
              this.manager.release( authManager );
          }
          return result;
      }
  }
  
  
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/context/SessionContextProviderImpl.java
  
  Index: SessionContextProviderImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.context;
  
  import java.util.Map;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.context.SessionContextProvider;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  
  
  /**
   *  Context provider for the authentication context
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContextProviderImpl.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class SessionContextProviderImpl
  implements SessionContextProvider {
  
      /**
       * Get the context
       * @param name The name of the context
       * @param objectModel The objectModel of the current request.
       * @param resolver    The source resolver
       * @param componentManager manager
       * @return The context
       * @throws ProcessingException If the context is not available.
       */
      public SessionContext getSessionContext(String           name,
                                              Map              objectModel,
                                              SourceResolver   resolver,
                                              ComponentManager manager)
      throws ProcessingException {
          SessionContext context = null;
          if (name.equals(org.apache.cocoon.webapps.authentication.AuthenticationConstants.SESSION_CONTEXT_NAME) == true) {
              final Request req = ObjectModelHelper.getRequest(objectModel);
              final String handlerName = (String)req.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_HANDLER_NAME);
              final String appName     = (String)req.getAttribute(AuthenticationConstants.REQUEST_ATTRIBUTE_APPLICATION_NAME);
              final Session session = req.getSession(false);
              if (session != null && handlerName != null) {
                  context = (SessionContext)session.getAttribute(AuthenticationConstants.SESSION_ATTRIBUTE_CONTEXT_NAME);
                  context = new SessionContextImpl(context, name, handlerName, appName, resolver, manager);
              }
          }
          return context;
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/context/SessionContextImpl.java
  
  Index: SessionContextImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.context;
  
  import java.io.IOException;
  import java.util.Map;
  
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.helpers.AttributesImpl;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.xml.dom.DOMUtil;
  import org.apache.cocoon.webapps.authentication.components.*;
  
  /**
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContextImpl.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class SessionContextImpl
  implements SessionContext {
  
      private String          name;
      private SessionContext  authContext;
      private Resource        loadResource;
      private Resource        saveResource;
      private Resource        authLoadResource;
      private Resource        authSaveResource;
      private String          handlerName;
      private String          applicationName;
  
      public SessionContextImpl(SessionContext context,
                                String         contextName,
                                String          handlerName,
                                String          applicationName,
                                SourceResolver  resolver,
                                ComponentManager manager)
      throws ProcessingException {
          AuthenticationManager authManager = null;
          try {
              authManager = (AuthenticationManager)manager.lookup(AuthenticationManager.ROLE);
              Handler handler = authManager.getHandler();
              this.name = contextName;
              this.authContext = context;
              this.handlerName = handlerName;
              this.applicationName = applicationName;
              this.authLoadResource = handler.getLoadResource();
              this.authSaveResource = handler.getSaveResource();
              if (this.applicationName != null) {
                  ApplicationHandler appHandler = (ApplicationHandler)handler.getApplications().get(this.applicationName);
                  this.loadResource = appHandler.getLoadResource();
                  this.saveResource = appHandler.getSaveResource();
              }
  
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup the resource connector.", ce);
          } finally {
              manager.release(authManager);
          }
      }
  
      /** Set the name of the context.
       *  This method must be invoked in the init phase.
       *  In addition a load and a save resource can be provided.
       */
      public void setup(String value, Resource load, Resource save) {
      }
  
      /**
       * Get the name of the context
       */
      public String getName() {
          return this.name;
      }
  
      /**
       *  Get a document fragment.
       *  If the node specified by the path exist, its content is returned
       *  as a DocumentFragment.
       *  If the node does not exists, <CODE>null</CODE> is returned.
       */
      public DocumentFragment getXML(String path)
      throws ProcessingException {
          if (path == null) {
              throw new ProcessingException("getXML: Path is required");
          }
          if (path.startsWith("/") == false) path = '/' + path;
  
          DocumentFragment frag = null;
  
          if (path.equals("/") == true) {
              // get all: first authentication then application
              frag = this.authContext.getXML("/" + this.handlerName + "/authentication");
  
              if (frag != null) {
                  // now add root node authentication
                  Node root = frag.getOwnerDocument().createElementNS(null, "authentication");
                  Node child;
                  while (frag.hasChildNodes() == true) {
                      child = frag.getFirstChild();
                      frag.removeChild(child);
                      root.appendChild(child);
                  }
                  frag.appendChild(root);
              }
  
              if (this.applicationName != null) {
                  // join
                  DocumentFragment appFrag = this.authContext.getXML("/" + this.handlerName + "/applications/" + this.applicationName);
                  if (appFrag != null) {
                      // now add root node application
                      Node root = appFrag.getOwnerDocument().createElementNS(null, "application");
                      Node child;
                      while (appFrag.hasChildNodes() == true) {
                          child = appFrag.getFirstChild();
                          appFrag.removeChild(child);
                          root.appendChild(child);
                      }
                      appFrag.appendChild(root);
  
                      if (frag == null) {
                          frag = appFrag;
                      } else {
                          while (appFrag.hasChildNodes() == true) {
                              child = appFrag.getFirstChild();
                              appFrag.removeChild(child);
                              child = frag.getOwnerDocument().importNode(child, true);
                              frag.appendChild(child);
                          }
                      }
                  }
              }
  
          } else if (path.startsWith("/authentication") == true) {
              frag = this.authContext.getXML("/" + this.handlerName + path);
  
          } else if (path.equals("/application") == true || path.startsWith("/application/") == true) {
              if (this.applicationName != null) {
                  String appPath;
                  if (path.equals("/application") == true) {
                      appPath ="/";
                  } else {
                      appPath = path.substring("/application".length());
                  }
                  frag = this.authContext.getXML("/" + this.handlerName + "/applications/" + this.applicationName + appPath);
              }
          } else {
              frag = this.authContext.getXML("/" + this.handlerName + path);
          }
  
          return frag;
      }
  
      /**
       * Convert the authentication XML of a handler to parameters.
       * The XML is flat and consists of elements which all have exactly one text node:
       * <parone>value_one<parone>
       * <partwo>value_two<partwo>
       * A parameter can occur more than once with different values.
       */
      public void addParametersFromAuthenticationXML(String handlerName,
                                                     String path,
                                                     SourceParameters parameters)
      throws ProcessingException {
          final DocumentFragment fragment = this.authContext.getXML("/" + handlerName + "/authentication" + path);
          if (fragment != null) {
              NodeList   childs = fragment.getChildNodes();
              if (childs != null) {
                  Node current;
                  for(int i = 0; i < childs.getLength(); i++) {
                      current = childs.item(i);
  
                      // only element nodes
                      if (current.getNodeType() == Node.ELEMENT_NODE) {
                          current.normalize();
                          NodeList valueChilds = current.getChildNodes();
                          String   key;
                          StringBuffer   valueBuffer;
                          String         value;
  
                          key = current.getNodeName();
                          valueBuffer = new StringBuffer();
                          for(int m = 0; m < valueChilds.getLength(); m++) {
                              current = valueChilds.item(m); // attention: current is reused here!
                              if (current.getNodeType() == Node.TEXT_NODE) { // only text nodes
                                  if (valueBuffer.length() > 0) valueBuffer.append(' ');
                                  valueBuffer.append(current.getNodeValue());
                              }
                          }
                          value = valueBuffer.toString().trim();
                          if (key != null && value != null && value.length() > 0) {
                              parameters.setParameter(key, value);
                          }
                      }
                  }
              }
          }
      }
  
      /**
       *  Set a document fragment at the given path.
       *  The implementation of this method is context specific.
       *  Usually all children of the node specified by the path are removed
       *  and the children of the fragment are inserted as new children.
       *  If the path is not existent it is created.
       */
      public void setXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          if (path == null) {
              throw new ProcessingException("setXML: Path is required");
          }
          if (path.startsWith("/") == false) path = '/' + path;
  
          if ( path.equals("/") ) {
              // set all is not allowed with "/"
              throw new ProcessingException("Path '/' is not allowed");
  
          } else if ( path.startsWith("/authentication") ) {
  
              this.cleanParametersCache();
              this.authContext.setXML('/' + this.handlerName + path, fragment);
  
          } else if (path.equals("/application") == true
                     || path.startsWith("/application/") == true) {
  
              if (this.applicationName == null) {
                  throw new ProcessingException("Application is required");
              }
              String appPath;
              if (path.equals("/application") == true) {
                  appPath = "/";
              } else {
                  appPath = path.substring("/application".length());
              }
              this.authContext.setXML("/" + this.handlerName + "/applications/" + this.applicationName + appPath, fragment);
  
          } else {
              this.authContext.setXML("/" + this.handlerName + path, fragment);
          }
      }
  
      /**
       * Set the XML for an application
       */
      public void setApplicationXML(String setHandlerName,
                                    String setApplicationName,
                                    String path,
                                    DocumentFragment fragment)
      throws ProcessingException {
          path = "/" + setHandlerName + "/applications/" + setApplicationName + path;
          this.authContext.setXML(path, fragment);
      }
  
      /**
       * Append a document fragment at the given path.
       * The implementation of this method is context specific.
       * Usually the children of the fragment are appended as new children of the
       * node specified by the path.
       * If the path is not existent it is created and this method should work
       * in the same way as setXML.
       */
      public void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          if (path == null) {
              throw new ProcessingException("appendXML: Path is required");
          }
          if (path.startsWith("/") == false) path = '/' + path;
  
          if ( path.equals("/") ) {
              // set all is not allowed with "/"
              throw new ProcessingException("Path '/' is not allowed");
  
          } else if ( path.startsWith("/authentication") ) {
  
              this.cleanParametersCache();
              this.authContext.appendXML('/' + this.handlerName + path, fragment);
  
          } else if (path.equals("/application") == true
                     || path.startsWith("/application/") == true) {
  
              if (this.applicationName == null) {
                  throw new ProcessingException("Application is required");
              }
              String appPath;
              if (path.equals("/application") == true) {
                  appPath = "/";
              } else {
                  appPath = path.substring("/application".length());
              }
              this.authContext.appendXML("/" + this.handlerName + "/applications/" + this.applicationName + appPath, fragment);
  
          } else {
              this.authContext.appendXML("/" + this.handlerName + path, fragment);
          }
      }
  
      /**
       * Remove some content from the context.
       * The implementation of this method is context specific.
       * Usually this method should remove all children of the node specified
       * by the path.
       */
      public void removeXML(String path)
      throws ProcessingException {
          if (path == null) {
              throw new ProcessingException("removeXML: Path is required");
          }
          if (path.startsWith("/") == false) path = '/' + path;
  
          if (path.equals("/") == true) {
              this.cleanParametersCache();
              this.authContext.removeXML("/" + this.handlerName);
  
          } else if (path.startsWith("/authentication") == true) {
  
              this.cleanParametersCache();
              this.authContext.removeXML("/" + this.handlerName + path);
  
          } else if (path.equals("/application") == true
                     || path.startsWith("/application/") == true) {
              if (this.applicationName == null) {
                  throw new ProcessingException("removeXML: Application is required for path " + path);
              }
              String appPath;
              if (path.equals("/application") == true) {
                  appPath = "/";
              } else {
                  appPath = path.substring("/application".length());
              }
              this.authContext.removeXML("/" + this.handlerName + "/applications/" + this.applicationName + appPath);
          } else {
              this.authContext.removeXML("/" + this.handlerName + path);
          }
      }
  
      /**
       * Set a context attribute.
       * Attributes over a means to store any data (object) in a session
       * context. If <CODE>value</CODE> is <CODE>null</CODE> the attribute is
       * removed. If already an attribute exists with the same key, the value
       * is overwritten with the new one.
       */
      public void setAttribute(String key, Object value)
      throws ProcessingException {
          this.authContext.setAttribute(key, value);
      }
  
      /**
       * Get the value of a context attribute.
       * If the attribute is not available return <CODE>null</CODE>.
       */
      public Object getAttribute(String key)
      throws ProcessingException {
          return this.authContext.getAttribute(key);
      }
  
      /**
       * Get the value of a context attribute.
       * If the attribute is not available the return the
       * <CODE>defaultObject</CODE>.
       */
      public Object getAttribute(String key, Object defaultObject)
      throws ProcessingException {
          return this.authContext.getAttribute(key, defaultObject);
      }
  
      /**
       * Get a copy of the first node specified by the path.
       * If the node does not exist, <CODE>null</CODE> is returned.
       */
      public Node getSingleNode(String path)
      throws ProcessingException {
          throw new ProcessingException("This method is not supported by the authenticaton session context.");
      }
  
      /**
       * Get a copy of all nodes specified by the path.
       */
      public NodeList getNodeList(String path)
      throws ProcessingException {
          throw new ProcessingException("This method is not supported by the authenticaton session context.");
      }
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      public void setNode(String path, Node node)
      throws ProcessingException {
          throw new ProcessingException("This method is not supported by the authenticaton session context.");
      }
  
      /**
       * Get the value of this node.
       * This is similiar to the xsl:value-of function.
       * If the node does not exist, <code>null</code> is returned.
       */
      public String getValueOfNode(String path)
      throws ProcessingException {
          throw new ProcessingException("This method is not supported by the authenticaton session context.");
      }
  
      /**
       * Set the value of a node.
       * All children of the node are removed beforehand and one single text
       * node with the given value is appended to the node.
       */
      public void setValueOfNode(String path, String value)
      throws ProcessingException {
          throw new ProcessingException("This method is not supported by the authenticaton session context.");
      }
  
      /**
       * Stream the XML directly to the handler.
       * This streams the contents of getXML() to the given handler without
       * creating a DocumentFragment containing a copy of the data.
       * If no data is available (if the path does not exist) <code>false</code> is
       * returned, otherwise <code>true</code>.
       */
      public boolean streamXML(String path, ContentHandler contentHandler,
                               LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException {
          if (path == null) {
              throw new ProcessingException("streamXML: Path is required");
          }
          if (path.startsWith("/") == false) path = '/' + path;
  
          if (path.equals("/") == true) {
              // get all: first authentication then application
              contentHandler.startElement(null, "authentication", "authentication", new AttributesImpl());
              this.authContext.streamXML('/' + this.handlerName + "/authentication", contentHandler, lexicalHandler);
              contentHandler.endElement(null, "authentication", "authentication");
  
              if (this.applicationName != null) {
                  contentHandler.startElement(null, "application", "application", new AttributesImpl());
                  this.authContext.streamXML('/' + this.handlerName + "/applications/" + this.applicationName, contentHandler, lexicalHandler);
                  contentHandler.endElement(null, "application", "application");
              }
              return true;
  
          } else if (path.startsWith("/authentication") == true) {
              return this.authContext.streamXML('/' + this.handlerName + path, contentHandler, lexicalHandler);
  
          } else if (path.equals("/application") == true || path.startsWith("/application/") == true) {
              if (this.applicationName != null) {
                  String appPath;
                  if (path.equals("/application") == true) {
                      appPath ="/";
                  } else {
                      appPath = path.substring("/application".length());
                  }
                  return this.authContext.streamXML('/' + this.handlerName + "/applications/" + this.applicationName + appPath, contentHandler, lexicalHandler);
              }
          } else {
              return this.authContext.streamXML('/' + this.handlerName + path, contentHandler, lexicalHandler);
          }
          return false;
      }
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      public void loadXML(String path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          if (path.startsWith("/") == false) path = '/' + path;
  
          if (path.equals("/") == true) {
              // load all: first authentication then application
              this.loadAuthenticationXML("/authentication",
                                         parameters,
                                         objectModel,
                                         resolver,
                                         manager);
              if (this.applicationName != null) {
                  this.loadApplicationXML("/",
                                          parameters,
                                          objectModel,
                                          resolver,
                                          manager);
              }
  
          } else if (path.startsWith("/authentication") == true) {
              this.loadAuthenticationXML(path,
                                         parameters,
                                         objectModel,
                                         resolver,
                                         manager);
  
          } else if (path.equals("/application") == true && this.applicationName != null) {
              this.loadApplicationXML("/",
                                      parameters,
                                      objectModel,
                                      resolver,
                                      manager);
          } else if (path.startsWith("/application/") == true && this.applicationName != null) {
              this.loadApplicationXML(path.substring(12), // start path with '/'
                                      parameters,
                                      objectModel,
                                      resolver,
                                      manager);
          } else {
              throw new ProcessingException("loadXML: Path is not valid: " + path);
          }
      }
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      public void saveXML(String             path,
                          SourceParameters parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          if (path.startsWith("/") == false) path = '/' + path;
  
          if (path.equals("/") == true) {
              // save all: first authentication then application
              this.saveAuthenticationXML("/authentication",
                                         parameters,
                                         objectModel,
                                         resolver,
                                         manager);
              if (this.applicationName != null) {
                  this.saveApplicationXML("/",
                                          parameters,
                                          objectModel,
                                          resolver,
                                          manager);
              }
  
          } else if (path.startsWith("/authentication") == true) {
              this.saveAuthenticationXML(path,
                                         parameters,
                                         objectModel,
                                         resolver,
                                         manager);
  
          } else if (path.equals("/application") == true && this.applicationName != null) {
              this.saveApplicationXML("/",
                                      parameters,
                                      objectModel,
                                      resolver,
                                      manager);
          } else if (path.startsWith("/application/") == true && this.applicationName != null) {
              this.saveApplicationXML(path.substring(12), // start path with '/'
                                      parameters,
                                      objectModel,
                                      resolver,
                                      manager);
          } else {
              throw new ProcessingException("saveXML: Path is not valid: " + path);
          }
      }
  
      /**
       * Clean the parameters cache
       */
      private void cleanParametersCache()
      throws ProcessingException {
          this.authContext.setAttribute("cachedparameters_" + this.handlerName, null);
          this.authContext.setAttribute("cachedmap_" + this.handlerName, null);
      }
  
      /**
       * Clean the parameters cache
       */
      public void cleanParametersCache(String handlerName)
      throws ProcessingException {
          this.authContext.setAttribute("cachedparameters_" + handlerName, null);
          this.authContext.setAttribute("cachedmap_" + handlerName, null);
      }
  
      /**
       * Save Authentication
       */
      private void saveAuthenticationXML(String             path,
                                         SourceParameters parameters,
                                         Map                objectModel,
                                         SourceResolver     resolver,
                                         ComponentManager   manager)
      throws ProcessingException {
          if (this.authSaveResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support saving.");
          }
          ResourceConnector connector = null;
          try {
              synchronized(this.authContext) {
                  DocumentFragment fragment = this.getXML(path);
                  if (fragment == null) {
                      // create empty fake fragment
                      fragment = DOMUtil.createDocument().createDocumentFragment();
                  }
                  if (parameters != null) {
                      parameters = (SourceParameters)parameters.clone();
                      parameters.add(this.authSaveResource.getResourceParameters());
                  } else if (this.authSaveResource.getResourceParameters() != null) {
                      parameters = (SourceParameters)this.authSaveResource.getResourceParameters().clone();
                  }
                  parameters = this.createParameters(parameters,
                                                     this.handlerName,
                                                     path,
                                                     null);
                  connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
                  connector.saveXML(this.authSaveResource.getResourceType(), null,
                                    this.authSaveResource.getResourceIdentifier(), parameters,
                                    fragment);
  
              } // end synchronized
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup the resource connector.", ce);
          } finally {
              manager.release( connector );
          }
      }
  
      /**
       * Save Authentication
       */
      private void loadAuthenticationXML(String             path,
                                         SourceParameters parameters,
                                         Map                objectModel,
                                         SourceResolver     resolver,
                                         ComponentManager   manager)
      throws ProcessingException {
          if (this.authLoadResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support loading.");
          }
          ResourceConnector connector = null;
          try {
              synchronized(this.authContext) {
                  if (parameters != null) {
                      parameters = (SourceParameters)parameters.clone();
                      parameters.add(this.authLoadResource.getResourceParameters());
                  } else if (this.authLoadResource.getResourceParameters() != null) {
                      parameters = (SourceParameters)this.authLoadResource.getResourceParameters().clone();
                  }
                  parameters = this.createParameters(parameters,
                                                     this.handlerName,
                                                     path,
                                                     null);
                  connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
                  DocumentFragment frag = connector.loadXML(this.authLoadResource.getResourceType(), null,
                                                            this.authLoadResource.getResourceIdentifier(), parameters);
                  this.setXML(path, frag);
  
              } // end synchronized
          } catch (ComponentException ce) {
              throw new ProcessingException("Unable to lookup the resource connector.", ce);
          } finally {
              manager.release( connector );
          }
      }
  
      /**
       * Load XML of an application
       */
      private void loadApplicationXML(String             path,
                                      SourceParameters parameters,
                                      Map                objectModel,
                                      SourceResolver     resolver,
                                      ComponentManager   manager)
      throws ProcessingException {
          if (this.loadResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support loading.");
          }
          // synchronized
          synchronized (this.authContext) {
  
              final String   loadResourceName = this.loadResource.getResourceIdentifier();
              final int      loadResourceType = this.loadResource.getResourceType();
              final SourceParameters loadParameters = this.loadResource.getResourceParameters();
              if (parameters != null) {
                  parameters = (SourceParameters)parameters.clone();
                  parameters.add(loadParameters);
              } else if (loadParameters != null) {
                  parameters = (SourceParameters)loadParameters.clone();
              }
              parameters = this.createParameters(parameters,
                                                 this.handlerName,
                                                 path,
                                                 this.applicationName);
              DocumentFragment fragment;
              ResourceConnector connector = null;
              try {
                  connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
                  fragment = connector.loadXML(loadResourceType, null,
                                               loadResourceName, parameters);
                  this.setXML(path, fragment);
  
              } catch (ComponentException ce) {
                  throw new ProcessingException("Unable to lookup the resource connector.", ce);
              } finally {
                  manager.release( connector );
              }
  
          } // end synchronized
  
      }
  
      /**
       * Save XML of an application
       */
      private void saveApplicationXML(String path,
                                      SourceParameters parameters,
                                      Map                objectModel,
                                      SourceResolver     resolver,
                                      ComponentManager   manager)
      throws ProcessingException {
          if (this.saveResource == null) {
              throw new ProcessingException("The context " + this.name + " does not support saving.");
          }
          // synchronized
          synchronized (this.authContext) {
  
              final String   saveResourceName = this.saveResource.getResourceIdentifier();
              final int      saveResourceType = this.saveResource.getResourceType();
              final SourceParameters saveParameters = this.saveResource.getResourceParameters();
              if (parameters != null) {
                  parameters = (SourceParameters)parameters.clone();
                  parameters.add(saveParameters);
              } else if (saveParameters != null) {
                  parameters = (SourceParameters)saveParameters.clone();
              }
              parameters = this.createParameters(parameters,
                                                 this.handlerName,
                                                 path,
                                                 this.applicationName);
              DocumentFragment fragment = this.getXML("/application" + path);
              if (fragment == null) {
                  // create empty fake fragment
                  fragment = DOMUtil.createDocument().createDocumentFragment();
              }
              ResourceConnector connector = null;
              try {
                  connector = (ResourceConnector)manager.lookup(ResourceConnector.ROLE);
                  connector.saveXML(saveResourceType, null,
                                    saveResourceName, parameters,
                                    fragment);
  
              } catch (ComponentException ce) {
                  throw new ProcessingException("Unable to lookup the resource connector.", ce);
              } finally {
                  manager.release( connector );
              }
  
          } // end synchronized
  
      }
  
      /**
       * Build parameters for loading and saving of application data
       */
      public SourceParameters createParameters(SourceParameters parameters,
                                                 String             myHandler,
                                                 String             path,
                                                 String             appName)
      throws ProcessingException {
          if (parameters == null) parameters = new SourceParameters();
  
          // add all elements from inside the handler data
          this.addParametersFromAuthenticationXML(myHandler,
                                                  "/data",
                                                  parameters);
  
          // add all top level elements from authentication
          this.addParametersFromAuthenticationXML(myHandler,
                                                  "",
                                                  parameters);
  
          // add application and path
          parameters.setSingleParameterValue("handler", myHandler);
          if (appName != null) parameters.setSingleParameterValue("application", appName);
          if (path != null) parameters.setSingleParameterValue("path", path);
  
          return parameters;
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/context/SessionContextProviderImpl.java
  
  Index: SessionContextProviderImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.context;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  import org.apache.cocoon.webapps.portal.PortalConstants;
  import org.apache.cocoon.webapps.portal.components.PortalManager;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.webapps.session.context.SessionContextProvider;
  
  import org.xml.sax.SAXException;
  
  /**
   *  Context provider for the portal context
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContextProviderImpl.java,v 1.4 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class SessionContextProviderImpl
  implements SessionContextProvider {
  
      /**
       * Get the context
       * @param name The name of the context
       * @param objectModel The objectModel of the current request.
       * @return The context
       * @throws ProcessingException If the context is not available.
       */
      public SessionContext getSessionContext(String name,
                                              Map objectModel,
                                              SourceResolver   resolver,
                                              ComponentManager manager)
      throws ProcessingException {
          SessionContext context = null;
          if (name.equals(PortalConstants.SESSION_CONTEXT_NAME) == true) {
              Request req = ObjectModelHelper.getRequest(objectModel);
              Session session = req.getSession(false);
              if (session != null) {
  
                  PortalManager portal = null;
                  try {
                      portal = (PortalManager)manager.lookup(PortalManager.ROLE);
                      // is this an external resource which wants access to a coplet?
                      String value = req.getParameter("portalcontext");
                      if (value != null) {
                          int sepOne, sepTwo;
                          sepOne = value.indexOf('_');
                          if (sepOne != -1) {
                              sepTwo = value.indexOf('_', sepOne+1);
                              if (sepTwo != -1) {
                                  String copletIdentifier = value.substring(0, sepOne);
                                  String copletID = value.substring(sepOne+1, sepTwo);
                                  String copletNumber = value.substring(sepTwo+1);
  
                                  if (copletIdentifier.equals("coplet") == true) {
                                      Map info = new HashMap(3);
                                      SessionContextImpl.copletInfo.set(info);
  
                                      SourceParameters pars = new SourceParameters();
                                      info.put(PortalConstants.COPLETINFO_PARAMETERS, pars);
                                      pars.setSingleParameterValue(PortalConstants.PARAMETER_ID, copletID);
                                      pars.setSingleParameterValue(PortalConstants.PARAMETER_NUMBER, copletNumber);
                                      pars.setSingleParameterValue(PortalConstants.PARAMETER_MEDIA,
                                          (String)req.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE));
  
                                      info.put(PortalConstants.COPLETINFO_STATUSPROFILE, portal.getStatusProfile());
                                      info.put(PortalConstants.COPLETINFO_PORTALURI, req.getRequestURI());
                                  }
                              }
                          }
                      } else {
                          if (SessionContextImpl.copletInfo.get() == null) {
                              throw new ProcessingException("Portal context not available outside a coplet.");
                          }
                      }
  
                      context = new SessionContextImpl(name, objectModel, portal);
                  } catch (SAXException se) {
                      throw new ProcessingException("SAXException", se);
                  } catch (IOException ioe) {
                      throw new ProcessingException("IOException", ioe);
                  } catch (ComponentException ce) {
                      throw new ProcessingException("Unable to lookup portal.", ce);
                  } finally {
                      manager.release(portal);
                  }
              }
          }
          return context;
      }
  }
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/context/SessionContextImpl.java
  
  Index: SessionContextImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.context;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.ext.LexicalHandler;
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.xml.sax.ext.LexicalHandler;
  
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.excalibur.source.SourceResolver;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  import org.apache.cocoon.webapps.portal.PortalConstants;
  import org.apache.cocoon.webapps.portal.components.PortalManager;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.connector.Resource;
  import org.apache.cocoon.webapps.session.context.SessionContext;
  import org.apache.cocoon.xml.IncludeXMLConsumer;
  import org.apache.cocoon.xml.dom.DOMBuilder;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  /**
   *  The portal context
   *
   *  This context allows access to various parts of a portal profile.
   *  The context provides reading of the following xml, if the current
   *  resource is running inside a portal module:
   * &lt;layout&gt;
   *     &lt;portal&gt;
   *         ...
   *     &lt;/portal&gt;
   *     &lt;coplets&gt;
   *         ...
   *     &lt;/coplets&gt;
   * &lt;/layout&gt;
   * &lt;configuration&gt;
   *     ...
   * &lt;/configuration&gt;
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionContextImpl.java,v 1.3 2002/07/12 11:25:58 cziegeler Exp $
  */
  public final class SessionContextImpl
  implements SessionContext {
  
      /* This contains all information about the currently processed coplet */
      public static ThreadLocal copletInfo = new ThreadLocal();
  
      /** The context name */
      private String   name;
  
      /** The attributes */
      private Map      attributes = new HashMap();
  
      /** The cached layoutDOM */
      private Document layoutDOM;
  
      /** The cached configurationDOM */
      private Document configurationDOM;
  
      /** The current profile */
      private Map      profile;
  
      /** All coplet parameters */
  
      private SourceParameters copletPars;
  
      /** The status profile */
      private Element  statusProfile;
  
      /** the coplet id */
      private String copletID;
  
      /** The number of the coplet */
      private String copletNumber;
  
      /** The profile ID */
      private String profileID;
  
      /** The portal URI */
      private String portalURI;
  
      /** The media type */
      private String mediaType;
  
      public SessionContextImpl(String  name,
                                Map     objectModel,
                                PortalManager portal)
      throws IOException, SAXException, ProcessingException {
          this.setup(name, null, null);
  
          // try to get the resource connector info
          Request request = ObjectModelHelper.getRequest(objectModel);
          Map info = (Map)SessionContextImpl.copletInfo.get();
          if (info != null) {
              SessionContextImpl.copletInfo.set(null);
              this.copletPars = (SourceParameters)info.get(PortalConstants.COPLETINFO_PARAMETERS);
              this.portalURI = (String)info.get(PortalConstants.COPLETINFO_PORTALURI);
              if (this.copletPars != null) {
                  this.copletID = this.copletPars.getParameter(PortalConstants.PARAMETER_ID);
                  this.copletNumber = this.copletPars.getParameter(PortalConstants.PARAMETER_NUMBER);
                  if (this.copletID != null && this.copletNumber != null) {
                      this.portalURI = this.portalURI + (this.portalURI.indexOf('?') == -1 ? '?' : '&')
                            + "portalcmd=update_" + this.copletID + "_" + this.copletNumber;
                  }
              }
              this.statusProfile = (Element)info.get(PortalConstants.COPLETINFO_STATUSPROFILE);
          }
          this.mediaType = (this.copletPars != null ? (String)copletPars.getParameter(PortalConstants.PARAMETER_MEDIA)
                                                    : (String)request.getAttribute(org.apache.cocoon.webapps.authentication.AuthenticationConstants.REQUEST_ATTRIBUTE_MEDIA_TYPE));
          // get the profile
  
          SessionContext context = portal.getContext(false);
          if (context != null) {
              if (context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE) != null) {
                  this.profileID = portal.getProfileID(PortalManager.BUILDTYPE_VALUE_ID,
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ROLE),
                    (String)context.getAttribute(PortalManager.ATTRIBUTE_PORTAL_ID), false);
                  this.profile = portal.retrieveProfile(this.profileID);
              }
          }
          this.getConfigurationDOM(portal);
      }
  
      /**
       * Get the name of the context
       */
      public String getName() {
          return this.name;
      }
  
      /**
       * Get the layout DOM
       */
      private void getLayoutDOM()
      throws ProcessingException {
          if (this.layoutDOM == null && this.profile != null) {
              try {
                  Map portalLayouts = (Map)this.profile.get(PortalConstants.PROFILE_PORTAL_LAYOUTS);
                  Map copletLayouts = (Map)this.profile.get(PortalConstants.PROFILE_COPLET_LAYOUTS);
                  DOMBuilder builder = new DOMBuilder();
                  builder.startDocument();
                  PortalManager.streamLayoutProfile(builder, portalLayouts, copletLayouts, this.mediaType);
                  builder.endDocument();
                  this.layoutDOM = builder.getDocument();
              } catch (SAXException local) {
                  throw new ProcessingException("Unable to get portal." + local, local);
              }
          }
      }
  
      /**
       * Get the configuration DOM
       */
      private void getConfigurationDOM(PortalManager portal)
      throws ProcessingException, IOException, SAXException {
          if (this.configurationDOM == null && portal != null) {
              try {
                  String contextID = null;
                  if (this.copletID != null && this.copletNumber != null) {
                      contextID = "coplet_"+copletID+"_"+copletNumber;
                  }
                  DOMBuilder builder = new DOMBuilder();
                  builder.startDocument();
                  portal.streamConfiguration(builder,
                                              this.portalURI,
                                              this.profileID,
                                              this.mediaType,
                                              contextID);
                  builder.endDocument();
                  this.configurationDOM = builder.getDocument();
              } catch (SAXException local) {
                  throw new ProcessingException("Unable to get portal." + local, local);
              }
          }
      }
  
      /* Set the context name */
      public void setup(String value, Resource load, Resource save) {
          name = value;
      }
  
      /**
       * Get the xml fragment
       */
      public synchronized DocumentFragment getXML(String path)
      throws ProcessingException {
          DocumentFragment result = null;
  
          if (path.startsWith("/") == true) path = path.substring(1);
          NodeList list = null;
  
          if (path == null || path.equals("") == true) {
              Document doc = DOMUtil.createDocument();
              result = doc.createDocumentFragment();
              this.getLayoutDOM();
              if (this.layoutDOM != null) {
                  result.appendChild(doc.importNode(this.layoutDOM.getDocumentElement(), true));
              }
              if (this.configurationDOM != null) {
                  result.appendChild(doc.importNode(this.configurationDOM.getDocumentElement(), true));
              }
  
              if (this.statusProfile != null) {
                  if (this.copletID != null && this.copletNumber != null) {
                      String statusPath = "customization/coplet[@id='"+copletID+"' and @number='"+copletNumber+"']";
                      try {
                          Node node = DOMUtil.getSingleNode(this.statusProfile, statusPath);
                          if (node != null) {
                              Element copletData = doc.createElementNS(null, "coplet-data");
                              NodeList childs = node.getChildNodes();
                              if (childs != null) {
                                  for(int l=0; l<childs.getLength(); l++) {
                                      copletData.appendChild(doc.importNode(childs.item(l), true));
                                  }
                              }
                              result.appendChild(copletData);
                          }
                      } catch (javax.xml.transform.TransformerException localException) {
                          throw new ProcessingException("TransformerException: " + localException, localException);
                      }
                  }
              }
          }
  
          if (path.equals("layout") == true
              || path.startsWith("layout/") == true) {
              try {
                  this.getLayoutDOM();
                  if (this.layoutDOM != null) list = DOMUtil.selectNodeList(this.layoutDOM, path);
              } catch (javax.xml.transform.TransformerException localException) {
                  throw new ProcessingException("TransformerException: " + localException, localException);
              }
          }
  
          if (path.equals("configuration") == true
              || path.startsWith("configuration/") == true) {
              try {
                  if (this.configurationDOM != null) list = DOMUtil.selectNodeList(this.configurationDOM, path);
              } catch (javax.xml.transform.TransformerException localException) {
                  throw new ProcessingException("TransformerException: " + localException, localException);
              }
          }
  
          if (path.startsWith("coplet-data/") == true
              || path.equals("coplet-data") == true) {
  
              if (this.statusProfile != null) {
                  if (this.copletID != null && this.copletNumber != null) {
                      String statusPath = "customization/coplet[@id='"+copletID+"' and @number='"+copletNumber+"']";
                      if (path.startsWith("coplet-data/") == true) {
                          statusPath = statusPath + path.substring(11);
                      }
                      try {
                          list = DOMUtil.selectNodeList(this.statusProfile, statusPath);
                      } catch (javax.xml.transform.TransformerException localException) {
                          throw new ProcessingException("TransformerException: " + localException, localException);
                      }
                  }
              }
          }
  
          if (list != null && list.getLength() > 0) {
              Document doc = DOMUtil.createDocument();
              result = doc.createDocumentFragment();
  
              for(int i = 0; i < list.getLength(); i++) {
  
                  // the found node is either an attribute or an element
                  if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
                      // if it is an attribute simple create a new text node with the value of the attribute
                      result.appendChild(doc.createTextNode(list.item(i).getNodeValue()));
                  } else {
                      // now we have an element
                      // copy all children of this element in the resulting tree
                      NodeList childs = list.item(i).getChildNodes();
                      if (childs != null) {
                          for(int m = 0; m < childs.getLength(); m++) {
                              result.appendChild(doc.importNode(childs.item(m), true));
                          }
                      }
                  }
              }
          }
  
          return result;
      }
  
  
      /**
       * Set the xml
       */
      public synchronized void setXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          if (path != null) {
              if (path.startsWith("/") == true) path = path.substring(1);
              if (path.startsWith("coplet-data/") == true
                  || path.equals("coplet-data") == true) {
  
                  if (this.statusProfile != null) {
                      if (this.copletID != null && this.copletNumber != null) {
                          String statusPath = "customization/coplet[@id='"+copletID+"' and @number='"+copletNumber+"']";
                          if (path.startsWith("coplet-data/") == true) {
                              statusPath = statusPath + path.substring(11);
                          }
  
                          Node node = DOMUtil.selectSingleNode(this.statusProfile, statusPath);
                          if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
                              // now we have to serialize the fragment to a string and insert this
                              Attr attr = (Attr)node;
                              attr.setNodeValue(DOMUtil.getValueOfNode(fragment));
                          } else {
  
                              // remove old childs
                              while (node.hasChildNodes() == true) {
                                  node.removeChild(node.getFirstChild());
                              }
  
                              // Insert new childs
                              NodeList childs = fragment.getChildNodes();
                              if (childs != null && childs.getLength() > 0) {
                                  for(int i = 0; i < childs.getLength(); i++) {
                                      Node n = this.statusProfile.getOwnerDocument().importNode(childs.item(i), true);
                                      node.appendChild(n);
                                  }
                              }
                          }
  
                          if (this.copletPars.getParameter(PortalConstants.PARAMETER_PERSISTENT, "false").equals("true") == true) {
                              this.profile.put(PortalConstants.PROFILE_SAVE_STATUS_FLAG, "true");
                          }
                      }
                  }
              }
          }
  
      }
  
      /**
       * Append a document fragment at the given path. The implementation of this
       * method is context specific.
       * Usually the children of the fragment are appended as new children of the
       * node specified by the path.
       * If the path is not existent it is created.
       */
      public synchronized void appendXML(String path, DocumentFragment fragment)
      throws ProcessingException {
          throw new ProcessingException("appendXML() not implemented.");
      }
  
      /**
       * Remove nodes
       */
      public synchronized void removeXML(String path)
      throws ProcessingException {
          throw new ProcessingException("removeXML() not implemented.");
      }
  
      /**
       * Get a copy the first node specified by the path.
       */
      public synchronized Node getSingleNode(String path)
      throws ProcessingException {
          Node result = null;
  
          throw new ProcessingException("getSingleNode() not implemented.");
          //return result;
      }
  
      /**
       * Get a copy all the nodes specified by the path.
       */
      public synchronized NodeList getNodeList(String path)
      throws ProcessingException {
          NodeList result = null;
          throw new ProcessingException("getNodeList() not implemented.");
          /*return result;*/
      }
  
      /**
       * Set the value of a node. The node is copied before insertion.
       */
      public synchronized void setNode(String path, Node node)
      throws ProcessingException {
          throw new ProcessingException("setNode() not implemented.");
      }
  
  
      /**
       * Set a context attribute. If value is null the attribute is removed.
       */
      public synchronized void setAttribute(String key, Object value) {
          if (value == null) {
              attributes.remove(key);
          } else {
              attributes.put(key, value);
          }
      }
  
      /**
       * Get a context attribute. If the attribute is not available return null
       */
      public synchronized Object getAttribute(String key) {
          return attributes.get(key);
      }
  
      /**
       * Get a context attribute. If the attribute is not available the defaultObject is returned
       */
      public synchronized Object getAttribute(String key, Object defaultObject) {
          Object value = attributes.get(key);
          if (value == null) value = defaultObject;
          return value;
      }
  
      /**
       * Get the value of this node. This is similiar to the xsl:value-of
       * function. If the node does not exist, <code>null</code> is returned.
       */
      public synchronized String getValueOfNode(String path)
      throws ProcessingException {
          String value = null;
  
          throw new ProcessingException("getValueOfNode() not implemented.");
  
          /*return value;*/
      }
  
      /**
       * Set the value of a node.
       */
      public synchronized void setValueOfNode(String path, String value)
      throws ProcessingException {
          throw new ProcessingException("setValueOfNode() not implemented.");
      }
  
      /**
       * Stream the XML directly to the handler. This streams the contents of getXML()
       * to the given handler without creating a DocumentFragment containing a copy
       * of the data
       */
      public synchronized boolean streamXML(String path,
                             ContentHandler contentHandler,
                             LexicalHandler lexicalHandler)
      throws SAXException, ProcessingException {
          boolean  streamed = false;
          DocumentFragment fragment = this.getXML(path);
          if (fragment != null) {
              streamed = true;
              IncludeXMLConsumer.includeNode(fragment, contentHandler, lexicalHandler);
          }
          return streamed;
      }
  
      /**
       * Try to load XML into the context.
       * If the context does not provide the ability of loading,
       * an exception is thrown.
       */
      public void loadXML(String path,
                          SourceParameters   parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support loading.");
      }
  
      /**
       * Try to save XML from the context.
       * If the context does not provide the ability of saving,
       * an exception is thrown.
       */
      public void saveXML(String path,
                          SourceParameters   parameters,
                          Map                objectModel,
                          SourceResolver     resolver,
                          ComponentManager   manager)
      throws SAXException, ProcessingException, IOException {
          throw new ProcessingException("The context " + this.name + " does not support saving.");
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/components/AbstractSessionComponent.java
  
  Index: AbstractSessionComponent.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.components;
  
  import org.apache.avalon.excalibur.pool.Recyclable;
  import org.apache.excalibur.source.SourceParameters;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.Recomposable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.ResourceNotFoundException;
  import org.apache.cocoon.components.RequestLifecycleComponent;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  import org.w3c.dom.DocumentFragment;
  import org.xml.sax.SAXException;
  import java.io.IOException;
  import java.util.Map;
  
  /**
   * The base class for all components
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AbstractSessionComponent.java,v 1.3 2002/07/31 13:13:31 stephan Exp $
  */
  public abstract class AbstractSessionComponent extends AbstractLogEnabled
      implements Component, Composable, Recomposable, Recyclable, RequestLifecycleComponent {
  
      private SessionManager    sessionManager;
      private ResourceConnector resourceConnectorComponent;
  
      protected ComponentManager manager;
  
      /** The current object model */
      protected Map     objectModel;
  
      /** The current source resolver */
      protected SourceResolver resolver;
  
      protected Request          request;
      protected Response         response;
  
  
      /**
       * Composer interface. Get the Avalon ComponentManager.
       */
      public void compose(ComponentManager manager) {
          this.manager = manager;
      }
  
      /**
       * Recomposable
       */
      public void recompose( ComponentManager componentManager )
      throws ComponentException {
          this.recycle();
          this.manager = componentManager;
      }
  
      /**
       * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
       * used to process the request.
       *  Set up the SessionManager component.
       *  This method is automatically called for each request. Do not invoke
       *  this method by hand.
       */
      public void setup(SourceResolver resolver, Map objectModel)
      throws ProcessingException, SAXException, IOException {
          this.objectModel = objectModel;
          this.resolver    = resolver;
          this.request = ObjectModelHelper.getRequest(objectModel);
          this.response = ObjectModelHelper.getResponse(objectModel);
      }
  
      /**
       * Get the SessionManager component
       */
      protected SessionManager getSessionManager()
      throws ProcessingException {
          if (this.sessionManager == null) {
              try {
                  this.sessionManager = (SessionManager)this.manager.lookup(SessionManager.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of SessionManager component.", ce);
              }
          }
          return this.sessionManager;
      }
  
      /**
       * Get the resource connector
       */
      protected ResourceConnector getResourceConnector()
      throws ProcessingException {
          if (this.resourceConnectorComponent == null) {
              try {
                  this.resourceConnectorComponent = (ResourceConnector)this.manager.lookup(ResourceConnector.ROLE);
              } catch (ComponentException ce) {
                  throw new ProcessingException("Error during lookup of resource connector.", ce);
              }
          }
          return this.resourceConnectorComponent;
      }
  
      /**
       * Recycle
       */
      public void recycle() {
          if (this.manager != null) {
              this.manager.release(this.sessionManager);
              this.manager.release(this.resourceConnectorComponent);
          }
          this.sessionManager = null;
          this.resourceConnectorComponent = null;
          this.objectModel = null;
          this.resolver = null;
          this.request = null;
          this.response = null;
      }
  
      /**
       * Load a resource.
       * The resource connector usually throws a ResourceNotFound exception
       * when a pipeline is not found. This exception is catched here
       * and rethrown as a usual ProcessingException with the given message!
       */
      public DocumentFragment loadXML(int                resourceType,
                                      Parameters         typeParameters,
                                      String             resourceIdentifier,
                                      SourceParameters   resourceParameters,
                                      String             errorMessage)
      throws ProcessingException {
          try {
              return this.getResourceConnector().loadXML(resourceType, typeParameters,
                                                         resourceIdentifier, resourceParameters);
          } catch (ResourceNotFoundException rnfe) {
              throw new ProcessingException(errorMessage, rnfe);
          }
      }
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/components/SessionManager.java
  
  Index: SessionManager.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.components;
  
  import java.io.*;
  import java.util.*;
  import java.util.jar.*;
  
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Recomposable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.excalibur.pool.Recyclable;
  
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.RequestLifecycleComponent;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.session.SessionConstants;
  import org.apache.cocoon.webapps.session.context.*;
  import org.apache.cocoon.webapps.session.connector.*;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.XMLUtils;
  import org.apache.cocoon.xml.dom.DOMUtil;
  
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.Element;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.Text;
  import org.xml.sax.SAXException;
  
  /**
   *  This is the basic session component.
   *
   *  The main purpose of this component is session handling, maintaining contexts
   *  and providing system management functions.
   *  The session information is divided into session contexts.
   *
   *  Transaction management<p>
   *  </p>
   *  Transactions are a series of get/set calls to a sessuib context which must
   *  be seen as atomic (single modification).
   *  We distingish between reading and writing. Usually parallel reading is
   *  allowed but if one thread wants to write, no other can read or write.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionManager.java,v 1.8 2002/09/05 06:14:23 cziegeler Exp $
  */
  public final class SessionManager
  extends AbstractLogEnabled
  implements Composable, Component, Recomposable, Recyclable, RequestLifecycleComponent {
  
      /** Avalon role */
      public static final String ROLE = SessionManager.class.getName();;
  
      /** This session attribute is used to store the information for the inputxml tags */
      private static final String ATTRIBUTE_INPUTXML_STORAGE= "org.apache.cocoon.webapps.session.InputXMLStorage";
  
      /** The <code>ComponentManager</code> */
      private ComponentManager manager;
  
      /** The request */
      private Request    request;
      /** The response */
      private Response   response;
      /** The object model */
      private Map        objectModel;
      /** The resolver */
      private SourceResolver resolver;
  
      /** SessionContexts */
      private Map  contexts;
      /** TransactionStates of the session contexts */
      private Map  transactionStates;
  
      /** Session contexts delivered by a provider */
      private Map  deliveredContexts;
  
      /** Registered context provider */
      private static Map contextProvider = new HashMap();
  
      /* The list of reserved contexts */
      static private String[] reservedContextNames = {"session",
                                                      "context"};
      /** Init the class,
       *  add the provider for the temp context
       */
      static {
          // add the provider for the portal context
          SessionContextProvider provider = new StandardSessionContextProvider();
          try {
              SessionManager.addSessionContextProvider(provider, SessionConstants.TEMPORARY_CONTEXT);
              SessionManager.addSessionContextProvider(provider, SessionConstants.REQUEST_CONTEXT);
              SessionManager.addSessionContextProvider(provider, SessionConstants.RESPONSE_CONTEXT);
          } catch (ProcessingException local) {
              throw new RuntimeException("Unable to register provider for standard contexts.");
          }
      }
  
      /**
       * Avalon Composer Interface
       */
      public void compose(ComponentManager manager) {
          this.manager = manager;
      }
  
      /**
       * Recomposable
       */
      public void recompose( ComponentManager componentManager )
      throws ComponentException {
          this.manager = componentManager;
      }
  
      /**
       * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
       * used to process the request.
       *  Set up the SessionManager.
       *  This method is automatically called for each request. Do not invoke
       *  this method by hand.
       */
      public void setup(SourceResolver resolver, Map objectModel)
      throws ProcessingException, SAXException, IOException {
          // no sync required
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN setup objectModel=" + objectModel);
          }
          this.objectModel = objectModel;
          this.request = ObjectModelHelper.getRequest(objectModel);
          this.response = ObjectModelHelper.getResponse(objectModel);
          this.resolver = resolver;
  
          this.processInputFields();
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END setup");
          }
      }
  
      /**
       *  Recycling the SessionManager.
       *  This method is automatically called after each request. Do not invoke
       *  this method by hand.
       */
      public void recycle() {
          this.objectModel = null;
          this.request = null;
          this.response = null;
          this.contexts = null;
          if (this.deliveredContexts != null) {
              this.deliveredContexts.clear();
          }
          this.transactionStates = null;
          this.resolver = null;
      }
  
      /**
       * Get the list of contexts
       */
      protected Map getSessionContexts() {
          if (this.contexts == null) {
              Session session = this.getSession(true);
              this.contexts = (Map)session.getAttribute("org.apache.cocoon.webapps.session.context.SessionContext");
              if (this.contexts == null) {
                  this.contexts = new HashMap(5, 3);
                  session.setAttribute("org.apache.cocoon.webapps.session.context.SessionContext", this.contexts);
              }
          }
          return this.contexts;
      }
  
      /**
       * Get the list of contexts
       */
      protected Map getSessionContextsTransactionStates() {
          if (this.transactionStates == null) {
              Session session = this.getSession(true);
              this.transactionStates = (Map)session.getAttribute("org.apache.cocoon.webapps.session.context.TransactionState");
              if (this.transactionStates == null) {
                  this.transactionStates = new HashMap(5, 3);
                  session.setAttribute("org.apache.cocoon.webapps.session.context.TransactionState", this.transactionStates);
              }
          }
          return this.transactionStates;
      }
  
      /**
       * Checks if the context name is a reserved context.
       */
      static boolean isReservedContextName(String name) {
          // synchronized (not needed)
          int     i, l;
          boolean found;
          found = false;
          i = 0;
          l = reservedContextNames.length;
          while (i < l && found == false) {
              found = reservedContextNames[i].equals(name);
              i++;
          }
          if (found == false) {
              found = (contextProvider.get(name) != null);
          }
          return found;
      }
  
      /**
       * Add a context provider.
       */
      public static synchronized void addSessionContextProvider(SessionContextProvider provider,
                                                                String                 contextName)
      throws ProcessingException {
          if (contextName != null && provider != null) {
              if (isReservedContextName(contextName) == true) {
                  throw new ProcessingException("Unable to register context '"+contextName+"' : Already registered.");
              }
              contextProvider.put(contextName, provider);
          } else {
              throw new ProcessingException("Unable to add new provider: Name or provider info missing.");
          }
      }
  
      /**
       * Get a reserved context
       */
      protected boolean existsReservedContext(String name) {
          // synchronized (not needed)
          SessionContext context = null;
          SessionContextProvider provider = (SessionContextProvider)contextProvider.get(name);
          if (provider != null) {
              if ( null != this.deliveredContexts ) {
                  context = (SessionContext)this.deliveredContexts.get(name);
              }
          }
  
          return (context != null);
      }
  
      /**
       * Get a reserved context
       */
      protected SessionContext getReservedContext(String name)
      throws ProcessingException {
          // synchronized (not needed)
          SessionContext context = null;
          SessionContextProvider provider = (SessionContextProvider)contextProvider.get(name);
          if (provider != null) {
              if ( null != this.deliveredContexts ) {
                  context = (SessionContext)this.deliveredContexts.get(name);
              }
              if (context == null) {
                  if ( null == this.deliveredContexts ) {
                      this.deliveredContexts = new HashMap(5);
                  }
                  context = provider.getSessionContext(name,
                                                       this.objectModel,
                                                       this.resolver,
                                                       this.manager);
                  if (context != null) this.deliveredContexts.put(name, context);
              }
          }
  
          return context;
      }
  
      /**
       *  Create a new session for the user.
       *  A new session is created for this user. If the user has already a session,
       *  no new session is created and the old one is returned.
       */
      public Session createSession() {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN createSession");
          }
          Session session = this.getSession(true);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END createSession session=" + session);
          }
          return session;
      }
  
      /**
       * Get the session for the current user.
       * If the user has no session right now, <CODE>null</CODE> is returned.
       * If createFlag is true, the session is created if it does not exist.
       */
      public Session getSession(boolean createFlag) {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getSession create=" + createFlag);
          }
          Session session = this.request.getSession(createFlag);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getSession session=" + session);
          }
  
          return session;
      }
  
      /**
       *  Terminate the current session.
       *  If the user has a session, this session is terminated and all of its
       *  data is deleted.
       *  @param force If this is set to true the session is terminated, if
       *                   it is set to false, the session is only terminated
       *                   if no session context is available.
       */
      public void terminateSession(boolean force) {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN terminateSession force="+force);
          }
  
          Session session = request.getSession(false);
          if (session != null) {
              if (force == true
                  || this.hasSessionContext() == false) {
                  synchronized(session) {
                      session.invalidate();
                  }
              }
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END terminateSession");
          }
      }
  
      /**
       *  Create a new public context in the session.
       *  Create a new public session context for this user. If this context
       *  already exists no new context is created and the old one will be used
       *  instead.
       */
      public SessionContext createContext(String name, String loadURI, String saveURI)
      throws IOException, SAXException, ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN createContext name=" + name +
                                     "load=" + loadURI +
                                     "save=" + saveURI);
          }
          // test arguments
          Session session = this.getSession(false);
          if (session == null) {
              throw new IllegalArgumentException("CreateContext: Session is required");
          }
          if (name == null) {
              throw new IllegalArgumentException("CreateContext: Name is required");
          }
  
          SessionContext context;
          synchronized(session) {
              // test for reserved context
              if (SessionManager.isReservedContextName(name) == true) {
                  throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be created manually.");
              }
  
              Map contexts = this.getSessionContexts();
              if (this.existsContext(name) == true) {
                  context = this.getContext(name);
              } else {
                  context = new SimpleSessionContext();
                  Resource loadResource = (loadURI == null) ? null : new Resource(this.resolver, loadURI);
                  Resource saveResource = (saveURI == null) ? null : new Resource(this.resolver, saveURI);
                  context.setup(name, loadResource, saveResource);
                  contexts.put(name, context);
                  this.getSessionContextsTransactionStates().put(context, new TransactionState());
              }
          }
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END createContext context="+context);
          }
  
          return context;
      }
  
      /**
       *  Delete a public context in the session.
       *  If the context exists for this user, it and all of its information
       *  is deleted.
       */
      public void deleteContext(String name)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN deleteContext name=" + name);
          }
  
  
          // test arguments
          if (name == null) {
              throw new IllegalArgumentException("SessionManager.deleteContext: Name is required");
          }
          if (SessionManager.isReservedContextName(name) == true) {
              throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be deleted manually.");
          }
          Session session = this.getSession(false);
          if (session == null) {
              throw new IllegalArgumentException("SessionManager.deleteContext: Session is required");
          }
  
          synchronized(session) {
              final Map contexts = this.getSessionContexts();
              if (contexts.containsKey(name) == true) {
                  SessionContext context = (SessionContext)contexts.get(name);
                  contexts.remove(name);
                  this.getSessionContextsTransactionStates().remove(context);
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END deleteContext");
          }
      }
  
      /**
       * Get information from the context.
       * A document fragment containg the xml data stored in the session context
       * with the given name is returned. If the information is not available,
       * <CODE>null</CODE> is returned.
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying which data to get.
       * @return A DocumentFragment containing the data or <CODE>null</CODE>
       */
      public DocumentFragment getContextFragment(String  contextName,
                                                       String  path)
      throws ProcessingException  {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN getContextFragment name=" + contextName + ", path=" + path);
          }
  
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.getContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.getContextFragment: Path is required");
          }
  
          SessionContext context;
          if (SessionManager.isReservedContextName(contextName) == true) {
              context = this.getReservedContext(contextName);
          } else {
              Session session = this.getSession(false);
              if (session == null) {
                  throw new IllegalArgumentException("SessionManager.getContextFragment: Session is required for context " + contextName);
              }
              context = this.getContext(contextName);
          }
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.getContextFragment: Context '" + contextName + "' not found.");
          }
  
          DocumentFragment frag;
          frag = context.getXML(path);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END getContextFragment documentFragment=" + (frag == null ? "null" : XMLUtils.serializeNodeToXML(frag)));
          }
          return frag;
      }
  
      /**
       * Stream public context data.
       * The document fragment containing the data from a path in the
       * given context is streamed to the consumer.
       *
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying which data to get.
       *
       * @return If the data is available <code>true</code> is returned,
       *         otherwise <code>false</code> is returned.
       */
      public boolean streamContextFragment(String  contextName,
                                                 String  path,
                                                 XMLConsumer consumer)
      throws SAXException, ProcessingException  {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN streamContextFragment name=" + contextName + ", path=" + path + ", consumer"+consumer);
          }
          boolean streamed = false;
  
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.streamContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.streamContextFragment: Path is required");
          }
  
          SessionContext context = this.getContext(contextName);
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.streamContextFragment: Context '" + contextName + "' not found.");
          }
  
          streamed = context.streamXML(path, consumer, consumer);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END streamContextFragment streamed=" + streamed);
          }
          return streamed;
      }
  
      /**
       * Set data in a public context.
       * The document fragment containing the data is set at the given path in the
       * public session context.
       *
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying where to set the data.
       * @param fragment    The DocumentFragment containing the data.
       *
       */
      public void setContextFragment(String  contextName,
                                           String  path,
                                           DocumentFragment fragment)
      throws ProcessingException  {
          // synchronized via context
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN setContextFragment name=" + contextName + ", path=" + path +
                 ", fragment=" + (fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment)));
          }
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.setContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.setContextFragment: Path is required");
          }
          if (fragment == null) {
              throw new IllegalArgumentException("SessionManager.setContextFragment: Fragment is required");
          }
  
          // get context
          SessionContext context = this.getContext(contextName);
  
          // check context
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.setContextFragment: Context '" + contextName + "' not found.");
          }
  
          context.setXML(path, fragment);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END setContextFragment");
          }
      }
  
      /**
       * Append data in a public context.
       * The document fragment containing the data is appended at the given
       * path in the public session context.
       *
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying where to append the data.
       * @param fragment    The DocumentFragment containing the data.
       *
       */
      public void appendContextFragment(String  contextName,
                                              String  path,
                                              DocumentFragment fragment)
      throws ProcessingException  {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN appendContextFragment name=" + contextName +
                                ", path=" + path +
                                ", fragment=" + (fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment)));
          }
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.appendContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.appendContextFragment: Path is required");
          }
          if (fragment == null) {
              throw new IllegalArgumentException("SessionManager.appendContextFragment: Fragment is required");
          }
  
          // get context
          SessionContext context = this.getContext(contextName);
  
          // check context
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.appendContextFragment: Context '" + contextName + "' not found.");
          }
  
          context.appendXML(path, fragment);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END appendContextFragment");
          }
      }
  
      /**
       * Merge data in a public context.
       * The document fragment containing the data is merged at the given
       * path in the public session context.
       *
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying where to merge the data.
       * @param fragment    The DocumentFragment containing the data.
       *
       */
      public void mergeContextFragment(String  contextName,
                                             String  path,
                                             DocumentFragment fragment)
      throws ProcessingException  {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN mergeContextFragment name=" + contextName + ", path=" + path +
                  ", fragment=" + (fragment == null ? "null" : XMLUtils.serializeNodeToXML(fragment)));
          }
  
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.mergeContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.mergeContextFragment: Path is required");
          }
          if (fragment == null) {
              throw new IllegalArgumentException("SessionManager.mergeContextFragment: Fragment is required");
          }
  
          // get context
          SessionContext context = this.getContext(contextName);
  
          // check context
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.mergeContextFragment: Context '" + contextName + "' not found.");
          }
  
          Node contextNode = context.getSingleNode(path);
          if (contextNode == null) {
              // no merge required
              context.setXML(path, fragment);
          } else {
              this.importNode(contextNode, fragment, false);
              context.setNode(path, contextNode);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END mergeContextFragment");
          }
      }
  
      /**
       * Remove data in a public context.
       * The data specified by the path is removed from the public session context.
       *
       * @param contextName The name of the public context.
       * @param path        XPath expression specifying where to merge the data.
       *
       */
      public void removeContextFragment(String  contextName,
                                              String  path)
      throws ProcessingException  {
          // synchronized via context
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN removeContextFragment name=" + contextName + ", path=" + path);
          }
          // test arguments
          if (contextName == null) {
              throw new IllegalArgumentException("SessionManager.removeContextFragment: Name is required");
          }
          if (path == null) {
              throw new IllegalArgumentException("SessionManager.removeContextFragment: Path is required");
          }
  
          // get context
          SessionContext context = this.getContext(contextName);
  
          // check context
          if (context == null) {
              throw new IllegalArgumentException("SessionManager.removeContextFragment: Context '" + contextName + "' not found.");
          }
  
          context.removeXML(path);
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END removeContextFragment");
          }
      }
  
      /**
       * Import nodes. If preserve is set to true, the nodes
       * marked with cocoon:preserve are always imported
       * overwriting others!
       */
      private void importNode(Node profile, Node delta, boolean preserve) {
          // no sync req
          NodeList profileChilds = null;
          NodeList deltaChilds   = delta.getChildNodes();
          int      i, len;
          int      m, l;
          boolean  found;
          Node     currentDelta = null;
          Node     currentProfile = null;
  
          len = deltaChilds.getLength();
          for(i = 0; i < len; i++) {
              currentDelta = deltaChilds.item(i);
              if (currentDelta.getNodeType() == Node.ELEMENT_NODE) {
                  // search the delta node in the profile
                  profileChilds = profile.getChildNodes();
                  l = profileChilds.getLength();
                  m = 0;
                  found = false;
                  while (found == false && m < l) {
                      currentProfile = profileChilds.item(m);
                      if (currentProfile.getNodeType() == Node.ELEMENT_NODE
                          && currentProfile.getNodeName().equals(currentDelta.getNodeName()) == true) {
  
                          // now we have found a node with the same name
                          // next: the attributes must match also
                          found = DOMUtil.compareAttributes((Element)currentProfile, (Element)currentDelta);
                      }
                      if (found == false) m++;
                  }
                  if (found == true) {
                      // this is not new
  
                      if (preserve == true
                          && ((Element)currentDelta).hasAttributeNS(SessionConstants.SESSION_NAMESPACE_URI, "preserve")
                          && ((Element)currentDelta).getAttributeNS(SessionConstants.SESSION_NAMESPACE_URI, "preserve").equalsIgnoreCase("true")) {
                          // replace the original with the delta
                          profile.replaceChild(profile.getOwnerDocument().importNode(currentDelta, true),
                                                currentProfile);
                      } else {
                          // do we have elements as children or text?
                          if (currentDelta.hasChildNodes() == true) {
                              currentDelta.normalize();
                              currentProfile.normalize();
                              // do a recursive call for sub elements
                              this.importNode((Element)currentProfile, (Element)currentDelta, preserve);
                              // and now the text nodes: Remove all from the profile and add all
                              // of the delta
                              NodeList childs = currentProfile.getChildNodes();
                              int      index, max;
                              max = childs.getLength();
                              for(index = max - 1; index >= 0; index--) {
                                  if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
                                      currentProfile.removeChild(childs.item(index));
                                  }
                              }
                              childs = currentDelta.getChildNodes();
                              max = childs.getLength();
                              for(index = 0; index < max; index++) {
                                  if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
                                      currentProfile.appendChild(currentProfile.getOwnerDocument()
                                       .createTextNode(childs.item(index).getNodeValue()));
                                  }
                              }
                          }
                      }
                  } else {
                      profile.appendChild(profile.getOwnerDocument().importNode(currentDelta, true));
                  }
              }
  
          }
  
      }
  
      /**
       * Get the url for the request.
       */
      public static String getURL(Request req) {
          // no need for synchronized
          boolean isDefaultPort = "http".equalsIgnoreCase(req.getScheme())
                                      && 80 == req.getServerPort();
          return req.getScheme() + "://" +
                 req.getServerName() +
                 (isDefaultPort ? "" : ":" + req.getServerPort()) +
                 req.getContextPath() +
                 req.getServletPath() +
                 (req.getPathInfo() == null ? "" : req.getPathInfo());
      }
  
      /**
       * Register input field and return the current value of the field.
       * This is a private method and should not be invoked directly.
       */
      public DocumentFragment registerInputField(String contextName,
                                                 String path,
                                                 String name,
                                                 String formName)
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN registerInputField context="+contextName+", path="+path+", name="+name+", formName="+formName);
          }
  
          // test arguments
          if (contextName == null) {
              throw new ProcessingException("SessionManager.registerInputField: Context Name is required");
          }
          if (path == null) {
              throw new ProcessingException("SessionManager.registerInputField: Path is required");
          }
          if (name == null) {
              throw new ProcessingException("SessionManager.registerInputField: Name is required");
          }
          if (formName == null) {
              throw new ProcessingException("SessionManager.registerInputField: Form is required");
          }
  
          DocumentFragment value = null;
          SessionContext context = this.getContext(contextName);
          if (context == null) {
              throw new ProcessingException("SessionManager.registerInputField: Context not found " + contextName);
          }
          Session session = this.getSession(false);
          if (session == null) {
              throw new ProcessingException("SessionManager.registerInputField: Session is required for context " + contextName);
          }
  
          synchronized(session) {
              Map inputFields = (Map)session.getAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE);
              if (inputFields == null) {
                  inputFields = new HashMap(10);
                  session.setAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE, inputFields);
              }
              inputFields.put(name, new Object[] {context, path, formName});
              value = context.getXML(path);
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END registerInputField value="+value);
          }
          return value;
      }
  
      /**
       * Process all input fields.
       * The fields are removed even if the request did not contain
       * any values.
       * This is a private method and should not be invoked directly.
       */
      public void processInputFields()
      throws ProcessingException {
          // synchronized
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN processInputFields");
          }
  
          final String formName = this.request.getParameter(SessionConstants.SESSION_FORM_PARAMETER);
          if ( null != formName ) {
              final Session session = this.getSession(false);
              if (session != null) {
                  synchronized(session) {
                      final Map inputFields = (Map)session.getAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE);
                      if (inputFields != null) {
                          final Enumeration keys = this.request.getParameterNames();
                          String   currentKey;
                          Object[] contextAndPath;
  
                          while (keys.hasMoreElements() == true) {
                              currentKey = (String)keys.nextElement();
                              if (inputFields.containsKey(currentKey) == true) {
                                  contextAndPath = (Object[])inputFields.get(currentKey);
                                  inputFields.remove(currentKey);
  
                                  SessionContext context = (SessionContext)contextAndPath[0];
                                  String path            = (String)contextAndPath[1];
  
                                  if (formName.equals(contextAndPath[2]) == true) {
                                      context.setXML(path,
                                                   this.getContextFragment(SessionConstants.REQUEST_CONTEXT, "/parameter/"+currentKey));
                                  }
                              }
                          }
                      }
                      // inputFields.clear();
                  }
              }
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END processInputFields");
          }
      }
  
      /**
       *  Get a public context.
       *  The session context with the given name is returned. If the context does
       *  not exist <CODE>null</CODE> is returned.
       */
      public synchronized SessionContext getContext(String name)
      throws ProcessingException {
          SessionContext context;
          if (SessionManager.isReservedContextName(name) == true) {
              context = this.getReservedContext(name);
          } else {
              Session session = this.getSession(false);
              if (session == null) {
                  throw new IllegalArgumentException("SessionManager.getContext: Session is required.");
              }
              synchronized (session) {
                  final Map contexts = this.getSessionContexts();
                  context = (SessionContext)contexts.get(name);
              }
          }
  
          return context;
      }
  
      /**
       * Check if a context exists
       */
      public synchronized boolean hasSessionContext() {
          Session session = this.getSession(false);
          if (session == null) {
              throw new IllegalArgumentException("SessionManager.hasSessionContext: Session is required.");
          }
          synchronized (session) {
              final Map contexts = this.getSessionContexts();
              return !(contexts.isEmpty());
          }
      }
  
      /**
       *  Check if a public context exists.
       *  If the session context with the given name exists, <CODE>true</CODE> is
       *  returned.
       */
      public synchronized boolean existsContext(String name) {
          Session session = this.getSession(false);
          if (session == null) {
              throw new IllegalArgumentException("SessionManager.existsContext: Session is required.");
          }
          synchronized (session) {
              final Map contexts = this.getSessionContexts();
              boolean result = contexts.containsKey(name);
              if (result == false && SessionManager.isReservedContextName(name) == true) {
                  result = this.existsReservedContext(name);
              }
              return result;
          }
      }
  
      private class TransactionState {
          /** number readers reading*/
          public int nr=0;
          /** number of readers total (reading or waiting to read)*/
          public int nrtotal=0;
          /** number writers writing, 0 or 1 */
          public int nw=0;
          /** number of writers total (writing or waiting to write)*/
          public int nwtotal=0;
      }
  
      /**
       *  Reset the transaction management state.
       */
      public void resetTransactions(SessionContext context) {
           TransactionState ts = (TransactionState)this.getSessionContextsTransactionStates().get(context);
          ts.nr=0;
          ts.nrtotal=0;
          ts.nw=0;
          ts.nwtotal=0;
      }
  
      /**
       *  Start a reading transaction.
       *  This call must always be matched with a stopReadingTransaction().
       *  Otherwise the session context is blocked.
       */
      public synchronized void startReadingTransaction(SessionContext context)
      throws ProcessingException {
           TransactionState ts = (TransactionState)this.getSessionContextsTransactionStates().get(context);
          ts.nrtotal++;
          while (ts.nw!=0) {
              try {
                  wait();
              } catch (InterruptedException local) {
                  throw new ProcessingException("Interrupted", local);
              }
          }
          ts.nr++;
      }
  
      /**
       *  Stop a reading transaction.
       *  This call must always be done for each startReadingTransaction().
       *  Otherwise the session context is blocked.
       */
      public synchronized void stopReadingTransaction(SessionContext context) {
          TransactionState ts = (TransactionState)this.getSessionContextsTransactionStates().get(context);
          ts.nr--;
          ts.nrtotal--;
          if (ts.nrtotal==0) notify();
      }
  
      /**
       *  Start a writing transaction.
       *  This call must always be matched with a stopWritingTransaction().
       *  Otherwise the session context is blocked.
       */
       public synchronized void startWritingTransaction(SessionContext context)
       throws ProcessingException {
           TransactionState ts = (TransactionState)this.getSessionContextsTransactionStates().get(context);
           ts.nwtotal++;
           while (ts.nrtotal+ts.nw != 0) {
              try {
                  wait();
              } catch (InterruptedException local) {
                  throw new ProcessingException("Interrupted", local);
              }
          }
          ts.nw=1;
       }
  
      /**
       *  Stop a writing transaction.
       *  This call must always be done for each startWritingTransaction().
       *  Otherwise the session context is blocked.
       */
      public synchronized void stopWritingTransaction(SessionContext context) {
          TransactionState ts = (TransactionState)this.getSessionContextsTransactionStates().get(context);
          ts.nw=0;
          ts.nwtotal--;
          notifyAll();
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/SessionConstants.java
  
  Index: SessionConstants.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session;
  
  /**
   * The <code>Constants</code> used throughout the core of the session management.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionConstants.java,v 1.1 2002/04/17 08:43:54 cziegeler Exp $
  */
  public interface SessionConstants {
  
      /** The namespace used by the session transformers */
      String SESSION_NAMESPACE_URI = "http://cocoon.apache.org/session/1.0";
  
      /** Reserved Context: Request context */
      String REQUEST_CONTEXT = "request";
  
      /** Reserved Context: Response context */
      String RESPONSE_CONTEXT= "response";
  
      /** Reserved Context: Temp */
      String TEMPORARY_CONTEXT = "temp";
  
      /** The request parameter name for the form handling */
      String SESSION_FORM_PARAMETER = "sessionform";
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/portal-fw/java/org/apache/cocoon/webapps/portal/acting/AuthAction.java
  
  Index: AuthAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.portal.acting;
  
  import java.util.Map;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.portal.components.PortalManager;
  
  /**
   *  This is the authentication action for the portal
   *  This action protecteds a pipeline by using a coplet ID.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AuthAction.java,v 1.1 2002/04/17 12:39:19 cziegeler Exp $
  */
  public final class AuthAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws Exception {
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("BEGIN act resolver="+resolver+
                                     ", objectModel="+objectModel+
                                     ", source="+source+
                                     ", par="+par);
          }
          final String copletID = par.getParameter("coplet", null);
  
          PortalManager portal = null;
          Map map = null;
  
          try {
              portal = (PortalManager)this.manager.lookup( PortalManager.ROLE );
              portal.configurationTest();
              if ( null != copletID) {
                  portal.checkAuthentication(redirector, copletID);
              }
  
          } finally {
              this.manager.release( portal );
          }
  
          if (this.getLogger().isDebugEnabled() == true) {
              this.getLogger().debug("END act map={}");
          }
          return EMPTY_MAP;
      }
  
  }
  
  
  1.5       +511 -1    xml-cocoon2/src/java/org/apache/cocoon/xml/dom/DOMUtil.java
  
  Index: DOMUtil.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/xml/dom/DOMUtil.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DOMUtil.java	24 Sep 2002 11:49:21 -0000	1.4
  +++ DOMUtil.java	27 Sep 2002 09:05:18 -0000	1.5
  @@ -51,6 +51,7 @@
   package org.apache.cocoon.xml.dom;
   
   import org.apache.excalibur.source.SourceParameters;
  +import org.apache.xpath.XPathAPI;
   import org.apache.avalon.excalibur.xml.Parser;
   import org.apache.avalon.excalibur.xml.XMLizable;
   import org.apache.avalon.excalibur.xml.xpath.XPathProcessor;
  @@ -66,6 +67,11 @@
   import java.util.Iterator;
   import java.util.Map;
   
  +import javax.xml.parsers.DocumentBuilder;
  +import javax.xml.parsers.DocumentBuilderFactory;
  +import javax.xml.parsers.ParserConfigurationException;
  +import javax.xml.transform.TransformerException;
  +
   /**
    *  This class is an utitity class for miscellaneous DOM functions, like
    *  getting and setting values of nodes.
  @@ -603,6 +609,510 @@
   
            // Give up: hope it's a string or has a meaningful string representation
            valueOf(parent, String.valueOf(v));
  +    }
  +
  +    /**
  +     * Use an XPath string to select a single node. XPath namespace
  +     * prefixes are resolved from the context node, which may not
  +     * be what you want (see the next method).
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @return The first node found that matches the XPath, or null.
  +     *
  +     * @throws TransformerException
  +     */
  +    public static Node getSingleNode(Node contextNode, String str)
  +    throws TransformerException {
  +        String[] pathComponents = buildPathArray(str);
  +        if (pathComponents == null) {
  +            return XPathAPI.selectSingleNode(contextNode, str);
  +        } else {
  +            return getFirstNodeFromPath(contextNode, pathComponents, false);
  +        }
  +    }
  +
  +    /**
  +     * Return the <CODE>Node</CODE> from the DOM Node <CODE>rootNode</CODE>
  +     * using the XPath expression <CODE>path</CODE>.
  +     * If the node does not exist, it is created and then returned.
  +     * This is a very simple method for creating new nodes. If the
  +     * XPath contains selectors ([,,,]) or "*" it is of course not
  +     * possible to create the new node. So if you use such XPaths
  +     * the node must exist beforehand.
  +     * An simple exception is if the expression contains attribute
  +     * test to values (e.g. [@id = 'du' and @number = 'you'],
  +     * the attributes with the given values are added. The attributes
  +     * must be separated with 'and'.
  +     * Another problem are namespaces: XPath requires sometimes selectors for
  +     * namespaces, e.g. : /*[namespace-uri()="uri" and local-name()="name"]
  +     * Creating such a node with a namespace is not possible right now as we use
  +     * a very simple XPath parser which is not able to parse all kinds of selectors
  +     * correctly.
  +     *
  +     * @param rootNode The node to start the search.
  +     * @param path     XPath expression for searching the node.
  +     * @return         The node specified by the path.
  +     * @throws ProcessingException If no path is specified or the XPath engine fails.
  +     */
  +    public static Node selectSingleNode(Node rootNode, String path)
  +    throws ProcessingException {
  +        // Now we have to parse the string
  +        // First test:  path? rootNode?
  +        if (path == null) {
  +            throw new ProcessingException("XPath is required.");
  +        }
  +        if (rootNode == null) return rootNode;
  +
  +        if (path.length() == 0 || path.equals("/") == true) return rootNode;
  +
  +        // now the first "quick" test is if the node exists using the
  +        // full XPathAPI
  +        try {
  +            Node testNode = getSingleNode(rootNode, path);
  +            if (testNode != null) return testNode;
  +        } catch (javax.xml.transform.TransformerException local) {
  +            throw new ProcessingException("Transforming exception during selectSingleNode with path: '"+path+"'. Exception: " + local, local);
  +        }
  +
  +        if (path.startsWith("/") == true) path = path.substring(1); // remove leading "/"
  +        if (path.endsWith("/") == true) { // remove ending "/" for root node
  +            path = path.substring(0, path.length() - 1);
  +        }
  +
  +        // now step through the nodes!
  +        Node parent = rootNode;
  +        int pos;
  +        int posSelector;
  +        do {
  +            pos = path.indexOf("/"); // get next separator
  +            posSelector = path.indexOf("[");
  +            if (posSelector != -1 && posSelector < pos) {
  +                posSelector = path.indexOf("]");
  +                pos = path.indexOf("/", posSelector);
  +            }
  +
  +            String  nodeName;
  +            boolean isAttribute = false;
  +            if (pos != -1) { // found separator
  +                nodeName = path.substring(0, pos); // string until "/"
  +                path = path.substring(pos+1); // rest of string after "/"
  +            } else {
  +                nodeName = path;
  +            }
  +
  +            // test for attribute spec
  +            if (nodeName.startsWith("@") == true) {
  +                isAttribute = true;
  +            }
  +
  +            Node singleNode;
  +            try {
  +                singleNode = getSingleNode(parent, nodeName);
  +            } catch (javax.xml.transform.TransformerException localException) {
  +                throw new ProcessingException("XPathUtil.selectSingleNode: " + localException.getMessage(), localException);
  +            }
  +
  +            // create node if necessary
  +            if (singleNode == null) {
  +                Node newNode;
  +                // delete XPath selectors
  +                int posSelect = nodeName.indexOf("[");
  +                String XPathExp = null;
  +                if (posSelect != -1) {
  +                    XPathExp = nodeName.substring(posSelect+1, nodeName.length()-1);
  +                    nodeName = nodeName.substring(0, posSelect);
  +                }
  +                if (isAttribute == true) {
  +                    try {
  +                        newNode = getOwnerDocument(rootNode).createAttributeNS(null, nodeName.substring(1));
  +                        ((Element)parent).setAttributeNodeNS((org.w3c.dom.Attr)newNode);
  +                        parent = newNode;
  +                    } catch (DOMException local) {
  +                        throw new ProcessingException("Unable to create new DOM node: '"+nodeName+"'.", local);
  +                    }
  +                } else {
  +                    try {
  +                        newNode = getOwnerDocument(rootNode).createElementNS(null, nodeName);
  +                    } catch (DOMException local) {
  +                        throw new ProcessingException("Unable to create new DOM node: '"+nodeName+"'.", local);
  +                    }
  +                    if (XPathExp != null) {
  +                        java.util.List attrValuePairs = new java.util.ArrayList(4);
  +                        boolean noError = true;
  +
  +                        String attr;
  +                        String value;
  +                        // scan for attributes
  +                        java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(XPathExp, "= ");
  +                        while (tokenizer.hasMoreTokens() == true) {
  +                            attr = tokenizer.nextToken();
  +                            if (attr.startsWith("@") == true) {
  +                                if (tokenizer.hasMoreTokens() == true) {
  +                                    value = tokenizer.nextToken();
  +                                    if (value.startsWith("'") && value.endsWith("'")) value = value.substring(1, value.length()-1);
  +                                    if (value.startsWith("\"") && value.endsWith("\"")) value = value.substring(1, value.length()-1);
  +                                    attrValuePairs.add(attr.substring(1));
  +                                    attrValuePairs.add(value);
  +                                } else {
  +                                    noError = false;
  +                                }
  +                            } else if (attr.trim().equals("and") == false) {
  +                                noError = false;
  +                            }
  +                        }
  +                        if (noError == true) {
  +                            for(int l=0;l<attrValuePairs.size();l=l+2) {
  +                                ((Element)newNode).setAttributeNS(null, (String)attrValuePairs.get(l),
  +                                                                (String)attrValuePairs.get(l+1));
  +                            }
  +                        }
  +                    }
  +                    parent.appendChild(newNode);
  +                    parent = newNode;
  +                }
  +            } else {
  +                parent = singleNode;
  +            }
  +        } while (pos != -1);
  +        return parent;
  +    }
  +
  +    /**
  +     * Get the value of the node specified by the XPath.
  +     * This works similar to xsl:value-of. If the node does not exist <CODE>null</CODE>
  +     * is returned.
  +     *
  +     * @param root The node to start the search.
  +     * @param path XPath search expression.
  +     * @return     The value of the node or <CODE>null</CODE>
  +     */
  +    public static String getValueOf(Node root, String path)
  +    throws ProcessingException {
  +        if (path == null) {
  +            throw new ProcessingException("Not a valid XPath: " + path);
  +        }
  +        if (root == null) return null;
  +        if (path.startsWith("/") == true) path = path.substring(1); // remove leading "/"
  +        if (path.endsWith("/") == true) { // remove ending "/" for root node
  +            path = path.substring(0, path.length() - 1);
  +        }
  +
  +        try {
  +            Node node = getSingleNode(root, path);
  +            if (node != null) {
  +                return getValueOfNode(node);
  +            }
  +        } catch (javax.xml.transform.TransformerException localException) {
  +            throw new ProcessingException("XPathUtil.selectSingleNode: " + localException.getMessage(), localException);
  +        }
  +        return null;
  +    }
  +
  +    /**
  +     * Get the value of the node specified by the XPath.
  +     * This works similar to xsl:value-of. If the node is not found
  +     * the <CODE>defaultValue</CODE> is returned.
  +     *
  +     * @param root The node to start the search.
  +     * @param path XPath search expression.
  +     * @param defaultValue The default value if the node does not exist.
  +     * @return     The value of the node or <CODE>defaultValue</CODE>
  +     */
  +    public static String getValueOf(Node root,
  +                                    String path,
  +                                    String defaultValue)
  +    throws ProcessingException {
  +        String value = getValueOf(root, path);
  +        if (value == null) value = defaultValue;
  +
  +        return value;
  +    }
  +
  +    /**
  +     * Get the boolean value of the node specified by the XPath.
  +     * This works similar to xsl:value-of. If the node exists and has a value
  +     * this value is converted to a boolean, e.g. "true" or "false" as value
  +     * will result into the corresponding boolean values.
  +     *
  +     * @param root The node to start the search.
  +     * @param path XPath search expression.
  +     * @return     The boolean value of the node.
  +     * @throws ProcessingException If the node is not found.
  +     */
  +    public static boolean getValueAsBooleanOf(Node root, String path)
  +    throws ProcessingException {
  +        String value = getValueOf(root, path);
  +        if (value == null) {
  +            throw new ProcessingException("No such node: " + path);
  +        }
  +        return Boolean.valueOf(value).booleanValue();
  +    }
  +
  +    /**
  +     * Get the boolean value of the node specified by the XPath.
  +     * This works similar to xsl:value-of. If the node exists and has a value
  +     * this value is converted to a boolean, e.g. "true" or "false" as value
  +     * will result into the corresponding boolean values.
  +     * If the node does not exist, the <CODE>defaultValue</CODE> is returned.
  +     *
  +     * @param root The node to start the search.
  +     * @param path XPath search expression.
  +     * @param defaultValue Default boolean value.
  +     * @return     The value of the node or <CODE>defaultValue</CODE>
  +     */
  +    public static boolean getValueAsBooleanOf(Node root,
  +                                              String path,
  +                                              boolean defaultValue)
  +    throws ProcessingException {
  +        String value = getValueOf(root, path);
  +        if (value == null) {
  +            return defaultValue;
  +        }
  +        return Boolean.valueOf(value).booleanValue();
  +    }
  +
  +    /**
  +     * Create a new empty DOM document.
  +     */
  +    public static Document createDocument()
  +    throws ProcessingException {
  +        try {
  +            DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
  +            documentFactory.setNamespaceAware(true);
  +            documentFactory.setValidating(false);
  +            DocumentBuilder docBuilder = documentFactory.newDocumentBuilder();
  +            return docBuilder.newDocument();
  +        } catch (ParserConfigurationException pce) {
  +            throw new ProcessingException("Creating document failed.", pce);
  +        }
  +    }
  +
  +    /**
  +     *  Use an XPath string to select a nodelist.
  +     *  XPath namespace prefixes are resolved from the contextNode.
  +     *
  +     *  @param contextNode The node to start searching from.
  +     *  @param str A valid XPath string.
  +     *  @return A NodeIterator, should never be null.
  +     *
  +     * @throws TransformerException
  +     */
  +    public static NodeList selectNodeList(Node contextNode, String str)
  +    throws TransformerException {
  +        String[] pathComponents = buildPathArray(str);
  +        if (pathComponents == null) {
  +            return XPathAPI.selectNodeList(contextNode, str);
  +        } else {
  +            return getNodeListFromPath(contextNode, pathComponents);
  +        }
  +    }
  +
  +    /**
  +     * Build the input for the get...FromPath methods. If the XPath
  +     * expression cannot be handled by the methods, <code>null</code>
  +     * is returned.
  +     */
  +    public static String[] buildPathArray(String xpath) {
  +        String[] result = null;
  +        if (xpath != null && xpath.charAt(0) != '/') {
  +            // test
  +            int components = 1;
  +            int i, l;
  +            l = xpath.length();
  +            boolean found = false;
  +            i = 0;
  +            while (i < l && found == false) {
  +                switch (xpath.charAt(i)) {
  +                    case '[' : found = true; break;
  +                    case '(' : found = true; break;
  +                    case '*' : found = true; break;
  +                    case '@' : found = true; break;
  +                    case ':' : found = true; break;
  +                    case '/' : components++;
  +                    default: i++;
  +                }
  +            }
  +            if (found == false) {
  +                result = new String[components];
  +                if (components == 1) {
  +                    result[components-1] = xpath;
  +                } else {
  +                    i = 0;
  +                    int start = 0;
  +                    components = 0;
  +                    while (i < l) {
  +                        if (xpath.charAt(i) == '/') {
  +                            result[components] = xpath.substring(start, i);
  +                            start = i+1;
  +                            components++;
  +                        }
  +                        i++;
  +                    }
  +                    result[components] = xpath.substring(start);
  +                }
  +            }
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * Use a path to select the first occurence of a node. The namespace
  +     * of a node is ignored!
  +     * @param contextNode The node starting the search.
  +     * @param path        The path to search the node. The
  +     *                    contextNode is searched for a child named path[0],
  +     *                    this node is searched for a child named path[1]...
  +     * @param create      If a child with the corresponding name is not found
  +     *                    and create is set, this node will be created.
  +    */
  +    public static Node getFirstNodeFromPath(Node contextNode,
  +                                            final String[] path,
  +                                            final boolean  create) {
  +        if (contextNode == null || path == null || path.length == 0)
  +            return contextNode;
  +        // first test if the node exists
  +        Node item = getFirstNodeFromPath(contextNode, path, 0);
  +        if (item == null && create == true) {
  +            int i = 0;
  +            NodeList childs;
  +            boolean found;
  +            int m, l;
  +            while (contextNode != null && i < path.length) {
  +                childs = contextNode.getChildNodes();
  +                found = false;
  +                if (childs != null) {
  +                    m = 0;
  +                    l = childs.getLength();
  +                    while (found == false && m < l) {
  +                        item = childs.item(m);
  +                        if (item.getNodeType() == Document.ELEMENT_NODE
  +                            && item.getLocalName().equals(path[i]) == true) {
  +                            found = true;
  +                            contextNode = item;
  +                        }
  +                        m++;
  +                    }
  +                }
  +                if (found == false) {
  +                    Element e = contextNode.getOwnerDocument().createElementNS(null, path[i]);
  +                    contextNode.appendChild(e);
  +                    contextNode = e;
  +                }
  +                i++;
  +            }
  +            item = contextNode;
  +        }
  +        return item;
  +    }
  +
  +    /**
  +     * Private helper method for getFirstNodeFromPath()
  +     */
  +    private static Node getFirstNodeFromPath(final Node contextNode,
  +                                             final String[] path,
  +                                             final int      startIndex) {
  +        int i = 0;
  +        NodeList childs;
  +        boolean found;
  +        int l;
  +        Node item = null;
  +
  +        childs = contextNode.getChildNodes();
  +        found = false;
  +        if (childs != null) {
  +            i = 0;
  +            l = childs.getLength();
  +            while (found == false && i < l) {
  +                item = childs.item(i);
  +                if (item.getNodeType() == Document.ELEMENT_NODE
  +                    && path[startIndex].equals(item.getLocalName()!=null?item.getLocalName():item.getNodeName()) == true) {
  +                    if (startIndex == path.length-1) {
  +                        found = true;
  +                    } else {
  +                        item = getFirstNodeFromPath(item, path, startIndex+1);
  +                        if (item != null) found = true;
  +                    }
  +                }
  +                if (found == false) {
  +                    i++;
  +                }
  +            }
  +            if (found == false) {
  +                item = null;
  +            }
  +        }
  +        return item;
  +    }
  +
  +    /**
  +     * Use a path to select all occurences of a node. The namespace
  +     * of a node is ignored!
  +     * @param contextNode The node starting the search.
  +     * @param path        The path to search the node. The
  +     *                    contextNode is searched for a child named path[0],
  +     *                    this node is searched for a child named path[1]...
  +     */
  +    public static NodeList getNodeListFromPath(Node contextNode,
  +                                                 String[] path) {
  +        if (contextNode == null) return new NodeListImpl();
  +        if (path == null || path.length == 0) {
  +            return new NodeListImpl(new Node[] {contextNode});
  +        }
  +        NodeListImpl result = new NodeListImpl();
  +        try {
  +            getNodesFromPath(result, contextNode, path, 0);
  +        } catch (NullPointerException npe) {
  +            // this NPE is thrown because the parser is not configured
  +            // to use DOM Level 2
  +            throw new NullPointerException("XMLUtil.getNodeListFromPath() did catch a NullPointerException."+
  +                          "This might be due to a missconfigured XML parser which does not use DOM Level 2."+
  +                          "Make sure that you use the XML parser shipped with Cocoon.");
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * Helper method for getNodeListFromPath()
  +     */
  +    private static void getNodesFromPath(final NodeListImpl result,
  +                                         final Node contextNode,
  +                                         final String[] path,
  +                                         final int startIndex) {
  +        final NodeList childs = contextNode.getChildNodes();
  +        int m, l;
  +        Node item;
  +        if (startIndex == (path.length-1)) {
  +            if (childs != null) {
  +                m = 0;
  +                l = childs.getLength();
  +                while (m < l) {
  +                    item = childs.item(m);
  +                    if (item.getNodeType() == Document.ELEMENT_NODE) {
  +                        // Work around: org.apache.xerces.dom.ElementImpl doesn't handle getLocalName() correct
  +                        if (path[startIndex].equals(item.getLocalName()!=null?item.getLocalName():item.getNodeName()) == true) {
  +                            result.addNode(item);
  +                        }
  +                    }
  +                    m++;
  +                }
  +            }
  +        } else {
  +            if (childs != null) {
  +                m = 0;
  +                l = childs.getLength();
  +                while (m < l) {
  +                    item = childs.item(m);
  +                    if (item.getNodeType() == Document.ELEMENT_NODE) {
  +                        // Work around: org.apache.xerces.dom.ElementImpl doesn't handle getLocalName() correct
  +                        if (path[startIndex].equals(item.getLocalName()!=null?item.getLocalName():item.getNodeName()) == true) {
  +                            getNodesFromPath(result, item, path, startIndex+1);
  +                        }
  +                    }
  +                    m++;
  +                }
  +            }
  +        }
       }
   
   }
  
  
  
  1.1                  xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/acting/SessionAction.java
  
  Index: SessionAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.session.acting;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.acting.ComposerAction;
  import org.apache.cocoon.Constants;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.webapps.session.components.SessionManager;
  
  /**
   * This action creates and terminates a session.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: SessionAction.java,v 1.1 2002/04/17 08:43:54 cziegeler Exp $
  */
  public final class SessionAction
  extends ComposerAction
  implements ThreadSafe {
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters par)
      throws ProcessingException {
          SessionManager sessionManager = null;
          try {
              sessionManager = (SessionManager)this.manager.lookup(SessionManager.ROLE);
              final String action = par.getParameter("action", "create");
              if ( action.equals("create") == true ) {
                  sessionManager.createSession();
              } else if ( action.equals("terminate") == true ) {
                  final String mode = par.getParameter("mode", "immediately");
                  if ( mode.equals("immediately") == true) {
                      sessionManager.terminateSession(true);
                  } else if ( mode.equals("if-unused") == true ) {
                      sessionManager.terminateSession(false);
                  } else {
                      throw new ProcessingException("Unknown mode " + mode + " for action " + action);
                  }
              } else {
                  throw new ProcessingException("Unknown action: " + action);
              }
          } catch (ComponentException ce) {
              throw new ProcessingException("Error during lookup of sessionManager component.", ce);
          } finally {
              this.manager.release( sessionManager );
          }
  
          return EMPTY_MAP;
      }
  
  }
  
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/generation/ConfigurationGenerator.java
  
  Index: ConfigurationGenerator.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication.generation;
  
  
  import java.io.IOException;
  import org.xml.sax.SAXException;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.generation.ComposerGenerator;
  import org.apache.cocoon.webapps.authentication.components.AuthenticationManager;
  
  /**
   *  This is the authentication Configuration Generator.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: ConfigurationGenerator.java,v 1.1 2002/04/17 10:04:52 cziegeler Exp $
  */
  public final class ConfigurationGenerator
  extends ComposerGenerator {
  
      public void generate()
      throws IOException, SAXException, ProcessingException {
  
          this.xmlConsumer.startDocument();
          AuthenticationManager authManager = null;
          try {
              authManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE);
  
              if (authManager.isAuthenticated() == true) {
                  authManager.showConfiguration(this.xmlConsumer, this.source);
              }
          } catch (ComponentException ex) {
              throw new ProcessingException("ComponentManagerException: " + ex, ex);
          } finally {
              this.manager.release( authManager );
          }
  
          this.xmlConsumer.endDocument();
      }
  
  }
  
  
  1.1                  xml-cocoon2/src/blocks/authentication-fw/java/org/apache/cocoon/webapps/authentication/AuthenticationConstants.java
  
  Index: AuthenticationConstants.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.webapps.authentication;
  
  /**
   * The <code>Constants</code> used throughout the core of the authentication
   * framework.
   *
   * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
   * @version CVS $Id: AuthenticationConstants.java,v 1.4 2002/08/15 14:51:27 cziegeler Exp $
  */
  public interface AuthenticationConstants {
  
      String REQUEST_ATTRIBUTE_HANDLER_NAME     = "org.apache.cocoon.webapps.authentication.HandlerName";
      String REQUEST_ATTRIBUTE_APPLICATION_NAME = "org.apache.cocoon.webapps.authentication.ApplicationName";
      String REQUEST_ATTRIBUTE_MEDIA_TYPE       = "org.apache.cocoon.webapps.authentication.MediaType";
  
      /** The name of the session attribute storing the context */
      String SESSION_ATTRIBUTE_CONTEXT_NAME = "org.apache.cocoon.webapps.authentication.SessionContext";
  
      /** The name of the authentication context. */
      String SESSION_CONTEXT_NAME = "authentication";
  
      /** Logout mode: session is terminated immediately */
      int LOGOUT_MODE_IMMEDIATELY = 0;
      
      /** Logout mode: session is terminated if not used anymore (by the 
       * session or the authentication framework */
      int LOGOUT_MODE_IF_UNUSED= 1;
  
      /** Logout mode: session is terminated immediately */
      int LOGOUT_MODE_IF_NOT_AUTHENTICATED = 2;
  }
  
  
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org