Package rogatkin.web

Source Code of rogatkin.web.AsyncContextImpl

/* tjws - AsyncContextImpl.java
* Copyright (C) 2004-2010 Dmitriy Rogatkin.  All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, 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.
*  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
*  ANY EXPRESS 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR
*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, 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.
*
*  $Id: AsyncContextImpl.java,v 1.6 2010/07/24 07:36:05 dmitriy Exp $
* Created on May 11, 2010
*/
package rogatkin.web;

import java.util.LinkedList;
import java.util.HashMap;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncListener;
import javax.servlet.AsyncEvent;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import Acme.Serve.Serve;

public class AsyncContextImpl implements AsyncContext, Serve.AsyncCallback {
  private ServletRequest request;

  private ServletResponse response;

  private Serve.ServeConnection servConn;

  private long timeout;

  private LinkedList<AsyncListener> listeners;

  private HashMap<AsyncListener, Object[]> associatedData;

  private boolean completed;

  AsyncContextImpl(ServletRequest request, ServletResponse response, Serve.ServeConnection servConn) {
    this.request = request;
    this.response = response;
    this.servConn = servConn;
    listeners = new LinkedList<AsyncListener>();
    associatedData = new HashMap<AsyncListener, Object[]>();
    servConn.spawnAsync(this);
  }

  @Override
  public void addListener(AsyncListener listener) {
    synchronized (listeners) {
      // TODO should be used Set (not List)?
      if (listeners.contains(listener) == false)
        listeners.add(listener);
    }

  }

  @Override
  public void addListener(AsyncListener listener, ServletRequest req, ServletResponse resp) {
    addListener(listener);
    Object[] data = new Object[2];
    data[0] = req;
    data[1] = resp;
    associatedData.put(listener, data);
  }

  @Override
  public void complete() {
    for (AsyncListener listener : listeners)
      try {
        Object[] data = associatedData.get(listener);
        listener.onComplete(data == null ? new AsyncEvent(this) : new AsyncEvent(this,
            (ServletRequest) data[0], (ServletResponse) data[1]));
      } catch (Throwable t) {
        if (t instanceof ThreadDeath)
          throw (ThreadDeath) t;
      }
    servConn.joinAsync();
    completed = true;
  }

  @Override
  public <T extends AsyncListener> T createListener(Class<T> listenerClass) throws ServletException {
    try {
      return listenerClass.newInstance();
    } catch (Exception e) {
      throw new ServletException("Can't create " + listenerClass + ", cause: " + e);
    }

  }

  @Override
  public void dispatch() {
    dispatch(((HttpServletRequest) request).getServletPath() + ((HttpServletRequest) request).getPathInfo());
    //dispatch(((HttpServletRequest) request).getRequestURI());
  }

  @Override
  public void dispatch(String path) {
    dispatch(request.getServletContext(), path);
  }

  @Override
  public void dispatch(ServletContext servletContext, String path) {
    if (completed)
      throw new IllegalStateException("Can't process dispatch after complete()");
    try {
      // TODO check if error handling
      ((WebAppServlet)servletContext).dispatch(path, request, response);
    } catch (Exception e) {
      for (AsyncListener listener : listeners)
        try {
          Object[] data = associatedData.get(listener);
          listener.onError(data == null ? new AsyncEvent(this, e) : new AsyncEvent(this,
              (ServletRequest) data[0], (ServletResponse) data[1], e));
        } catch (Throwable t) {
          if (t instanceof ThreadDeath)
            throw (ThreadDeath) t;
        }
    }
  }

  @Override
  public ServletRequest getRequest() {
    return request;
  }

  @Override
  public ServletResponse getResponse() {
    return response;
  }

  @Override
  public long getTimeout() {
    return timeout;
  }

  @Override
  public boolean hasOriginalRequestAndResponse() {
    return request == servConn && response == servConn;
  }

  @Override
  public void setTimeout(long timeout) {
    this.timeout = timeout;
  }

  @Override
  public void start(Runnable r) {
    ((WebAppServlet) request.getServletContext()).asyncThreads.execute(r);
  }

  public void notifyTimeout() {
    for (AsyncListener listener : listeners)
      try {
        Object[] data = associatedData.get(listener);
        listener.onTimeout(data == null ? new AsyncEvent(this) : new AsyncEvent(this, (ServletRequest) data[0],
            (ServletResponse) data[1]));
      } catch (Throwable t) {
        if (t instanceof ThreadDeath)
          throw (ThreadDeath) t;
      }
  }

  public void notifyStart() {
    for (AsyncListener listener : listeners)
      try {
        Object[] data = associatedData.get(listener);
        listener.onStartAsync(data == null ? new AsyncEvent(this) : new AsyncEvent(this,
            (ServletRequest) data[0], (ServletResponse) data[1]));
      } catch (Throwable t) {
        if (t instanceof ThreadDeath)
          throw (ThreadDeath) t;
      }
  }
}
TOP

Related Classes of rogatkin.web.AsyncContextImpl

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.