Package de.jochenbrissier.backyard.core

Source Code of de.jochenbrissier.backyard.core.Backyard

package de.jochenbrissier.backyard.core;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.Servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;

import de.jochenbrissier.backyard.module.BackyardModule;
import de.jochenbrissier.backyard.module.WebsocketEvent;
import de.jochenbrissier.backyard.util.MemberChannelUtil;
import de.jochenbrissier.backyard.util.ServerDedec;
import de.jochenbrissier.backyard.util.ServerNotSupportedException;

/**
* The main / entry point of Backyard. <br>
*This class declares the main part of the API. <br>
* <br>
*How to ues: <br>
*Backyard backyard = new Backyard(requeset,response); <br>
* <br>
* ba.startAsync(); <br>
* <br>
* To resume the async event. call <br>
* <br>
* ba.stopAsync(); <br>
* <br>
* Thats it.!! easy :)
*
* @author jochenbrissier
*
*/

public class Backyard {

  Log log = LogFactory.getLog(Backyard.class);

  // static globals
  private static Injector in;
  public static ChannelHandler channelhandler;
  private static ArrayList<ChannelListenerBuffer> channelListenerBuffer = new ArrayList<ChannelListenerBuffer>();

  private static MemberHandler memberhandler;

  // members
  private Member member;
  private HttpServlet servlet;
  private HttpServletRequest req;
  private HttpServletResponse resp;
  private static boolean alternativ_impl = false;
  private static boolean websocketSupport = false;

  /**
   *Constructor of Backyard.
   *
   * @param req
   *            a HttpServletRequest object
   * @param resp
   *            a HttpServeltRespons object
   */

  public Backyard(HttpServletRequest req, HttpServletResponse resp) {

    this.resp = resp;
    this.req = req;
   
    if (!alternativ_impl)
      in = Guice.createInjector(new BackyardModule());

    channelhandler = in.getInstance(ChannelHandler.class);

    memberhandler = in.getInstance(MemberHandler.class);

    // load channelhandler from the buffer

    for (ChannelListenerBuffer key : channelListenerBuffer) {

      if (key.getChannel().matches(".*_nb")) {
        addChannelListener(new Integer(key.getChannel().split("_")[0]),
            key.getCl());
      } else {
        addChannelListener(key.getChannel(), key.getCl());
      }

    }
    // clear the buffer;

    channelListenerBuffer.clear();

    // get the member from the member handler.
    this.member = memberhandler.getMember(req.getSession().getId());

    // if member exist in meta channel replace member form channel handler
    // (IMPROVE)

    // listen to meta channel
    listenToChannel(0);

  }

  /**
   * Functions detects the server on which backyard is running and configure
   * some settings e.g. loading the specific module for the server supports
   * the server websockets
   *
   * @param servlet
   */
  public static void autoDedectImpl(Servlet servlet) {
    try {

      // class to detect the running server
      ServerDedec det = new ServerDedec(servlet);

      // load injector
      in = Guice.createInjector(new StandardModule(), det
          .getModuleClass());

      // set alternativ_impl to true
      alternativ_impl = true;

      // set websocket support based on XML
      websocketSupport = det.getWebSocketSupport();

    } catch (ClassNotFoundException e) {
      e.printStackTrace();

    } catch (ServerNotSupportedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  /**
   *
   * Override the Standard Module e.g for Channel, Member, ...
   *
   * @param ba
   */

  public static void setStandartImpel(AbstractModule ba) {
    in = Guice.createInjector(ba);
    alternativ_impl = true;
  }

  /**
   * Backyard also provides a alternative implementations for a specific
   * servlet container such as Tomcat, Jetty or Glassfish You can also write
   * your own implementation for a other servlet container. <br>
   * <br>
   *
   * First you have to extend the class BackyardEvent and implement the
   * methods. <br>
   *
   * Second you have to write a second class and extend it with AbstractModule
   * from google guice project. <br>
   * In the module class you have to call
   * bind(Event.class).to(Yourclass.class);
   *
   * <br>
   *
   * Third you have to invoke Backyard.setAlternativeImpl(new YourModule());
   *
   * @param ba
   */

  public static void setAlternativeImpl(AbstractModule ba) {
    in = Guice.createInjector(new StandardModule(), ba);
    alternativ_impl = true;
  }

  /**
   * Backyard also provides a alternative implementations for a specific
   * servlet container such as Tomcat, Jetty or Glassfish You can also write
   * your own implementation for a other servlet container. <br>
   * <br>
   *
   * First you have to extend the class BackyardEvent and implement the
   * methods. <br>
   *
   * Second you have to write a second class and extend it with AbstractModule
   * from google guice project. <br>
   * In the module class you have to call
   * bind(Event.class).to(Yourclass.class);
   *
   * <br>
   *
   * Third you have to invoke Backyard.setAlternativeImpl(new YourModule());
   *
   * @param ba
   */
  public static void setAlternativeImpl(AbstractModule ba, AbstractModule ab) {
    in = Guice.createInjector(new StandardModule(), ba, ab);
    alternativ_impl = true;

  }

  /**
   * Backyard also provides a alternative implementations for a specific
   * servlet container such as Tomcat, Jetty or Glassfish You can also write
   * your own implementation for a other servlet container. <br>
   * <br>
   *
   * First you have to extend the class BackyardEvent and implement the
   * methods. <br>
   *
   * Second you have to write a second class and extend it with AbstractModule
   * from google guice project. <br>
   * In the module class you have to call
   * bind(Event.class).to(Yourclass.class);
   *
   * <br>
   *
   * Third you have to invoke Backyard.setAlternativeImpl(new YourModule());
   *
   * @param ba
   */
  // TODO: IMPLEMENT THIS !
  /*
   * public static void setAlternativeImpl(Iterable<? extends Module> ba) { in
   * = Guice.createInjector(ba);
   *
   * }
   */

  /**
   * set a other member to backyard obj. standart member is the member from
   * which the request comes
   *
   * @param member
   */

  public void setMember(Member member) {
    this.member = member;
  }

  /**
   * get servelt has in this version no effect
   *
   * @return
   */

  public HttpServlet getServlet() {
    return servlet;
  }

  /**
   * set the servelt has in this version no effect
   *
   * @return
   */

  public void setServlet(HttpServlet servlet) {
    this.servlet = servlet;

  }

  /**
   * Returns the meta channel The meta channel contains all members.
   *
   *
   *
   * @return
   */

  public static Channel getMetaChannel() {

    return channelhandler.getChannel("meta");

  }

  /**
   * returns the member object
   *
   * @return
   */

  public Member getMember() {

    return memberhandler.getMember(this.req.getSession().getId());

  }

  /**
   * let the current member, from which the request came listen to the a
   * channel
   *
   * @param name
   * @return
   */

  public Channel listenToChannel(String name) {

    Channel cn = channelhandler.getChannel(name);
    cn.addMember(this.member);

    return cn;

  }

  /**
   * adds a channel to the queue
   *
   * @param name
   * @return
   */

  public static Channel addChannel(String name) {
    return channelhandler.getChannel(name);
  }

  /**
   * add a listener to a specific channel
   *
   * @param channel
   * @param cl
   */

  public static void addChannelListener(String channel, ChannelListener cl) {

    if (channelhandler == null) {

      channelListenerBuffer.add(new ChannelListenerBuffer(channel, cl));
      return;

    }

    channelhandler.getChannel(channel).addListener(cl);

  }

  /**
   * add a listener to a specific channel
   *
   * @param channel
   * @param cl
   */

  public static void addChannelListener(int id, ChannelListener cl) {
    if (channelhandler == null) {

      channelListenerBuffer
          .add(new ChannelListenerBuffer(id + "_nb", cl));
      return;

    }

    channelhandler.getChannel(id).addListener(cl);
  }

  /**
   * removes a channellistener from a channel
   *
   * @param id
   */

  public static void removeChannelListener(int id) {
    channelhandler.getChannel(id).addListener(null);
  }

  /**
   * removes a channellistener from a channel
   *
   * @param id
   */

  public static void removeChannelListener(String name) {
    channelhandler.getChannel(name).addListener(null);
  }

  /**
   * removes a channel from the queue
   *
   * @param id
   */

  public static void removeChannel(int id) {
    channelhandler.removeChannel(channelhandler.getChannel(id));
  }

  /**
   * removes a channel from the queue
   *
   * @param id
   */

  public static void removeChannel(String name) {
    channelhandler.removeChannel(channelhandler.getChannel(name));
  }

  /**
   * lets a specific member listen to a channel
   *
   * @param channel
   * @param member
   * @return
   */

  public static Channel listentoChannel(String channel, Member member) {

    Channel cn = channelhandler.getChannel(channel);
    cn.addMember(member);
    return cn;
  }

  /**
   * lets a specific member listen to a channel
   *
   * @param channel
   * @param member
   * @return
   */

  public static Channel listentoChannel(int id, Member member) {

    Channel cn = channelhandler.getChannel(id);
    cn.addMember(member);
    return cn;
  }

  /**
   * lets a the member, from which the request came listen to a channel
   *
   * @param channel
   * @param member
   * @return
   */

  public Channel listenToChannel(int id) {
    Channel cn = channelhandler.getChannel(id);
    cn.addMember(this.member);

    return cn;

  }

  /**
   * stops the current req -> res processing until a message will send to the
   * member or the function stopAsync will called
   *
   *
   *
   * @return
   */
  public Event startAsync() {

    Event event = in.getInstance(Event.class);
    event.init(this.req, this.resp);
    this.member.setEvent(event);
    Member anMember = memberhandler
        .getMember(this.req.getSession().getId());
    anMember.setEvent(event);
    return event;

  }

  /**
   * stops the current req -> res processing until a message will send to the
   * member or the function stopAsync will called
   *
   * if this function will called it will give the BackyardEvent implmentation
   * the given obj.
   *
   *
   *
   *
   * @return
   */

  public Event startAsync(Object obj) {
    Event event = in.getInstance(Event.class);

    event.setEvent(obj);

    event.init(this.req, this.resp);
    this.member.setEvent(event);
    Member anMember = memberhandler
        .getMember(this.req.getSession().getId());
    anMember.setEvent(event);
    return event;

  }

  /**
   * stops the async prossesing
   */

  public void stopAsync() {
    stopAsync("na");

  }

  /**
   * sops the asyn prossesing and will send the message to the member
   *
   * @param message
   */

  public void stopAsync(String message) {
    this.member.sendMessage(new Message(message));
  }

  /***
   * returns a channel. if the channel not exists it will creat it
   *
   * @param name
   * @return
   */

  public Channel getChannel(String name) {
    return channelhandler.getChannel(name);
  }

  /**
   *
   * @return true if the member has a comet event.
   */

  public boolean hasEvent() {
    return getMetaChannel().hasEvent(this.member);
  }

  /**
   *
   * @param member
   * @return return true if the given member has an event
   */
  public boolean hasEvent(Member member) {

    return getMetaChannel().isMember(member.getMemberlId());

  }

  /**
   * functions checks if the current server supports websockets
   *
   * @return
   */
  public static boolean isWebsocketSupport() {
    return websocketSupport;
  }

  /**
   * function creates a new Websocket if the container supports it
   *
   * @return
   */
  public static WebsocketEvent getSocket() {

    if (isWebsocketSupport()) {
      Injector inj = Guice.createInjector(new WebsocketModule());

      return inj.getInstance(WebsocketEvent.class);
    }
    // TODO: EXCPTION
    return null;
  }

  public static Member getSocketMember(HttpServletRequest req) {

    // try to find a existing user
    // get session id
    String id = req.getSession().getId();

    Member member = null;
    member = memberhandler.getMember(id);

    if (member instanceof WebSocketMember)
      return member;

    // create a new member
    Member wsmember = new WebSocketMember(Backyard.getSocket());
    wsmember.setMemberId(id);

    MemberChannelUtil mcu = new MemberChannelUtil(channelhandler,
        memberhandler);

    List<Channel> ch = mcu.getMemberChannels(member);

    mcu.addMemberToChannels(ch, wsmember);
   
   
    memberhandler.replaceMember(wsmember);

    // tranclate the channels from old to new member obj

    return wsmember;
  }

}
TOP

Related Classes of de.jochenbrissier.backyard.core.Backyard

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.