001: package com.icesoft.faces.webapp.http.servlet;
002:
003: import java.io.IOException;
004: import java.io.InputStream;
005: import java.io.Writer;
006: import java.io.PrintWriter;
007:
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.Set;
011: import java.util.HashSet;
012: import java.util.Iterator;
013:
014: import org.apache.catalina.CometEvent;
015: import org.apache.catalina.CometProcessor;
016:
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019:
020: import javax.servlet.ServletException;
021: import javax.servlet.http.HttpServlet;
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import com.icesoft.faces.webapp.http.core.SendUpdatedViews;
026: import com.icesoft.faces.webapp.http.core.ViewQueue;
027:
028: public class TomcatPushServlet extends HttpServlet implements
029: CometProcessor {
030:
031: private static Log log = LogFactory.getLog(TomcatPushServlet.class);
032:
033: public void init() throws ServletException {
034: }
035:
036: public void destroy() {
037: }
038:
039: /**
040: * Process the given Comet event.
041: *
042: * @param event The Comet event that will be processed
043: * @throws IOException
044: * @throws ServletException
045: */
046: public void event(CometEvent event) throws IOException,
047: ServletException {
048:
049: HttpServletRequest request = event.getHttpServletRequest();
050: HttpServletResponse response = event.getHttpServletResponse();
051:
052: if (event.getEventType() == CometEvent.EventType.BEGIN) {
053: begin(event, request, response);
054: } else if (event.getEventType() == CometEvent.EventType.ERROR) {
055: error(event, request, response);
056: } else if (event.getEventType() == CometEvent.EventType.END) {
057: end(event, request, response);
058: } else if (event.getEventType() == CometEvent.EventType.READ) {
059: read(event, request, response);
060: }
061: }
062:
063: protected void begin(CometEvent event, HttpServletRequest request,
064: HttpServletResponse response) throws IOException,
065: ServletException {
066: //We need access to the CometEvent, but this is not passed down through
067: //our dispatcher chain, so we obtain the queues directly here
068: MainSessionBoundServlet mainBound = (MainSessionBoundServlet) SessionDispatcher
069: .getSingletonSessionServlet(request.getSession());
070: ViewQueue allUpdatedViews = mainBound.getAllUpdatedViews();
071: Collection synchronouslyUpdatedViews = mainBound
072: .getSynchronouslyUpdatedViews();
073: allUpdatedViews.onPut(new EventResponder(event,
074: synchronouslyUpdatedViews, allUpdatedViews));
075: }
076:
077: protected void end(CometEvent event, HttpServletRequest request,
078: HttpServletResponse response) throws IOException,
079: ServletException {
080: event.close();
081: }
082:
083: protected void error(CometEvent event, HttpServletRequest request,
084: HttpServletResponse response) throws IOException,
085: ServletException {
086: }
087:
088: protected void read(CometEvent event, HttpServletRequest request,
089: HttpServletResponse response) throws IOException,
090: ServletException {
091: InputStream is = request.getInputStream();
092: byte[] buf = new byte[512];
093: do {
094: int n = is.read(buf); //can throw an IOException
095: if (n > 0) {
096: if (log.isDebugEnabled()) {
097: log.debug("Read " + n + " bytes: "
098: + new String(buf, 0, n) + " for session: "
099: + request.getSession(true).getId());
100: }
101: } else if (n < 0) {
102: error(event, request, response);
103: return;
104: }
105: } while (is.available() > 0);
106: }
107:
108: protected void service(HttpServletRequest request,
109: HttpServletResponse response) throws IOException,
110: ServletException {
111: // Not used by Tomcat6
112: throw new ServletException(
113: "service() not supported by TomcatPushServlet");
114: }
115:
116: }
117:
118: class EventResponder implements Runnable {
119: ViewQueue allUpdatedViews;
120: Collection synchronouslyUpdatedViews;
121: CometEvent event;
122: Writer writer;
123:
124: public EventResponder(CometEvent event,
125: Collection synchronouslyUpdatedViews,
126: ViewQueue allUpdatedViews) {
127: this .event = event;
128: this .synchronouslyUpdatedViews = synchronouslyUpdatedViews;
129: this .allUpdatedViews = allUpdatedViews;
130: try {
131: HttpServletResponse response = event
132: .getHttpServletResponse();
133: writer = response.getWriter();
134: response.setContentType("text/xml;charset=UTF-8");
135: } catch (IOException e) {
136: e.printStackTrace();
137: }
138: }
139:
140: public void run() {
141: try {
142: allUpdatedViews.removeAll(synchronouslyUpdatedViews);
143: synchronouslyUpdatedViews.clear();
144: Set viewIdentifiers = new HashSet(allUpdatedViews);
145: if (!viewIdentifiers.isEmpty()) {
146: Iterator identifiers = viewIdentifiers.iterator();
147: writer.write("<updated-views>");
148: while (identifiers.hasNext()) {
149: writer.write(identifiers.next().toString());
150: writer.write(' ');
151: }
152: writer.write("</updated-views>");
153: event.close();
154: }
155: } catch (Throwable e) {
156: e.printStackTrace();
157: }
158: }
159:
160: }
|