*/
package javax.servlet;
-import org.apache.catalina.connector.AsyncContextImpl.AsyncState;
+import org.apache.catalina.core.AsyncContextImpl.AsyncState;
/**
* @since Servlet 3.0
private ServletRequest request;
private ServletResponse response;
- AsyncEvent(ServletRequest request, ServletResponse response) {
+ public AsyncEvent(ServletRequest request, ServletResponse response) {
this.request = request;
this.response = response;
}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.catalina.connector;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.servlet.AsyncContext;
-import javax.servlet.AsyncListener;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Globals;
-import org.apache.coyote.ActionCode;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-/**
- *
- * @author fhanik
- *
- */
-public class AsyncContextImpl implements AsyncContext {
-
- public static enum AsyncState {
- NOT_STARTED, STARTED, DISPATCHING, DISPATCHED, COMPLETING, TIMING_OUT
- }
-
- protected static Log log = LogFactory.getLog(AsyncContextImpl.class);
-
- private ServletRequest servletRequest = null;
- private ServletResponse servletResponse = null;
- private List<AsyncListenerWrapper> listeners = new ArrayList<AsyncListenerWrapper>();
- private boolean hasOriginalRequestAndResponse = true;
- private volatile Runnable dispatch = null;
- private Context context = null;
- private AtomicReference<AsyncState> state = new AtomicReference<AsyncState>(AsyncState.NOT_STARTED);
- private long timeout = -1;
-
- private Request request;
-
- public AsyncContextImpl(Request request) {
- //TODO SERVLET3 - async
- this.request = request;
- }
-
- @Override
- public void complete() {
- if (state.compareAndSet(AsyncState.STARTED, AsyncState.COMPLETING) ||
- state.compareAndSet(AsyncState.DISPATCHED, AsyncState.COMPLETING)) {
- // TODO SERVLET3 - async
- AtomicBoolean dispatched = new AtomicBoolean(false);
- request.coyoteRequest.action(ActionCode.ACTION_ASYNC_COMPLETE,dispatched);
- if (!dispatched.get()) doInternalComplete(false);
- } else {
- throw new IllegalStateException("Complete not allowed. Invalid state:"+state.get());
- }
-
- }
-
- @Override
- public void dispatch() {
- HttpServletRequest sr = (HttpServletRequest)getServletRequest();
- String path = sr.getRequestURI();
- String cpath = sr.getContextPath();
- if (cpath.length()>1) path = path.substring(cpath.length());
- dispatch(path);
- }
-
- @Override
- public void dispatch(String path) {
- dispatch(request.getServletContext(),path);
- }
-
- @Override
- public void dispatch(ServletContext context, String path) {
- // TODO SERVLET3 - async
- if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING) ||
- state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING)) {
-
- if (request.getAttribute(ASYNC_REQUEST_URI)==null) {
- request.setAttribute(ASYNC_REQUEST_URI, request.getRequestURI());
- request.setAttribute(ASYNC_CONTEXT_PATH, request.getContextPath());
- request.setAttribute(ASYNC_SERVLET_PATH, request.getServletPath());
- request.setAttribute(ASYNC_QUERY_STRING, request.getQueryString());
- }
- final RequestDispatcher requestDispatcher = context.getRequestDispatcher(path);
- final HttpServletRequest servletRequest = (HttpServletRequest)getRequest();
- final HttpServletResponse servletResponse = (HttpServletResponse)getResponse();
- Runnable run = new Runnable() {
- public void run() {
- DispatcherType type = (DispatcherType)request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
- try {
- //piggy back on the request dispatcher to ensure that filters etc get called.
- //TODO SERVLET3 - async should this be include/forward or a new dispatch type
- //javadoc suggests include with the type of DispatcherType.ASYNC
- request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
- requestDispatcher.include(servletRequest, servletResponse);
- }catch (Exception x) {
- //log.error("Async.dispatch",x);
- throw new RuntimeException(x);
- }finally {
- request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, type);
- }
- }
- };
- this.dispatch = run;
- AtomicBoolean dispatched = new AtomicBoolean(false);
- request.coyoteRequest.action(ActionCode.ACTION_ASYNC_DISPATCH, dispatched );
- if (!dispatched.get()) {
- try {
- doInternalDispatch();
- }catch (ServletException sx) {
- throw new RuntimeException(sx);
- }catch (IOException ix) {
- throw new RuntimeException(ix);
- }
- }
-
- } else {
- throw new IllegalStateException("Dispatch not allowed. Invalid state:"+state.get());
- }
- }
-
- @Override
- public ServletRequest getRequest() {
- return getServletRequest();
- }
-
- @Override
- public ServletResponse getResponse() {
- return getServletResponse();
- }
-
- @Override
- public void start(final Runnable run) {
- if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING) ||
- state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING)) {
- // TODO SERVLET3 - async
- final ServletContext sctx = getServletRequest().getServletContext();
- Runnable r = new Runnable() {
- public void run() {
- //TODO SERVLET3 - async - set context class loader when running the task.
- try {
-
- run.run();
- }catch (Exception x) {
- log.error("Unable to run async task.",x);
- }
- }
- };
- this.dispatch = r;
- AtomicBoolean dispatched = new AtomicBoolean(false);
- request.coyoteRequest.action(ActionCode.ACTION_ASYNC_DISPATCH, dispatched );
- if (!dispatched.get()) {
- try {
- doInternalDispatch();
- }catch (ServletException sx) {
- throw new RuntimeException(sx);
- }catch (IOException ix) {
- throw new RuntimeException(ix);
- }
- }
- } else {
- throw new IllegalStateException("Dispatch not allowed. Invalid state:"+state.get());
- }
- }
-
- public void addAsyncListener(AsyncListener listener) {
- AsyncListenerWrapper wrapper = new AsyncListenerWrapper();
- wrapper.setListener(listener);
- wrapper.setServletRequest(getServletRequest());
- wrapper.setServletResponse(getServletResponse());
- listeners.add(wrapper);
- }
-
- public void addAsyncListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) {
- AsyncListenerWrapper wrapper = new AsyncListenerWrapper();
- wrapper.setListener(listener);
- wrapper.setServletRequest(servletRequest);
- wrapper.setServletResponse(servletResponse);
- listeners.add(wrapper);
- }
-
-
- protected void recycle() {
- servletRequest = null;
- servletResponse = null;
- listeners.clear();
- hasOriginalRequestAndResponse = true;
- state.set(AsyncState.NOT_STARTED);
- context = null;
- timeout = -1;
- }
-
- public boolean isStarted() {
- return (state.get()!=AsyncState.NOT_STARTED);
- }
-
- public void setStarted(Context context) {
- if (state.compareAndSet(AsyncState.NOT_STARTED, AsyncState.STARTED)) {
- this.context = context;
- } else {
- throw new IllegalStateException("Start illegal. Invalid state: "+state.get());
- }
- }
-
- public ServletRequest getServletRequest() {
- return servletRequest;
- }
-
- public void setServletRequest(ServletRequest servletRequest) {
- this.servletRequest = servletRequest;
- }
-
- public ServletResponse getServletResponse() {
- return servletResponse;
- }
-
- public void setServletResponse(ServletResponse servletResponse) {
- this.servletResponse = servletResponse;
- }
-
- @Override
- public boolean hasOriginalRequestAndResponse() {
- return hasOriginalRequestAndResponse;
- }
-
- public void setHasOriginalRequestAndResponse(boolean hasOriginalRequestAndResponse) {
- this.hasOriginalRequestAndResponse = hasOriginalRequestAndResponse;
- }
-
- public boolean isCompleted() {
- return (state.get()==AsyncState.NOT_STARTED);
- }
-
- public void setCompleted() {
- this.state.set(AsyncState.NOT_STARTED);
- }
-
- public void doInternalDispatch() throws ServletException, IOException {
- if (this.state.compareAndSet(AsyncState.TIMING_OUT, AsyncState.DISPATCHED)) {
- log.info("TIMING OUT!");
- boolean listenerInvoked = false;
- for (AsyncListenerWrapper listener : listeners) {
- listener.fireOnTimeout();
- listenerInvoked = true;
- }
- if (!listenerInvoked) {
- ((HttpServletResponse)servletResponse).setStatus(500);
- }
- doInternalComplete(true);
- } else if (this.state.compareAndSet(AsyncState.DISPATCHING, AsyncState.DISPATCHED)) {
- if (this.dispatch!=null) {
- try {
- dispatch.run();
- } catch (RuntimeException x) {
- doInternalComplete(true);
- if (x.getCause() instanceof ServletException) throw (ServletException)x.getCause();
- if (x.getCause() instanceof IOException) throw (IOException)x.getCause();
- else throw new ServletException(x);
- } finally {
- dispatch = null;
- }
- }
- } else if (this.state.get()==AsyncState.COMPLETING) {
- doInternalComplete(false);
- } else {
- throw new IllegalStateException("Dispatch illegal. Invalid state: "+state.get());
- }
- }
-
- public void doInternalComplete(boolean error) {
- if (isCompleted()) return;
- if (state.compareAndSet(AsyncState.STARTED, AsyncState.NOT_STARTED)) {
- //this is the same as
- //request.startAsync().complete();
- recycle();
- } else if (state.compareAndSet(AsyncState.COMPLETING, AsyncState.NOT_STARTED)) {
- for (AsyncListenerWrapper wrapper : listeners) {
- try {
- wrapper.fireOnComplete();
- }catch (IOException x) {
- //how does this propagate, or should it?
- //TODO SERVLET3 - async
- log.error("",x);
- }
- }
- try {
- if (!error) getResponse().flushBuffer();
-
- }catch (Exception x) {
- log.error("",x);
- }
- recycle();
-
- } else {
- throw new IllegalStateException("Complete illegal. Invalid state:"+state.get());
- }
- }
-
- public AsyncState getState() {
- return state.get();
- }
-
- protected void setState(AsyncState st) {
- state.set(st);
- }
-
- public long getAsyncTimeout() {
- return timeout;
- }
-
- public void setAsyncTimeout(long timeout) {
- this.timeout = timeout;
- request.coyoteRequest.action(ActionCode.ACTION_ASYNC_SETTIMEOUT,new Long(timeout));
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.catalina.connector;
-
-import java.io.IOException;
-
-import javax.servlet.AsyncListener;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-/**
- * TODO SERVLET 3 - async
- * @author fhanik
- *
- */
-public class AsyncListenerWrapper {
-
- private AsyncListener listener = null;
- private ServletRequest servletRequest = null;
- private ServletResponse servletResponse = null;
-
- public void fireOnComplete() throws IOException {
- // TODO SERVLET 3 - async
-
- }
-
-
- public void fireOnTimeout() throws IOException {
- // TODO SERVLET 3 - async
-
- }
-
- public ServletRequest getServletRequest() {
- return servletRequest;
- }
-
- public void setServletRequest(ServletRequest servletRequest) {
- this.servletRequest = servletRequest;
- }
-
- public ServletResponse getServletResponse() {
- return servletResponse;
- }
-
- public void setServletResponse(ServletResponse servletResponse) {
- this.servletResponse = servletResponse;
- }
-
- public AsyncListener getListener() {
- return listener;
- }
-
- public void setListener(AsyncListener listener) {
- this.listener = listener;
- }
-
-
-
-}
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
import org.apache.tomcat.util.res.StringManager;
+import org.apache.catalina.core.AsyncContextImpl;
import org.apache.catalina.util.URLEncoder;
import org.apache.coyote.ActionCode;
import org.apache.coyote.Adapter;
AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext();
//TODO SERVLET3 - async
//configure settings for timed out
- asyncConImpl.setState(AsyncContextImpl.AsyncState.TIMING_OUT);
+ asyncConImpl.setTimeoutState();
}
- if (status==SocketStatus.TIMEOUT) {
- AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext();
- //TODO SERVLET3 - async
- //configure settings for timed out
- asyncConImpl.setState(AsyncContextImpl.AsyncState.TIMING_OUT);
- }
connector.getContainer().getPipeline().getFirst().invoke(request, response);
}catch (RuntimeException x) {
success = false;
import javax.security.auth.Subject;
import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import org.apache.catalina.Realm;
import org.apache.catalina.Session;
import org.apache.catalina.Wrapper;
+import org.apache.catalina.core.AsyncContextImpl;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.ParameterMap;
public AsyncContext startAsync() {
// TODO SERVLET3 - async
+ return startAsync(getRequest(),response.getResponse());
+ }
+
+ public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
if (!isAsyncSupported()) throw new IllegalStateException("Not supported.");
if (asyncContext==null) asyncContext = new AsyncContextImpl(this);
else if (asyncContext.isStarted()) throw new IllegalStateException("Already started.");
asyncContext.setStarted(getContext());
- asyncContext.setServletRequest(getRequest());
- asyncContext.setServletResponse(response.getResponse());
- return asyncContext;
- }
-
- public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
- startAsync();
asyncContext.setServletRequest(request);
asyncContext.setServletResponse(response);
+ asyncContext.initEvent();
//TODO SERVLET3 - async - need to retrieve the ServletContext here
//or just the webapp classloader associated with to do
//run with start(Runnable)
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.catalina.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.connector.Request;
+import org.apache.coyote.ActionCode;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+/**
+ *
+ * @author fhanik
+ *
+ */
+public class AsyncContextImpl implements AsyncContext {
+
+ public static enum AsyncState {
+ NOT_STARTED, STARTED, DISPATCHING, DISPATCHED, COMPLETING, TIMING_OUT
+ }
+
+ protected static Log log = LogFactory.getLog(AsyncContextImpl.class);
+
+ private ServletRequest servletRequest = null;
+ private ServletResponse servletResponse = null;
+ private List<AsyncListenerWrapper> listeners = new ArrayList<AsyncListenerWrapper>();
+ private boolean hasOriginalRequestAndResponse = true;
+ private volatile Runnable dispatch = null;
+ private Context context = null;
+ private AtomicReference<AsyncState> state = new AtomicReference<AsyncState>(AsyncState.NOT_STARTED);
+ private long timeout = -1;
+ private AsyncEvent event = null;
+
+ private Request request;
+
+ public AsyncContextImpl(Request request) {
+ //TODO SERVLET3 - async
+ this.request = request;
+ }
+
+ @Override
+ public void complete() {
+ if (state.compareAndSet(AsyncState.STARTED, AsyncState.COMPLETING) ||
+ state.compareAndSet(AsyncState.DISPATCHED, AsyncState.COMPLETING)) {
+ // TODO SERVLET3 - async
+ AtomicBoolean dispatched = new AtomicBoolean(false);
+ request.getCoyoteRequest().action(ActionCode.ACTION_ASYNC_COMPLETE,dispatched);
+ if (!dispatched.get()) doInternalComplete(false);
+ } else {
+ throw new IllegalStateException("Complete not allowed. Invalid state:"+state.get());
+ }
+
+ }
+
+ @Override
+ public void dispatch() {
+ HttpServletRequest sr = (HttpServletRequest)getServletRequest();
+ String path = sr.getRequestURI();
+ String cpath = sr.getContextPath();
+ if (cpath.length()>1) path = path.substring(cpath.length());
+ dispatch(path);
+ }
+
+ @Override
+ public void dispatch(String path) {
+ dispatch(request.getServletContext(),path);
+ }
+
+ @Override
+ public void dispatch(ServletContext context, String path) {
+ // TODO SERVLET3 - async
+ if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING) ||
+ state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING)) {
+
+ if (request.getAttribute(ASYNC_REQUEST_URI)==null) {
+ request.setAttribute(ASYNC_REQUEST_URI, request.getRequestURI());
+ request.setAttribute(ASYNC_CONTEXT_PATH, request.getContextPath());
+ request.setAttribute(ASYNC_SERVLET_PATH, request.getServletPath());
+ request.setAttribute(ASYNC_QUERY_STRING, request.getQueryString());
+ }
+ final RequestDispatcher requestDispatcher = context.getRequestDispatcher(path);
+ final HttpServletRequest servletRequest = (HttpServletRequest)getRequest();
+ final HttpServletResponse servletResponse = (HttpServletResponse)getResponse();
+ Runnable run = new Runnable() {
+ public void run() {
+ DispatcherType type = (DispatcherType)request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
+ try {
+ //piggy back on the request dispatcher to ensure that filters etc get called.
+ //TODO SERVLET3 - async should this be include/forward or a new dispatch type
+ //javadoc suggests include with the type of DispatcherType.ASYNC
+ request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
+ requestDispatcher.include(servletRequest, servletResponse);
+ }catch (Exception x) {
+ //log.error("Async.dispatch",x);
+ throw new RuntimeException(x);
+ }finally {
+ request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, type);
+ }
+ }
+ };
+ this.dispatch = run;
+ AtomicBoolean dispatched = new AtomicBoolean(false);
+ request.getCoyoteRequest().action(ActionCode.ACTION_ASYNC_DISPATCH, dispatched );
+ if (!dispatched.get()) {
+ try {
+ doInternalDispatch();
+ }catch (ServletException sx) {
+ throw new RuntimeException(sx);
+ }catch (IOException ix) {
+ throw new RuntimeException(ix);
+ }
+ }
+
+ } else {
+ throw new IllegalStateException("Dispatch not allowed. Invalid state:"+state.get());
+ }
+ }
+
+ @Override
+ public ServletRequest getRequest() {
+ return getServletRequest();
+ }
+
+ @Override
+ public ServletResponse getResponse() {
+ return getServletResponse();
+ }
+
+ @Override
+ public void start(final Runnable run) {
+ if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING) ||
+ state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING)) {
+ // TODO SERVLET3 - async
+ final ServletContext sctx = getServletRequest().getServletContext();
+ Runnable r = new Runnable() {
+ public void run() {
+ //TODO SERVLET3 - async - set context class loader when running the task.
+ try {
+
+ run.run();
+ }catch (Exception x) {
+ log.error("Unable to run async task.",x);
+ }
+ }
+ };
+ this.dispatch = r;
+ AtomicBoolean dispatched = new AtomicBoolean(false);
+ request.getCoyoteRequest().action(ActionCode.ACTION_ASYNC_DISPATCH, dispatched );
+ if (!dispatched.get()) {
+ try {
+ doInternalDispatch();
+ }catch (ServletException sx) {
+ throw new RuntimeException(sx);
+ }catch (IOException ix) {
+ throw new RuntimeException(ix);
+ }
+ }
+ } else {
+ throw new IllegalStateException("Dispatch not allowed. Invalid state:"+state.get());
+ }
+ }
+
+ public void addAsyncListener(AsyncListener listener) {
+ AsyncListenerWrapper wrapper = new AsyncListenerWrapper();
+ wrapper.setListener(listener);
+ listeners.add(wrapper);
+ }
+
+ public void addAsyncListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) {
+ AsyncListenerWrapper wrapper = new AsyncListenerWrapper();
+ wrapper.setListener(listener);
+ listeners.add(wrapper);
+ }
+
+
+ public void recycle() {
+ servletRequest = null;
+ servletResponse = null;
+ listeners.clear();
+ hasOriginalRequestAndResponse = true;
+ state.set(AsyncState.NOT_STARTED);
+ context = null;
+ timeout = -1;
+ event = null;
+ }
+
+ public boolean isStarted() {
+ return (state.get()!=AsyncState.NOT_STARTED);
+ }
+
+ public void setStarted(Context context) {
+ if (state.compareAndSet(AsyncState.NOT_STARTED, AsyncState.STARTED)) {
+ this.context = context;
+ } else {
+ throw new IllegalStateException("Start illegal. Invalid state: "+state.get());
+ }
+ }
+
+ public ServletRequest getServletRequest() {
+ return servletRequest;
+ }
+
+ public void setServletRequest(ServletRequest servletRequest) {
+ this.servletRequest = servletRequest;
+ }
+
+ public ServletResponse getServletResponse() {
+ return servletResponse;
+ }
+
+ public void setServletResponse(ServletResponse servletResponse) {
+ this.servletResponse = servletResponse;
+ }
+
+ @Override
+ public boolean hasOriginalRequestAndResponse() {
+ return hasOriginalRequestAndResponse;
+ }
+
+ public void setHasOriginalRequestAndResponse(boolean hasOriginalRequestAndResponse) {
+ this.hasOriginalRequestAndResponse = hasOriginalRequestAndResponse;
+ }
+
+ public boolean isCompleted() {
+ return (state.get()==AsyncState.NOT_STARTED);
+ }
+
+ public void setCompleted() {
+ this.state.set(AsyncState.NOT_STARTED);
+ }
+
+ public void doInternalDispatch() throws ServletException, IOException {
+ if (this.state.compareAndSet(AsyncState.TIMING_OUT, AsyncState.DISPATCHED)) {
+ log.debug("TIMING OUT!");
+ boolean listenerInvoked = false;
+ for (AsyncListenerWrapper listener : listeners) {
+ listener.fireOnTimeout(event);
+ listenerInvoked = true;
+ }
+ if (!listenerInvoked) {
+ ((HttpServletResponse)servletResponse).setStatus(500);
+ }
+ doInternalComplete(true);
+ } else if (this.state.compareAndSet(AsyncState.DISPATCHING, AsyncState.DISPATCHED)) {
+ if (this.dispatch!=null) {
+ try {
+ dispatch.run();
+ } catch (RuntimeException x) {
+ doInternalComplete(true);
+ if (x.getCause() instanceof ServletException) throw (ServletException)x.getCause();
+ if (x.getCause() instanceof IOException) throw (IOException)x.getCause();
+ else throw new ServletException(x);
+ } finally {
+ dispatch = null;
+ }
+ }
+ } else if (this.state.get()==AsyncState.COMPLETING) {
+ doInternalComplete(false);
+ } else {
+ throw new IllegalStateException("Dispatch illegal. Invalid state: "+state.get());
+ }
+ }
+
+ public void doInternalComplete(boolean error) {
+ if (isCompleted()) return;
+ if (state.compareAndSet(AsyncState.STARTED, AsyncState.NOT_STARTED)) {
+ //this is the same as
+ //request.startAsync().complete();
+ recycle();
+ } else if (state.compareAndSet(AsyncState.COMPLETING, AsyncState.NOT_STARTED)) {
+ for (AsyncListenerWrapper wrapper : listeners) {
+ try {
+ wrapper.fireOnComplete(event);
+ }catch (IOException x) {
+ //how does this propagate, or should it?
+ //TODO SERVLET3 - async
+ log.error("",x);
+ }
+ }
+ try {
+ if (!error) getResponse().flushBuffer();
+
+ }catch (Exception x) {
+ log.error("",x);
+ }
+ recycle();
+
+ } else {
+ throw new IllegalStateException("Complete illegal. Invalid state:"+state.get());
+ }
+ }
+
+ public AsyncState getState() {
+ return state.get();
+ }
+
+ protected void setState(AsyncState st) {
+ state.set(st);
+ }
+
+ public long getAsyncTimeout() {
+ return timeout;
+ }
+
+ public void setAsyncTimeout(long timeout) {
+ this.timeout = timeout;
+ request.getCoyoteRequest().action(ActionCode.ACTION_ASYNC_SETTIMEOUT,new Long(timeout));
+ }
+
+ public void setTimeoutState() {
+ state.set(AsyncState.TIMING_OUT);
+ }
+
+ public void initEvent() {
+ event = new AsyncEvent(getRequest(),getResponse());
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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.catalina.core;
+
+import java.io.IOException;
+
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+/**
+ * TODO SERVLET 3 - async
+ * @author fhanik
+ *
+ */
+public class AsyncListenerWrapper {
+
+ private AsyncListener listener = null;
+
+ public void fireOnComplete(AsyncEvent event) throws IOException {
+ // TODO SERVLET 3 - async
+ listener.onComplete(event);
+ }
+
+
+ public void fireOnTimeout(AsyncEvent event) throws IOException {
+ // TODO SERVLET 3 - async
+ listener.onTimeout(event);
+ }
+
+ public AsyncListener getListener() {
+ return listener;
+ }
+
+ public void setListener(AsyncListener listener) {
+ this.listener = listener;
+ }
+
+
+
+}
import org.apache.catalina.CometProcessor;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
-import org.apache.catalina.connector.AsyncContextImpl;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
try {
Thread.currentThread().setName("Async0-Thread");
log.info("Putting AsyncThread to sleep");
- Thread.sleep(10*1000);
+ Thread.sleep(2*1000);
log.info("Dispatching");
actx.dispatch();
}catch (InterruptedException x) {
String path = "/jsp/async/async1.jsp";
Thread.currentThread().setName("Async1-Thread");
log.info("Putting AsyncThread to sleep");
- Thread.sleep(10*1000);
+ Thread.sleep(2*1000);
log.info("Dispatching to "+path);
actx.dispatch(path);
}catch (InterruptedException x) {
try {
Thread.currentThread().setName("Async2-Thread");
log.info("Putting AsyncThread to sleep");
- Thread.sleep(10*1000);
+ Thread.sleep(2*1000);
log.info("Writing data.");
actx.getResponse().getWriter().write("Output from background thread. Time:"+System.currentTimeMillis()+"\n");
actx.complete();