Package org.persvr.servlet

Source Code of org.persvr.servlet.JettyBayeux$PersevereService

package org.persvr.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import org.mortbay.cometd.AbstractBayeux;
import org.mortbay.cometd.BayeuxService;
import org.mortbay.cometd.ChannelId;
import org.mortbay.cometd.ClientImpl;
import org.mortbay.cometd.Transport;
import org.mortbay.cometd.continuation.ContinuationBayeux;
import org.mortbay.cometd.continuation.ContinuationCometdServlet;
import org.mortbay.util.ajax.JSON;
import org.mozilla.javascript.Function;
import org.persvr.data.GlobalData;
import org.persvr.data.Identification;
import org.persvr.data.ObservablePersistable;
import org.persvr.data.ObservedCall;
import org.persvr.data.Persistable;
import org.persvr.data.PersistableObject;
import org.persvr.data.PropertyChangeSetListener;
import org.persvr.javascript.PersevereContextFactory;
import org.persvr.remote.Client;
import org.persvr.remote.Client.IndividualRequest;

import org.cometd.Bayeux;
import org.cometd.Channel;
import org.cometd.Message;
/**
* Persevere utilization of Jetty's Bayeux implementation
* @author Kris
*
*/
public class JettyBayeux extends ContinuationCometdServlet {
  ServletConfig servletConfig;
  /**
   * Our implementation of Jetty's Bayuex
   * @author Kris
   *
   */
  static class RestChannelsBayeux extends ContinuationBayeux {
    RestChannelsBayeux(){
      super();
        _transports=new JSON.Literal("[\"rest-channels\",\""+Bayeux.TRANSPORT_LONG_POLL+ "\",\""+Bayeux.TRANSPORT_CALLBACK_POLL+"\"]");
    }
    /**
     * Appends a * on channel names that end with a slash
     */
      @Override
    public ChannelId getChannelId(String id) {
        return super.getChannelId(id.endsWith("/") ? id + "*" : id);
    }

    /**
     * Appends a * on channel names that end with a slash
     */
      @Override
    public Channel getChannel(String id, boolean create)
      {
        return super.getChannel(id.endsWith("/") ? id + "*" : id,create);
      }
      /**
       * Publishes an event
       * @param channel
       * @param data
       * @throws IOException
       */
      public void internalPublish(String channel, Object data) throws IOException {
        super.doPublish(getChannelId(channel), null, data, null);
      }
      /**
       * Intercepts all messages sent from the client
       */
    @Override
    public String handle(ClientImpl client, Transport transport, Message message) throws IOException {
      if (!message.getChannel().startsWith("/meta")){
        // These are published messages
        Persistable target = (Persistable) Identification.idForString((String) message.getChannel()).getTarget();
        Function messageFunc = (Function) target.get("message");
        messageFunc.call(PersevereContextFactory.getContext(), GlobalData.getGlobalScope(), target, new Object[]{message.getData()});
        // don't actually publish it, let Persevere handle it
        return null;
      }
      if (message.getChannel().startsWith("/meta/subscribe")){
        // A subscription request, we just need to make sure the global listener
        //  object is subscribed to the given resource
        String id = (String) message.get("subscription");
        while (id.endsWith("*")){
          id = id.substring(0, id.length() - 1);
        }
        Object target = Identification.idForString(id).getTarget();
        if (target instanceof ObservablePersistable)
          ((ObservablePersistable) target).subscribe();
        PersistableObject.addListener(jettyBayeuxRestListener);
      }
      return super.handle(client, transport, message);
    }
   
  }
  /**
   * Get our impl
   */
  @Override
  protected AbstractBayeux newBayeux() {
    return new RestChannelsBayeux();
  }
  /**
   * Initialize the Bayeux server
   */
  @Override
  public void init() throws ServletException {
    super.init();
    AbstractBayeux bayeux=(AbstractBayeux)getServletContext().getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
    new PersevereService(bayeux);
  }
  /**
   * Listen for events that go through the message handler
   * @author Kris
   *
   */
  public static class RestListener implements PropertyChangeSetListener {

    public void propertyChange(List<ObservedCall> evt) {
      for(ObservedCall call : evt){
        if ("MESSAGE".equalsIgnoreCase(call.getMethod())){
          try {
              IndividualRequest request = new Client(null).getIndividualRequest(null, null);
            ((RestChannelsBayeux)bayeux).internalPublish("/" + call.getSourceId(), new JSON.Literal(request.serialize(call.getContent())));
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
        }
      }
    }
   
  }
  static RestListener jettyBayeuxRestListener = new RestListener();
  static Bayeux bayeux;
  /**
   * Initialize and save a reference to Bayeux
   *
   */
  public static class PersevereService extends BayeuxService {
   
    public PersevereService(Bayeux bayeuxArg) {
      super(bayeuxArg, "persevere");
      bayeux = bayeuxArg;
    }
  }
  @Override
  public ServletConfig getServletConfig() {
    return servletConfig;
  }
}
TOP

Related Classes of org.persvr.servlet.JettyBayeux$PersevereService

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.