Package org.gatein.portal.wsrp

Source Code of org.gatein.portal.wsrp.WSRPServiceIntegration$SimpleSessionEventBroadcaster

/*
* JBoss, a division of Red Hat
* Copyright 2010, Red Hat Middleware, LLC, and individual
* contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.gatein.portal.wsrp;

import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.gatein.common.logging.Logger;
import org.gatein.common.logging.LoggerFactory;
import org.gatein.pc.api.PortletInvoker;
import org.gatein.pc.federation.FederatingPortletInvoker;
import org.gatein.pc.portlet.container.ContainerPortletInvoker;
import org.gatein.pc.portlet.impl.state.StateConverterV0;
import org.gatein.pc.portlet.impl.state.StateManagementPolicyService;
import org.gatein.pc.portlet.state.StateConverter;
import org.gatein.pc.portlet.state.producer.PortletStatePersistenceManager;
import org.gatein.pc.portlet.state.producer.ProducerPortletInvoker;
import org.gatein.portal.wsrp.state.consumer.JCRConsumerRegistry;
import org.gatein.portal.wsrp.state.producer.configuration.JCRProducerConfigurationService;
import org.gatein.portal.wsrp.state.producer.registrations.JCRRegistrationPersistenceManager;
import org.gatein.portal.wsrp.state.producer.state.JCRPortletStatePersistenceManager;
import org.gatein.registration.RegistrationManager;
import org.gatein.registration.RegistrationPersistenceManager;
import org.gatein.registration.impl.RegistrationManagerImpl;
import org.gatein.wci.ServletContainer;
import org.gatein.wci.ServletContainerFactory;
import org.gatein.wci.WebApp;
import org.gatein.wci.WebAppEvent;
import org.gatein.wci.WebAppLifeCycleEvent;
import org.gatein.wci.WebAppListener;
import org.gatein.wci.impl.DefaultServletContainerFactory;
import org.gatein.wsrp.WSRPConstants;
import org.gatein.wsrp.api.SessionEvent;
import org.gatein.wsrp.api.SessionEventBroadcaster;
import org.gatein.wsrp.api.SessionEventListener;
import org.gatein.wsrp.consumer.registry.ActivatingNullInvokerHandler;
import org.gatein.wsrp.consumer.registry.ConsumerRegistry;
import org.gatein.wsrp.producer.ProducerHolder;
import org.gatein.wsrp.producer.WSRPProducer;
import org.gatein.wsrp.producer.config.ProducerConfigurationService;
import org.picocontainer.Startable;

import javax.servlet.ServletContext;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
* @version $Revision$
*/
public class WSRPServiceIntegration implements Startable, WebAppListener
{
   private static final Logger log = LoggerFactory.getLogger(WSRPServiceIntegration.class);

   private static final String CLASSPATH = "classpath:/";
   private static final String PRODUCER_CONFIG_LOCATION = "producerConfigLocation";
   private static final String CONSUMERS_CONFIG_LOCATION = "consumersConfigLocation";

   private final InputStream configurationIS;
   private final String producerConfigLocation;
   private WSRPProducer producer;

   private ConsumerRegistry consumerRegistry;
   private ExoContainer container;
   private final boolean bypass;
   private static final String WSRP_ADMIN_GUI_CONTEXT_PATH = "/wsrp-admin-gui";

   public WSRPServiceIntegration(ExoContainerContext context, InitParams params, ConfigurationManager configurationManager,
                                 org.exoplatform.portal.pc.ExoKernelIntegration pc, NodeHierarchyCreator nhc) throws Exception
   {
      // IMPORTANT: even though PC ExoKernelIntegration and NodeHierarchyCreator is not used anywhere in the code, it's still needed for pico
      // to properly make sure that this service is started after the PC one. Yes, Pico is crap. :/

      // todo: we currently only allow the service to go through initialization if we are running in the default portal
      // as this service is not meant to work with extensions yet...
      String consumersConfigLocation;
      if ("portal".equals(context.getName()))
      {
         if (params != null)
         {
            producerConfigLocation = params.getValueParam(PRODUCER_CONFIG_LOCATION).getValue();
            consumersConfigLocation = params.getValueParam(CONSUMERS_CONFIG_LOCATION).getValue();
         }
         else
         {
            throw new IllegalArgumentException("Improperly configured service: missing values for "
               + PRODUCER_CONFIG_LOCATION + "and " + CONSUMERS_CONFIG_LOCATION);
         }

         configurationIS = configurationManager.getInputStream(CLASSPATH + producerConfigLocation);

         container = context.getContainer();

         bypass = false;
      }
      else
      {
         log.info("The WSRP service can only be started in the default portal context. WSRP was not started for '"
            + context.getName() + "'");

         producerConfigLocation = null;
         consumersConfigLocation = null;
         configurationIS = null;
         bypass = true;
      }
   }

   public void start()
   {
      if (!bypass)
      {
         startProducer();
         startConsumers();

         // listen for web app events so that we can inject services into WSRP admin UI "cleanly"
         // todo: this service injection should really be done using CDI... :/
         ServletContainerFactory factory = DefaultServletContainerFactory.getInstance();
         ServletContainer servletContainer = factory.getServletContainer();
         servletContainer.addWebAppListener(this);

         log.info("WSRP Service version '" + WSRPConstants.WSRP_SERVICE_VERSION + "' started");
      }
   }

   private void startProducer()
   {

      JCRProducerConfigurationService producerConfigurationService;
      try
      {
         producerConfigurationService = new JCRProducerConfigurationService(container);
         producerConfigurationService.setDefaultConfigurationIS(configurationIS);
         producerConfigurationService.reloadConfiguration();
      }
      catch (Exception e)
      {
         throw new RuntimeException("Couldn't load WSRP producer configuration from " + producerConfigLocation, e);
      }
      container.registerComponentInstance(ProducerConfigurationService.class, producerConfigurationService);

      RegistrationPersistenceManager registrationPersistenceManager;
      try
      {
         registrationPersistenceManager = new JCRRegistrationPersistenceManager(container);
      }
      catch (Exception e)
      {
         throw new RuntimeException("Couldn't instantiate RegistrationPersistenceManager", e);
      }
      RegistrationManager registrationManager = new RegistrationManagerImpl();
      registrationManager.setPersistenceManager(registrationPersistenceManager);

      // retrieve container portlet invoker from eXo kernel
      ContainerPortletInvoker containerPortletInvoker =
         (ContainerPortletInvoker)container.getComponentInstanceOfType(ContainerPortletInvoker.class);

      // The producer persistence manager
      PortletStatePersistenceManager producerPersistenceManager;
      try
      {
         producerPersistenceManager = new JCRPortletStatePersistenceManager(container);
      }
      catch (Exception e)
      {
         throw new RuntimeException("Couldn't instantiate PortletStatePersistenceManager", e);
      }

      // The producer state management policy
      StateManagementPolicyService producerStateManagementPolicy = new StateManagementPolicyService();
      producerStateManagementPolicy.setPersistLocally(true);

      // The producer state converter
      StateConverter producerStateConverter = new StateConverterV0();

      // The producer portlet invoker
      ProducerPortletInvoker producerPortletInvoker = new ProducerPortletInvoker();
      producerPortletInvoker.setNext(containerPortletInvoker);
      producerPortletInvoker.setPersistenceManager(producerPersistenceManager);
      producerPortletInvoker.setStateManagementPolicy(producerStateManagementPolicy);
      producerPortletInvoker.setStateConverter(producerStateConverter);

      // create and wire WSRP producer
      producer = ProducerHolder.getProducer(true);
      producer.setPortletInvoker(producerPortletInvoker);
      producer.setRegistrationManager(registrationManager);
      producer.setConfigurationService(producerConfigurationService);

      producer.start();
   }

   private void startConsumers()
   {
      // retrieve federating portlet invoker from container
      FederatingPortletInvoker federatingPortletInvoker =
         (FederatingPortletInvoker)container.getComponentInstanceOfType(PortletInvoker.class);

      try
      {
         consumerRegistry = new JCRConsumerRegistry(container);
         consumerRegistry.setFederatingPortletInvoker(federatingPortletInvoker);
         consumerRegistry.setSessionEventBroadcaster(new SimpleSessionEventBroadcaster());
         consumerRegistry.start();

         // set up a NullInvokerHandler so that when a remote producer is queried, we can start it if needed
         ActivatingNullInvokerHandler handler = new ActivatingNullInvokerHandler();
         handler.setConsumerRegistry(consumerRegistry);
         federatingPortletInvoker.setNullInvokerHandler(handler);
      }
      catch (Exception e)
      {
         throw new RuntimeException("Couldn't start WSRP consumers registry.", e);
      }
      container.registerComponentInstance(ConsumerRegistry.class, consumerRegistry);
   }

   public void stop()
   {
      if (!bypass)
      {
         // stop listening to web app events
         ServletContainerFactory factory = DefaultServletContainerFactory.getInstance();
         ServletContainer servletContainer = factory.getServletContainer();
         servletContainer.removeWebAppListener(this);

         stopProducer();
         stopConsumers();
      }
   }

   private void stopProducer()
   {
      producer.stop();

      producer = null;
   }

   private void stopConsumers()
   {
      try
      {
         consumerRegistry.stop();
      }
      catch (Exception e)
      {
         throw new RuntimeException("Couldn't stop WSRP consumers registry.", e);
      }

      consumerRegistry = null;
   }

   public void onEvent(WebAppEvent event)
   {
      if (event instanceof WebAppLifeCycleEvent)
      {
         WebAppLifeCycleEvent lifeCycleEvent = (WebAppLifeCycleEvent)event;
         WebApp webApp = event.getWebApp();
         ServletContext context = webApp.getServletContext();

         // if we see the WSRP admin GUI being deployed or undeployed, inject or remove services
         if (WSRP_ADMIN_GUI_CONTEXT_PATH.equals(webApp.getContextPath()))
         {
            switch (lifeCycleEvent.getType())
            {
               case WebAppLifeCycleEvent.ADDED:
                  context.setAttribute("ConsumerRegistry", consumerRegistry);
                  context.setAttribute("ProducerConfigurationService", producer.getConfigurationService());
                  break;
               case WebAppLifeCycleEvent.REMOVED:
                  context.removeAttribute("ConsumerRegistry");
                  context.removeAttribute("ProducerConfigurationService");
                  break;
            }
         }
      }
   }

   private static class SimpleSessionEventBroadcaster implements SessionEventBroadcaster
   {
      private Map<String, SessionEventListener> listeners = new ConcurrentHashMap<String, SessionEventListener>();

      public void registerListener(String listenerId, SessionEventListener listener)
      {
         listeners.put(listenerId, listener);
      }

      public void unregisterListener(String listenerId)
      {
         listeners.remove(listenerId);
      }

      public void notifyListenersOf(SessionEvent event)
      {
         for (SessionEventListener listener : listeners.values())
         {
            listener.onSessionEvent(event);
         }
      }

   }
}
TOP

Related Classes of org.gatein.portal.wsrp.WSRPServiceIntegration$SimpleSessionEventBroadcaster

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.