Package org.apache.cocoon.sunshine.sunrise

Source Code of org.apache.cocoon.sunshine.sunrise.SunRise

/*

============================================================================
                   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  <stefano@apache.org>. For more  information on the Apache
Software Foundation, please see <http://www.apache.org/>.

*/
package org.apache.cocoon.sunshine.sunrise;

import java.io.IOException;
import java.util.*;

import org.apache.excalibur.source.SourceParameters;
import org.apache.excalibur.source.SourceUtil;
import org.apache.avalon.framework.CascadingRuntimeException;
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.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.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLUtils;

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;

import org.apache.cocoon.sunshine.SunShine;
import org.apache.cocoon.sunshine.context.SessionContext;
import org.apache.cocoon.sunshine.components.AbstractSunShineComponent;
import org.apache.cocoon.sunshine.context.SessionContextProvider;
import org.apache.cocoon.sunshine.context.SimpleSessionContext;
import org.apache.cocoon.sunshine.connector.ResourceConnector;
import org.apache.cocoon.sunshine.connector.Resource;
import org.apache.cocoon.xml.IncludeXMLConsumer;
import org.apache.cocoon.sunshine.xml.XMLUtil;
import org.apache.cocoon.sunshine.sunrise.context.SessionContextImpl;
import org.apache.cocoon.sunshine.sunrise.context.SessionContextProviderImpl;

/**
*  This is the basis sunShine component.
*
* @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
* @version CVS $Id: SunRise.java,v 1.5.2.6 2002/11/21 15:06:50 sylvain Exp $
*/
public final class SunRise
extends AbstractSunShineComponent
implements Configurable {

    /** The Avalon Role */
    public static final String ROLE = "org.apache.cocoon.sunshine.sunrise.SunRise";

    /** Request parameter */
    public static final String REQ_PARAMETER_STATE = "sunrisestate";
    public static final String REQ_PARAMETER_ROLE  = "sunriserole";
    public static final String REQ_PARAMETER_ID    = "sunriseid";
    public static final String REQ_PARAMETER_USER  = "sunriseuser";

    private static final String SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE = "org.apache.cocoon.sunshine.sunrise.adminrole";

    /** All Handlers hashed by their name */
    private Map     configuredHandlers;

    /** All handlers of the current user */
    private Map     userHandlers;

    /** The handler configuration */
    private Configuration  configuration;

    /** 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 sunSpot context
     */
    static {
        // add the provider for the sunSpot context
        contextProvider = new SessionContextProviderImpl();
        try {
            SunShine.addSessionContextProvider(contextProvider, Constants.SESSION_CONTEXT_NAME);
        } catch (ProcessingException local) {
            throw new CascadingRuntimeException("Unable to register provider for sunRise context.", local);
        }
    }

    /**
     * Set the configuration for sunRise.
     * The configuration is set global once when the AuthAction is
     * conigured, allowing other components to use the sunRise
     * instance
     */
    private static Configuration sunRiseConfiguration;
    public static void setConfiguration(Configuration configuration) {
        sunRiseConfiguration = configuration;
    }

    /**
     * Recyclable
     */
    public void recycle() {
        super.recycle();
        this.applicationName = null;
        this.application = null;
        this.handler = null;
        this.handlerName = null;
        this.userHandlers = null;
    }

    /**
     * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
     * used to process the request.
     *  Set up the sunShine 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 {
        super.setup(resolver, objectModel);

        // synchronized
        this.configureHandlers(SunRise.sunRiseConfiguration);

        // 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(Constants.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) throw new ConfigurationException("sunRise needs mediatypes configuration");
        this.defaultMediaType = mediaConf.getAttribute("default");
        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;
        this.configuredHandlers = null;
    }

    /**
     * Configure the sunRise handler
     */
    private void configureHandlers(Configuration configuration)
    throws ProcessingException {
        if (this.configuredHandlers == null
            || configuration.equals(this.configuration) == false) {
            this.configuration = configuration; // store the configuration
            try {
                this.configuredHandlers = new Hashtable(3, 2);

                Configuration handlersConfiguration = configuration.getChild("handlers", false);
                Configuration currentHandlerConf;

                if (handlersConfiguration != null) {
                    Configuration[] handlerConfs = handlersConfiguration.getChildren("handler");
                    if (handlerConfs != null) {
                        for(int i = 0; i < handlerConfs.length; i++) {

                            currentHandlerConf = handlerConfs[i];
                            String        value;

                            // get name
                            String name = currentHandlerConf.getAttribute("name");

                            // test if handler is unique
                            if (this.configuredHandlers.get(name) != null) {
                                throw new ConfigurationException("Handler names must be unique: " + name);
                            }

                            // create handler
                            Handler currentHandler = new Handler(name);

                            // store handler
                            this.configuredHandlers.put(name, currentHandler);

                            currentHandler.configure(this.resolver, this.request, currentHandlerConf);
                        }
                    }
                }
            } catch (IOException local) {
                throw new ProcessingException("IOException: " + local, local);
            } catch (SAXException local) {
                throw new ProcessingException("SAXException: " + local, local);
            } catch (ConfigurationException local) {
                throw new ProcessingException("ConfigurationException: " + local, local);
            }
        }

    }

    /**
     * Store the handlers in the session of the user
     */
    private void storeHandlers()
    throws ProcessingException {
        final Request req = ObjectModelHelper.getRequest( this.objectModel );
        final Session session = req.getSession();
        Map myHandlers = (Map)session.getAttribute(Constants.SESSION_ATTRIBUTE_HANDLERS);
        if (myHandlers == null) {
            this.userHandlers = this.configuredHandlers;
            session.setAttribute(Constants.SESSION_ATTRIBUTE_HANDLERS, this.userHandlers);
            this.configuredHandlers = null;
            this.configureHandlers(this.configuration);
        }
    }

    /**
     * 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;
    }

    /**
     * Create a new context
     */
    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.getSunRiseSessionContext(true);

        synchronized (context) {

            String state = this.request.getParameter(SunRise.REQ_PARAMETER_STATE);
            if (state == null) {
                state = (isAdmin == true ? "main" : "seluser");
            }

            if (state.equals("addrole") == true) {
                String role = this.request.getParameter(SunRise.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(SunRise.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, null);
            }

            if (state.equals("delrole") == true) {
                try {
                    String role = this.request.getParameter(SunRise.REQ_PARAMETER_ROLE);
                    if (role != null) {
                        // first delete user
                        DocumentFragment userDF = this.getUsers(role, null);
                        NodeList         users   = null;
                        if (userDF != null) users = XMLUtil.selectNodeList(userDF, "users/user");
                        if (users != null) {
                            for(int i = 0; i < users.getLength(); i++) {
                                this.deleteUser(role, XMLUtil.getValueOf(users.item(i), "ID"), null);
                            }
                        }
                        this.deleteRole(role, null);
                    }
                    context.setAttribute(SunRise.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(SunRise.REQ_PARAMETER_ROLE);
                    id   = this.request.getParameter(SunRise.REQ_PARAMETER_ID);
                    user = this.request.getParameter(SunRise.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("sunrisedeluser");
                        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(SunRise.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(SunRise.REQ_PARAMETER_ROLE);
                    id   = this.request.getParameter(SunRise.REQ_PARAMETER_ID);
                }
                if (role != null && id != null) {
                    context.setAttribute(SunRise.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);

                    // include users
                    DocumentFragment userDF = this.getUsers(role, id);
                    Element          users   = null;
                    try {
                        if (userDF != null) users = (Element)XMLUtil.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(SunRise.REQ_PARAMETER_ROLE);
                    id   = this.request.getParameter(SunRise.REQ_PARAMETER_ID);
                }
                if (role != null && id != null) {
                    context.setAttribute(SunRise.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);

                    // include users
                    DocumentFragment userDF = this.getUsers(role, id);
                    Element          users   = null;
                    try {
                        if (userDF != null) users = (Element)XMLUtil.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(SunRise.REQ_PARAMETER_ROLE);
                context.setAttribute(SunRise.SESSION_CONTEXT_ATTRIBUTE_ADMIN_ROLE, role);
                // include users
                DocumentFragment userDF = this.getUsers(role, null);
                Node             users   = null;
                try {
                    if (userDF != null) users = XMLUtil.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 = XMLUtil.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(SunRise.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 = false;

            // get the session context
            // if no session context: not authenticated
            SessionContext context = this.getSunRiseSessionContext(false);
            if (context != null) {
                synchronized(context) {

                    try {
                        // is result in cache (= context attribute)
                        if (context.getAttribute("SUNRISE_ISAUTHENTICATED:" + name) != null) {
                            isAuthenticated = true;
                        } else {
                            DocumentFragment id = context.getXML("/" + name + "/authentication/ID");
                            isAuthenticated = (id != null);
                            if (isAuthenticated == true) {
                                // cache result
                                context.setAttribute("SUNRISE_ISAUTHENTICATED:" + name, "YES");
                            }
                        }
                    } catch (ProcessingException local) {
                        // ignore this for now
                        this.getLogger().error("isAuthenticated");
                        isAuthenticated = false;
                    }
                }
            }
        }

        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;

        // get user handlers (if available)
        final Request req = ObjectModelHelper.getRequest( this.objectModel );
        final Session session = req.getSession(false);
        if ( null != session ) {
            this.userHandlers = (Map)session.getAttribute(Constants.SESSION_ATTRIBUTE_HANDLERS);
        }

        // set the configuration for the handler
        final String newHandlerName = (String)this.request.getAttribute(Constants.REQUEST_ATTRIBUTE_HANDLER_NAME);
        final String newAppName     = (String)this.request.getAttribute(Constants.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) {
                if ( null != this.userHandlers) {
                    this.handler = (Handler)this.userHandlers.get(this.handlerName);
                } else {
                    this.handler = (Handler)this.configuredHandlers.get(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 sunrise
                    this.checkLoaded((SessionContextImpl)this.getSunShineComponent().getContext(Constants.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
        if ( null == name ) return null;
        if ( null != this.userHandlers ) {
            return (Handler)this.userHandlers.get( name );
        } else {
            return (Handler)this.configuredHandlers.get( name );
        }
    }

    /**
     * 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;

        final Handler myHandler = this.getHandler(loginHandlerName);
        if (this.getLogger().isInfoEnabled() == true) {
            this.getLogger().info("sunRise: 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) {
                    this.storeHandlers();

                    if (this.getLogger().isInfoEnabled() == true) {
                        this.getLogger().info("sunRise: Success 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.getSunRiseSessionContext(true);
                    if (this.getLogger().isDebugEnabled() == true) {
                        this.getLogger().debug("session created");
                    }
                    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("sunrise");
                        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.getSunShineComponent().getContext(Constants.SESSION_CONTEXT_NAME),
                                                        appHandler, "/");
                            } else {
                                loaded = appHandler.getIsLoaded(context);
                            }
                        }
                        myHandler.setApplicationsLoaded(context, loaded);

                    } // end sync
                }
            }
            if (isValid == false) {
                if (this.getLogger().isInfoEnabled() == true) {
                    this.getLogger().info("sunRise: Failed authentication using handler '" +  myHandler.getName()+"'");
                }
                // get the /authentication/data Node if available
                Node data = null;

                if (authenticationFragment != null) {
                    data = XMLUtil.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 = XMLUtil.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 sunRise SessionContext
     */
    private SessionContext getSunRiseSessionContext(boolean create)
    throws ProcessingException {
        // synchronized
        if (this.getLogger().isDebugEnabled() == true) {
            this.getLogger().debug("BEGIN getSunRiseSessionContext create=" + create);
        }
        SessionContext context = null;

        Session session = this.getSunShineComponent().getSession(create);
        if (session != null) {
            synchronized(session) {
                context = (SessionContext)session.getAttribute(Constants.SESSION_ATTRIBUTE_CONTEXT_NAME);
                if (context == null && create == true) {
                    context = new SimpleSessionContext();
                    context.setup(Constants.SESSION_CONTEXT_NAME, null, null);
                    session.setAttribute(Constants.SESSION_ATTRIBUTE_CONTEXT_NAME, context);
                }
            }
        }

        if (this.getLogger().isDebugEnabled() == true) {
            this.getLogger().debug("END getSunRiseSessionContext context=" + context);
        }
        return context;
    }

    /**
     * Logout from the given handler
     * Terminate session if required
     */
    public void logout(String  logoutHandlerName,
                       String  mode)
    throws ProcessingException {
        // synchronized via context
        if (this.getLogger().isDebugEnabled() == true) {
            this.getLogger().debug("BEGIN logout handler=" + logoutHandlerName +
                                   ", mode="+mode);
        }
        SessionContext context = this.getSunRiseSessionContext(false);

        if (context != null && logoutHandlerName != null) {

            // cached?
            if (context.getAttribute("SUNRISE_ISAUTHENTICATED:" + logoutHandlerName) != null) {
                context.setAttribute("SUNRISE_ISAUTHENTICATED:" + logoutHandlerName, null);
            }
            // remove context
            context.removeXML(logoutHandlerName);
            // FIXME (CZ): The sessionContextImpl should not be null, but
            //             it is sometimes. Why?
            SessionContextImpl sessionContextImpl = (SessionContextImpl)
                        this.getSunShineComponent().getContext(Constants.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);

            // reset application load status
            logoutHandler.setApplicationsLoaded(context, false);
            Iterator apps = logoutHandler.getApplications().values().iterator();
            ApplicationHandler current;
            while (apps.hasNext() == true) {
                current = (ApplicationHandler)apps.next();
                current.setIsLoaded(context, false);
            }

            final List handlerContexts = logoutHandler.getHandlerContexts();
            final Iterator iter = handlerContexts.iterator();
            while ( iter.hasNext() ) {
                final SessionContext deleteContext = (SessionContext) iter.next();
                this.getSunShineComponent().deleteContext( deleteContext.getName() );
            }
            logoutHandler.clearHandlerContexts();
        }

        if ( mode != null && mode.equalsIgnoreCase("terminateSession") ) {
            this.getSunShineComponent().terminateSession(true);
        }

        if (this.getLogger().isDebugEnabled() == true) {
            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.getSunShineComponent().getSession(false);
            synchronized(session) {

                try {
                    // create new context
                    context = this.getSunShineComponent().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 = XMLUtil.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.getSunShineComponent().getSession(true);
        synchronized(o) {

            if (appHandler.getIsLoaded(context) == 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(context, 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(context);
                }
                appHandler.getHandler().setApplicationsLoaded(context, 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.getSunRiseSessionContext(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.getSunRiseSessionContext(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(Constants.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 for sunRise.
*/
final class MediaType {

    String name;
    String useragent;

    MediaType(String name, String useragent) {
        this.name = name;
        this.useragent = useragent;
    }
}
TOP

Related Classes of org.apache.cocoon.sunshine.sunrise.SunRise

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.