Package org.apache.cocoon.portal.wsrp.adapter

Source Code of org.apache.cocoon.portal.wsrp.adapter.WSRPAdapter

/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.portal.wsrp.adapter;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;

import oasis.names.tc.wsrp.v1.types.BlockingInteractionResponse;
import oasis.names.tc.wsrp.v1.types.MarkupContext;
import oasis.names.tc.wsrp.v1.types.MarkupResponse;
import oasis.names.tc.wsrp.v1.types.MarkupType;
import oasis.names.tc.wsrp.v1.types.PortletContext;
import oasis.names.tc.wsrp.v1.types.PortletDescription;
import oasis.names.tc.wsrp.v1.types.SessionContext;
import oasis.names.tc.wsrp.v1.types.UpdateResponse;

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.wrapper.RequestParameters;
import org.apache.cocoon.portal.PortalManagerAspect;
import org.apache.cocoon.portal.PortalManagerAspectPrepareContext;
import org.apache.cocoon.portal.PortalManagerAspectRenderContext;
import org.apache.cocoon.portal.PortalService;
import org.apache.cocoon.portal.coplet.CopletData;
import org.apache.cocoon.portal.coplet.CopletInstanceData;
import org.apache.cocoon.portal.coplet.adapter.impl.AbstractCopletAdapter;
import org.apache.cocoon.portal.coplet.status.SizingStatus;
import org.apache.cocoon.portal.event.EventManager;
import org.apache.cocoon.portal.event.Receiver;
import org.apache.cocoon.portal.event.impl.ChangeCopletInstanceAspectDataEvent;
import org.apache.cocoon.portal.event.impl.FullScreenCopletEvent;
import org.apache.cocoon.portal.layout.Layout;
import org.apache.cocoon.portal.serialization.IncludingHTMLSerializer;
import org.apache.cocoon.portal.util.HtmlSaxParser;
import org.apache.cocoon.portal.wsrp.consumer.ConsumerEnvironmentImpl;
import org.apache.cocoon.portal.wsrp.consumer.ProducerDescription;
import org.apache.cocoon.portal.wsrp.consumer.ProducerRegistryImpl;
import org.apache.cocoon.portal.wsrp.consumer.Request;
import org.apache.cocoon.portal.wsrp.consumer.RequestImpl;
import org.apache.cocoon.portal.wsrp.consumer.RequiresConsumerEnvironment;
import org.apache.cocoon.portal.wsrp.consumer.RequiresPortalService;
import org.apache.cocoon.portal.wsrp.consumer.RequiresWSRPAdapter;
import org.apache.cocoon.portal.wsrp.consumer.SimplePortletWindowSession;
import org.apache.cocoon.portal.wsrp.consumer.UserContextProvider;
import org.apache.cocoon.portal.wsrp.consumer.WSRPRequestImpl;
import org.apache.cocoon.portal.wsrp.logging.WSRPLogManager;
import org.apache.cocoon.portal.wsrp.logging.WSRPLogger;
import org.apache.cocoon.servlet.CocoonServlet;
import org.apache.cocoon.util.ClassUtils;
import org.apache.cocoon.xml.AbstractXMLPipe;
import org.apache.cocoon.xml.AttributesImpl;
import org.apache.cocoon.xml.XMLUtils;
import org.apache.commons.lang.exception.NestableRuntimeException;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.wsrp4j.consumer.GroupSession;
import org.apache.wsrp4j.consumer.PortletDriver;
import org.apache.wsrp4j.consumer.PortletKey;
import org.apache.wsrp4j.consumer.PortletSession;
import org.apache.wsrp4j.consumer.Producer;
import org.apache.wsrp4j.consumer.SessionHandler;
import org.apache.wsrp4j.consumer.User;
import org.apache.wsrp4j.consumer.UserSession;
import org.apache.wsrp4j.consumer.WSRPPortlet;
import org.apache.wsrp4j.consumer.driver.PortletKeyImpl;
import org.apache.wsrp4j.consumer.driver.UserImpl;
import org.apache.wsrp4j.consumer.driver.WSRPPortletImpl;
import org.apache.wsrp4j.exception.ErrorCodes;
import org.apache.wsrp4j.exception.WSRPException;
import org.apache.wsrp4j.log.LogManager;
import org.apache.wsrp4j.util.Constants;
import org.apache.wsrp4j.util.WindowStates;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

/**
* Adapter to use wsrp-portlets as coplets <br/>
* It provides the wsrp support by initializing wsrp4j <br/>
* The aspect/adapter can be configured at the portal manager.<br/>
*
* @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
* @author <a href="mailto:malessandrini@s-und-n.de">Michel Alessandrini</a>
*
* @version $Id: WSRPAdapter.java 365359 2006-01-02 15:19:58Z cziegeler $
*/
public class WSRPAdapter
    extends AbstractCopletAdapter
    implements Contextualizable,
               PortalManagerAspect,
               Serviceable,
               Initializable,
               Disposable,
               Parameterizable,
               Receiver {

    /** Key to store the consumer map into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_CONSUMER_MAP = "wsrp-consumer-map";

    /** Key to store the portlet instance key into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_PORTLET_INSTANCE_KEY = "wsrp-portlet-instance-key";

    /** Key to store the portlet key into the coplet instance data objectt as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_PORTLET_KEY = "wsrp-portletkey";

    /** Key to store the wsrp user into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_USER = "wsrp-user";

    /** Key to store the layout for the wsrp portlet into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_LAYOUT = "wsrp-layout";

    /** Key to store the wsrp title into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_PORTLET_TITLE = "wsrp-title";

    /** Key to store the wsrp modes into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_PORTLET_MODES = "wsrp-modes";

    /** Key to store the window states into the coplet instance data object as a temporary attribute. */
    public static final String ATTRIBUTE_NAME_PORTLET_WINDOWSTATES = "wsrp-window-states";

    /** Unique name of the consumer. */
    public static final String CONSUMER_URL = "http://cocoon.apache.org/portal/wsrp-consumer";
   
    /** Name of the service. */
    public static final String consumerAgent = "Apache Cocoon Portal." + org.apache.cocoon.Constants.VERSION;
   
    /** The avalon context. */
    protected Context context;
   
    /** The consumer environment implementation. */
    protected ConsumerEnvironmentImpl consumerEnvironment;
   
    /** Stores the current coplet instance data per thread. */
    protected final ThreadLocal copletInstanceData = new ThreadLocal();

    /** The servlet configuration. */
    protected ServletConfig servletConfig;

    /** The service locator. */
    protected ServiceManager manager;

    /** The portal service. */
    protected PortalService service;

    /** The user context provider. */
    protected UserContextProvider userContextProvider;

    /** Location of the wsrp configuration. */
    protected String wsrpConfigLocation;

    /** Initialized? */
    protected boolean initialized = false;

    /** The wsrp configuration. */
    protected Configuration wsrpConfiguration;

    /** The configuration for this adapter. */
    protected Parameters parameters;

    /**
     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
     */
    public void contextualize(Context context) throws ContextException {
        this.context = context;
        try {
            this.servletConfig = (ServletConfig) context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG);
            // we have to somehow pass this component down to other components!
            // This is ugly, but it's the only chance for sofisticated component containers
            // that wrap component implementations!
            this.servletConfig.getServletContext().setAttribute(WSRPAdapter.class.getName(), this);
        } catch (ContextException ignore) {
            // we ignore the context exception
            // this avoids startup errors if the portal is configured for the CLI
            // environment
            this.getLogger().warn("The wsrp support is disabled as the servlet context is not available.", ignore);
        }
    }   

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
        EventManager eventManager = null;
        try {
            eventManager = (EventManager)this.manager.lookup(EventManager.ROLE);
            eventManager.subscribe(this);
        } finally {
            this.manager.release(eventManager);
        }
        this.service = (PortalService)this.manager.lookup(PortalService.ROLE);
        this.userContextProvider = (UserContextProvider)this.manager.lookup(UserContextProvider.ROLE);
    }

    /**
     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
     */
    public void parameterize(Parameters params) throws ParameterException {
        this.wsrpConfigLocation = params.getParameter("wsrp-config");
        this.parameters = params;
    }

    /**
     * Sets the <tt>WSRPLogger</tt>, the <tt>producerConfig</tt> and the <tt>consumerEnvironment</tt><br/>
     *
     * @see org.apache.avalon.framework.activity.Initializable#initialize()
     */
    public void initialize() throws Exception {
        LogManager.setLogManager(new WSRPLogManager(new WSRPLogger(this.getLogger())));
        this.consumerEnvironment = new ConsumerEnvironmentImpl();
        this.consumerEnvironment.init(this.service,
                                      this);
        consumerEnvironment.setConsumerAgent(consumerAgent);
    }

    /**
     * Removes all portlets, producers and users out of the <tt>consumerEnvironment</tt>-registries<br/>
     *
     * @see org.apache.avalon.framework.activity.Disposable#dispose()
     */
    public void dispose() {
        if ( this.consumerEnvironment != null ) {
            this.consumerEnvironment.getPortletRegistry().removeAllPortlets();

            this.consumerEnvironment.getProducerRegistry().removeAllProducers();

            this.consumerEnvironment.getUserRegistry().removeAllUsers();
        }
        if ( this.manager != null ) {
            EventManager eventManager = null;
            try {
                eventManager = (EventManager)this.manager.lookup(EventManager.ROLE);
                eventManager.unsubscribe(this);
            } catch (Exception ignore) {
                // let's ignore it
            } finally {
                this.manager.release(eventManager);
            }
            this.manager.release(this.service);
            this.manager.release(this.userContextProvider);
            this.service = null;
            this.userContextProvider = null;
            this.manager = null;
        }
        try {
            ContainerUtil.dispose(this.consumerEnvironment);
            this.consumerEnvironment = null;
        } catch (Throwable t) {
            this.getLogger().error("Destruction failed!", t);
        }
       
        if ( this.servletConfig != null ) {
            this.servletConfig.getServletContext().removeAttribute(WSRPAdapter.class.getName());
            this.servletConfig = null;
        }
    }

    /**
     * Gets the required information of the producer, user, wsrp-portlet, window-states, window-modes<br/>
     * and stores its into the copletInstanceData<br/>
     * After that it initiates the <tt>getServiceDescription()</tt>-call<br/>
     *
     * @see org.apache.cocoon.portal.coplet.adapter.impl.AbstractCopletAdapter#login(org.apache.cocoon.portal.coplet.CopletInstanceData)
     */
    public void login(CopletInstanceData coplet) {
        super.login(coplet);

        final CopletData copletData = coplet.getCopletData();

        // get the producer
        final String producerId = (String) copletData.getAttribute("producer-id");
        if ( producerId == null ) {
            // if the producer can't be found, we simply return
            this.getLogger().error("Producer not configured in wsrp coplet " + copletData.getId());
            return;           
        }
        final Producer producer = consumerEnvironment.getProducerRegistry().getProducer(producerId);
        if ( producer == null ) {
            // if the producer can't be found, we simply return
            this.getLogger().error("Producer with id " + producerId + " not found.");
            return;
        }

        // get the wsrp user and store it as an attribute on the instance
        final String currentUserID = this.service.getComponentManager().getProfileManager().getUser().getUserName();      
        User user = this.consumerEnvironment.getUserRegistry().getUser(currentUserID);
        if ( user == null ) {
            // create a new user
            user = new UserImpl(currentUserID);
            user.setUserContext(this.userContextProvider.createUserContext(currentUserID));
            this.consumerEnvironment.getUserRegistry().addUser(user);
        }
        coplet.setTemporaryAttribute(ATTRIBUTE_NAME_USER, user);

        // get the portlet handle
        final String portletHandle = (String) copletData.getAttribute("portlet-handle");
        if ( portletHandle == null ) {
            // if the portlet handle can't be found, we simply return
            this.getLogger().error("Portlet handle not configured in wsrp coplet " + copletData.getId());
            return;           
        }

        // get the wsrp portlet
        final PortletKey portletKey = new PortletKeyImpl(portletHandle, producerId);
        WSRPPortlet wsrpportlet = this.consumerEnvironment.getPortletRegistry().getPortlet(portletKey);
        if ( wsrpportlet == null ) {
            wsrpportlet = new WSRPPortletImpl(portletKey);
            final PortletContext portletContext = new PortletContext(null, portletKey.getPortletHandle(), null);
            wsrpportlet.setPortletContext(portletContext);
            try {
                consumerEnvironment.getPortletRegistry().addPortlet(wsrpportlet);
            } catch (WSRPException we) {
                this.getLogger().error("Exception adding wsrp portlet.", we);
                return;
            }
        }
        coplet.setTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_KEY, portletKey);
        final Session session = ObjectModelHelper.getRequest(this.service.getObjectModel()).getSession();
        final String portletInstanceKey = this.getPortletInstanceKey(portletKey, coplet, session.getId());
        coplet.setTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_INSTANCE_KEY, portletInstanceKey);

        // create consumer parameters
        final Map addParams = new HashMap();
        addParams.put(Constants.PORTLET_INSTANCE_KEY, portletInstanceKey);
        coplet.setTemporaryAttribute(ATTRIBUTE_NAME_CONSUMER_MAP, addParams);

        // get the window-state and -mode
        SimplePortletWindowSession windowSession;
        wsrpportlet = consumerEnvironment.getPortletRegistry().getPortlet(portletKey);

        try {
            // this call includes the getServiceDescription()-Invocation
            // additionally register() initCookie() and so on will be handled
            // (within ProducerImpl and PortletDriverImpl)
            windowSession = getSimplePortletWindowSession(wsrpportlet,
                                                          portletInstanceKey,
                                                          user);
            final PortletDescription desc = producer.getPortletDescription(portletHandle);
            coplet.setTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_TITLE,
                                         desc.getTitle());
            final MarkupType markupType = desc.getMarkupTypes(0);
            coplet.setTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_MODES, markupType.getModes());
            coplet.setTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_WINDOWSTATES, markupType.getWindowStates());

        } catch (WSRPException e) {
            this.getLogger().error("Invoking getServiceDescription()", e);
        }
    }

  /**
     * Checks the values of the <tt>portlet-key</tt> and the <tt>user</tt> for current portlet-instance<br/>
     * After that all passed the <tt>getMarkup()</tt>-call will be initiated<br />
     *
   * @see org.apache.cocoon.portal.coplet.adapter.impl.AbstractCopletAdapter#streamContent(org.apache.cocoon.portal.coplet.CopletInstanceData, org.xml.sax.ContentHandler)
   */
  public void streamContent(CopletInstanceData coplet, ContentHandler contentHandler)
    throws SAXException {
        try {
            // set the coplet in the thread local variable to give other components access to
            // the instance
            this.setCurrentCopletInstanceData(coplet);

            // get the portlet key and the user
            final PortletKey portletKey = (PortletKey)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_KEY);
            if ( portletKey == null ) {
                throw new SAXException("WSRP configuration is missing: portlet key.");
            }
            final User user = (User)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_USER);
            if ( user == null ) {
                throw new SAXException("WSRP configuration is missing: user.");
            }
           
            final String portletInstanceKey = (String)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_INSTANCE_KEY);

            // getMarkup()
            final WSRPPortlet wsrpportlet = consumerEnvironment.getPortletRegistry().getPortlet(portletKey);

            SimplePortletWindowSession windowSession = getSimplePortletWindowSession(wsrpportlet, portletInstanceKey, user);
            final MarkupContext markupContext = this.getMarkupContext(wsrpportlet, windowSession, user);
            if ( markupContext == null || markupContext.getMarkupString() == null ) {
                throw new SAXException("No markup received from wsrp coplet " + coplet.getId());
            }
            final String content = markupContext.getMarkupString();

            final Boolean usePipeline;
            final boolean usesGet;
            // If the portlet uses the method get we always have to rewrite form elements
            final Producer producer = this.consumerEnvironment.getProducerRegistry().getProducer(portletKey.getProducerId());
            final PortletDescription desc = producer.getPortletDescription(portletKey.getPortletHandle());
            if ( desc.getUsesMethodGet() != null && desc.getUsesMethodGet().booleanValue() ) {
                usePipeline = Boolean.TRUE;
                usesGet = true;
            } else {
                usePipeline = (Boolean)this.getConfiguration(coplet, "use-pipeline", Boolean.FALSE);
                usesGet = false;
            }
            if ( usePipeline.booleanValue() ) {
                if ( usesGet ) {
                    contentHandler = new FormRewritingHandler(contentHandler);
                }
                HtmlSaxParser.parseString(content, HtmlSaxParser.getContentFilter(contentHandler));
            } else {
                // stream out the include for the serializer
                IncludingHTMLSerializer.addPortlet(portletInstanceKey, content);
                contentHandler.startPrefixMapping("portal", IncludingHTMLSerializer.NAMESPACE);
                final AttributesImpl attr = new AttributesImpl();
                attr.addCDATAAttribute("portlet", portletInstanceKey);
                contentHandler.startElement(IncludingHTMLSerializer.NAMESPACE,
                                            "include",
                                            "portal:include",
                                            attr);
                contentHandler.endElement(IncludingHTMLSerializer.NAMESPACE,
                                          "include",
                                          "portal:include");
                contentHandler.endPrefixMapping("portal");
            }
        } catch (WSRPException e) {
            throw new SAXException("Exception during getMarkup of wsrp coplet: " + coplet.getId(), e);
        } catch (SAXException se) {
            throw se;
        } finally {
            this.setCurrentCopletInstanceData(null);
        }
  }
   
    /**
     * Releases all sessions (<tt>userSession, groupSession, portletSession</tt>)<br/>
     *
     * @see org.apache.cocoon.portal.coplet.adapter.impl.AbstractCopletAdapter#logout(org.apache.cocoon.portal.coplet.CopletInstanceData)
     */
    public void logout(CopletInstanceData coplet) {
      super.logout(coplet);

        PortletKey portletKey = (PortletKey)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_KEY);
        User user = (User)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_USER);
        final String portletInstanceKey = (String)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_INSTANCE_KEY);
        Producer producer = consumerEnvironment.getProducerRegistry().getProducer(portletKey.getProducerId());
       
        // releaseSession()
        try {
            UserSession userSession = consumerEnvironment.getSessionHandler().getUserSession(portletKey.getProducerId(), user.getUserID());
            PortletDescription portletDescription = producer.getPortletDescription(portletKey.getPortletHandle());
            GroupSession groupSession = userSession.getGroupSession(portletDescription.getGroupID());
            PortletSession portletSession = groupSession.getPortletSession(portletInstanceKey);
            SessionContext sessionContext = portletSession.getSessionContext();
            WSRPPortlet wsrpportlet = consumerEnvironment.getPortletRegistry().getPortlet(portletKey);
            PortletDriver portletDriver = consumerEnvironment.getPortletDriverRegistry().getPortletDriver(wsrpportlet);
   
            if (sessionContext != null) {
                String[] sessions = new String[1];
                sessions[0] = new String (sessionContext.getSessionID());
                portletDriver.releaseSessions(sessions, user.getUserID());
            }
           
            userSession.removeGroupSession(portletDescription.getGroupID());
        } catch (WSRPException e) {
            this.getLogger().error("session deregister()", e);
        }
    }
   
    /**
     * After getting the <tt>userSession</tt> and <tt>groupSession</tt> it performs the <tt>getServiceDescription()</tt>-call<br/>
    
     * @param portlet
     * @param portletInstanceKey
     * @param user
     * @return SimplePortletWindowSession
     * @throws WSRPException
     */
    public SimplePortletWindowSession getSimplePortletWindowSession(WSRPPortlet portlet,
                                                                    String portletInstanceKey,
                                                                    User user)
    throws WSRPException {
        SimplePortletWindowSession windowSession = null;

        // get the user session
        SessionHandler sessionHandler = consumerEnvironment.getSessionHandler();
        UserSession userSession = sessionHandler.getUserSession(portlet.getPortletKey().getProducerId(), user.getUserID());

        if (userSession != null) {
            // get the group session
            String groupID = null;
            try {
                Producer producer = consumerEnvironment.getProducerRegistry().getProducer(portlet.getPortletKey().getProducerId());
                // *********************************
                // getServiceDescription()
                // *********************************
                PortletDescription portletDescription = producer.getPortletDescription(portlet.getPortletKey().getPortletHandle());

                if (portletDescription != null) {
                    groupID = portletDescription.getGroupID();
                }
            } catch (WSRPException e) {
                groupID = "default_group_id";
                this.getLogger().info("using default-group");
            }

            GroupSession groupSession = userSession.getGroupSession(groupID);

            if (groupSession != null) {
                PortletSession portletSession = groupSession.getPortletSession(portlet.getPortletKey().getPortletHandle());

                if (portletSession != null) {
                    windowSession = (SimplePortletWindowSession) portletSession.getPortletWindowSession(portletInstanceKey);
                } else {
                    this.getLogger().error("WSRP-Errorcode: " + Integer.toString(ErrorCodes.PORTLET_SESSION_NOT_FOUND));
                }
            } else {
                this.getLogger().error("WSRP-Errorcode: " + Integer.toString(ErrorCodes.GROUP_SESSION_NOT_FOUND));
            }
        } else {
            this.getLogger().error("WSRP-Errorcode: " + Integer.toString(ErrorCodes.USER_SESSION_NOT_FOUND));
        }
        return windowSession;
    }

    /**
     * Performs an blocking interaction with the given portlet and session.<br/>
     * If the response to this call is a redirect URL's it won't be followed.<br/>
     *
     * An optionally returned markup context is store in the window session<br/>
     * and should be processed by the portlet driver instead of making a new<br/>
     * getMarkup() call.<br/>
     *
     * @param portlet The portlet on which this action should be performed
     * @param windowSession The window session of the portlet on which the action should
     *        be performed
     * @param user The user on which this action should be performed
     * @param request The request with all required information for the call
     **/
    protected void performBlockingInteraction(WSRPPortlet portlet,
                                              SimplePortletWindowSession windowSession,
                                              User user,
                                              Request request) {
        try {
            PortletDriver portletDriver = consumerEnvironment.getPortletDriverRegistry().getPortletDriver(portlet);
            BlockingInteractionResponse response = portletDriver.performBlockingInteraction(
                    new WSRPRequestImpl(windowSession, request, consumerEnvironment), user.getUserID());

            if (response != null) {
                UpdateResponse update = response.getUpdateResponse();
                if (update != null) {
                    //update the WSRP portlet sessionContext
                    windowSession.getPortletSession().setSessionContext(update.getSessionContext());

                    MarkupContext markupContext = update.getMarkupContext();
                    if (markupContext != null) {
                        windowSession.updateMarkupCache(markupContext);
                    }

                    windowSession.setNavigationalState(update.getNavigationalState());

                    String windowState = null;
                    if ((windowState = update.getNewWindowState()) != null) {
                        windowSession.setWindowState(windowState);
                    }

                    String windowMode = null;
                    if ((windowMode = update.getNewMode()) != null) {
                        windowSession.setMode(windowMode);
                    }
                } else if (response.getRedirectURL() != null) {
                    this.getLogger().debug("response.getRedirectURL() != null");
                }
            }
        } catch (WSRPException e) {
            this.getLogger().error("Error occured during performInteraction!", e);
        }
    }

    /**
     * Retrieves the markup generated by the portlet.
     *
     * @param portlet
     * @param windowSession
     * @param user
     * @return The markup context.
     **/
    protected MarkupContext getMarkupContext(WSRPPortlet portlet,
                                             SimplePortletWindowSession windowSession,
                                             User user)
    throws WSRPException {
        WSRPRequestImpl wsrpRequest = new WSRPRequestImpl(windowSession, null, this.consumerEnvironment);

        PortletDriver portletDriver = consumerEnvironment.getPortletDriverRegistry().getPortletDriver(portlet);
        MarkupResponse response = portletDriver.getMarkup(wsrpRequest, user.getUserID());

        if (response != null) {
            SessionContext sessionContext = response.getSessionContext();
            if (sessionContext != null && windowSession != null) {
                windowSession.getPortletSession().setSessionContext(sessionContext);
            }

            return response.getMarkupContext();
        }
        return null;
    }

    /**
     * Creates a <tt>String</tt> consists of the producer-id_portlet-handle_coplet-id_user-name <br/>
     *
     * @param key includes the essential values
     * @param coplet current <tt>CopletInstanceData</tt>-object
     * @param userName
     * @return the unique string which represents the portlet-instance
     * */
    protected String getPortletInstanceKey(PortletKey key,
                                           CopletInstanceData coplet,
                                           String userName) {
        final StringBuffer buffer = new StringBuffer(key.getProducerId());
        buffer.append('_').append(key.getPortletHandle()).append('_');
        buffer.append(coplet.getId()).append('_').append(userName);
        return buffer.toString();   
    }
   
    /**
     * Gets all required information like <tt>portletKey, portletInstanceKey, userName, portletModes, windowStates,
     * interactionState</tt> and the <tt>navigationalStat</tt><br/>
     *
     * After that it decides with the <tt>URL_TYPE</tt> to perform the <tt>performBlockingInteraction()</tt>-call or
     * do some render- alternatively some resource-specific things<br/>
     *
     * @see Receiver
     */
    public void inform(WSRPEvent event, PortalService service) {
        final CopletInstanceData coplet = (CopletInstanceData)event.getTarget();
        this.setCurrentCopletInstanceData(coplet);
       
        try {
            PortletKey portletKey = (PortletKey)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_KEY);
            final String portletInstanceKey = (String)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_PORTLET_INSTANCE_KEY);
            WSRPPortlet wsrpPortlet = consumerEnvironment.getPortletRegistry().getPortlet(portletKey);
            User user = (User) coplet.getTemporaryAttribute(ATTRIBUTE_NAME_USER);
           
            org.apache.cocoon.environment.Request requestObject = ObjectModelHelper.getRequest(service.getObjectModel());
            java.util.Enumeration formParameter = requestObject.getParameterNames();

            Request request = new RequestImpl();
            String portletMode = requestObject.getParameter(Constants.PORTLET_MODE);
            String windowState = requestObject.getParameter(Constants.WINDOW_STATE);
           
            request.setInteractionState(requestObject.getParameter(Constants.INTERACTION_STATE));
            SimplePortletWindowSession windowSession = getSimplePortletWindowSession(wsrpPortlet, portletInstanceKey, user);
            windowSession.setNavigationalState(requestObject.getParameter(Constants.NAVIGATIONAL_STATE));

            if (portletMode != null) {
                windowSession.setMode(portletMode);
            }
            if (windowState != null) {
                if ( !windowState.equals(windowSession.getWindowState()) ) {
                    final Layout layout = (Layout)coplet.getTemporaryAttribute(ATTRIBUTE_NAME_LAYOUT);
                    final Layout fullScreenLayout = service.getEntryLayout(null);
                    if ( fullScreenLayout != null
                         && fullScreenLayout.equals( layout )
                         && !windowState.equals(WindowStates._maximized) ) {
                        FullScreenCopletEvent e = new FullScreenCopletEvent( coplet, null );
                        service.getComponentManager().getEventManager().send(e);
                    }
                    if ( windowState.equals(WindowStates._minimized) ) {
                        ChangeCopletInstanceAspectDataEvent e = new ChangeCopletInstanceAspectDataEvent(coplet, "size", SizingStatus.STATUS_MINIMIZED);
                        service.getComponentManager().getEventManager().send(e);
                    }
                    if ( windowState.equals(WindowStates._normal) ) {
                        ChangeCopletInstanceAspectDataEvent e = new ChangeCopletInstanceAspectDataEvent(coplet, "size", SizingStatus.STATUS_MAXIMIZED);
                        service.getComponentManager().getEventManager().send(e);
                    }
                    if ( windowState.equals(WindowStates._maximized) ) {
                        FullScreenCopletEvent e = new FullScreenCopletEvent( coplet, layout );
                        service.getComponentManager().getEventManager().send(e);
                    }
                    windowSession.setWindowState(windowState);
                }
            }
            if (requestObject.getParameter(Constants.URL_TYPE).equals(Constants.URL_TYPE_BLOCKINGACTION)) {
            // performBlockingInteraction()
                String parameter;
                while (formParameter.hasMoreElements()) {
                    parameter = (String) formParameter.nextElement();
                    request.addFormParameter(parameter, requestObject.getParameter(parameter));
                }
                performBlockingInteraction(wsrpPortlet, windowSession, user, request);
           
            }
               
        } catch (WSRPException e) {
            this.getLogger().error("Error during processing wsrp event.", e);
        } finally {
            this.setCurrentCopletInstanceData(null);
        }
    }

    /**
     * @see org.apache.cocoon.portal.PortalManagerAspect#prepare(org.apache.cocoon.portal.PortalManagerAspectPrepareContext, org.apache.cocoon.portal.PortalService)
     */
    public void prepare(PortalManagerAspectPrepareContext aspectContext,
                        PortalService service)
    throws ProcessingException {
        // process the events
        aspectContext.invokeNext();
    }

    /**
     * @see org.apache.cocoon.portal.PortalManagerAspect#render(org.apache.cocoon.portal.PortalManagerAspectRenderContext, org.apache.cocoon.portal.PortalService, org.xml.sax.ContentHandler, org.apache.avalon.framework.parameters.Parameters)
     */
    public void render(PortalManagerAspectRenderContext aspectContext,
                       PortalService service,
                       ContentHandler ch,
                       Parameters parameters)
    throws SAXException {
        aspectContext.invokeNext(ch, parameters);
    }

    /**
     * @return Returns the <tt>consumerEnvironmentImpl</tt>
     */
    public ConsumerEnvironmentImpl getConsumerEnvironment() {
        return consumerEnvironment;
    }

    /**
     * Add a new producer<br/>
     *
     * @param desc The producer description.
     * @return Returns true if the producer could be added.
     */
    public boolean addProducer(ProducerDescription desc) {
        return ((ProducerRegistryImpl)this.consumerEnvironment.getProducerRegistry()).addProducer(desc);
    }

    /**
     * This sets the current coplet instance data for the thread <br/>
     *
     * @param coplet The coplet instance data or null to clear the information.
     */
    public void setCurrentCopletInstanceData(CopletInstanceData coplet) {
        this.copletInstanceData.set(coplet);
    }

    /**
     * Return the current coplet instance data<br/>
     *
     * @return Returns the instance or null.
     */
    public CopletInstanceData getCurrentCopletInstanceData() {
        return (CopletInstanceData)this.copletInstanceData.get();
    }

    /**
     * This handler is triggered by a form element. It rewrites the
     * action if the method get is used. In this case all request parameters
     * of the action are added as hidden fields.
     */
    public static final class FormRewritingHandler extends AbstractXMLPipe {

        public FormRewritingHandler(ContentHandler ch) {
            this.setContentHandler(ch);
            if ( ch instanceof LexicalHandler ) {
                this.setLexicalHandler((LexicalHandler)ch);
            }
        }

        /**
         * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
         */
        public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
            if ( loc.equalsIgnoreCase("form") && a.getValue("method").equalsIgnoreCase("get") ) {
                final String action = a.getValue("action");
                int pos = action.indexOf('?');
                if ( pos != -1 ) {
                    AttributesImpl ai = new AttributesImpl(a);
                    a = ai;
                    final String queryString = action.substring(pos+1);
                    ai.removeAttribute("action");
                    ai.addCDATAAttribute("action", action.substring(0, pos));
                    super.startElement(uri, loc, raw, a);
                    RequestParameters rp = new RequestParameters(queryString);

                    final Enumeration e = rp.getParameterNames();
                    while ( e.hasMoreElements() ) {
                        final String key = (String)e.nextElement();
                        final String value = rp.getParameter(key);
                        AttributesImpl attributes = new AttributesImpl();
                        attributes.addCDATAAttribute("type", "hidden");
                        attributes.addCDATAAttribute("name", key);
                        attributes.addCDATAAttribute("value", value);
                        XMLUtils.createElement(this.contentHandler, "input", attributes);
                    }
                    return;
                }
            }
            super.startElement(uri, loc, raw, a);
        }

    }

    /**
     * Check if we have read our configuration already.
     * If not, read the config and invoke the configure method.
     */
    protected void checkInitialized() {
        if ( !this.initialized ) {
            synchronized (this) {
                if (! this.initialized ) {
                    this.initialized = true;
                    SourceResolver resolver = null;
                    Source source = null;
                    try {
                        resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
                        source = resolver.resolveURI(this.wsrpConfigLocation);
                        DefaultConfigurationBuilder dcb = new DefaultConfigurationBuilder();
                        this.wsrpConfiguration = dcb.build(source.getInputStream());
                    } catch (ConfigurationException ce) {
                        this.getLogger().error("Unable to read wsrp configuration: " + this.wsrpConfigLocation, ce);
                    } catch (IOException ioe) {
                        this.getLogger().error("Unable to read wsrp configuration: " + this.wsrpConfigLocation, ioe);
                    } catch (SAXException sae) {
                        this.getLogger().error("Unable to read wsrp configuration: " + this.wsrpConfigLocation, sae);
                    } catch (ServiceException se) {
                        throw new NestableRuntimeException("Unable to get source resolver.", se);
                    } finally {
                        if ( resolver != null ) {
                            resolver.release(source);
                        }
                        this.manager.release(resolver);
                    }           
                }
            }
        }
    }

    /**
     * Get the wsrp configuration.
     */
    public Configuration getWsrpConfiguration() {
        this.checkInitialized();
        return this.wsrpConfiguration;
    }

    /**
     * Get the adapter configuration.
     */
    public Parameters getAdapterConfiguration() {
        return this.parameters;
    }

    /**
     * Create a component.
     */
    public Object createObject(String className)
    throws Exception {
        final Object component = ClassUtils.newInstance(className);
        ContainerUtil.enableLogging(component, this.getLogger());
        if (component instanceof RequiresConsumerEnvironment) {
            ((RequiresConsumerEnvironment)component).setConsumerEnvironment(this.consumerEnvironment);
        }
        if (component instanceof RequiresWSRPAdapter) {
            ((RequiresWSRPAdapter)component).setWSRPAdapter(this);
        }
        if (component instanceof RequiresPortalService) {
            ((RequiresPortalService)component).setPortalService(this.service);
        }
        ContainerUtil.contextualize(component, context);
        ContainerUtil.service(component, manager);
        ContainerUtil.initialize(component);

        return component;
    }

}
TOP

Related Classes of org.apache.cocoon.portal.wsrp.adapter.WSRPAdapter

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.