1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.osgi.equinoxtools.console;
14
15 import java.io.IOException;
16 import java.io.PrintWriter;
17 import java.util.HashMap;
18 import java.util.LinkedList;
19 import java.util.Map;
20 import java.util.Queue;
21
22 import javax.servlet.ServletException;
23 import javax.servlet.http.HttpServlet;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.eclipse.jetty.continuation.Continuation;
28 import org.eclipse.jetty.continuation.ContinuationSupport;
29 import org.eclipse.jetty.osgi.equinoxtools.WebEquinoxToolsActivator;
30 import org.eclipse.jetty.osgi.equinoxtools.console.WebConsoleWriterOutputStream.OnFlushListener;
31 import org.eclipse.osgi.framework.console.ConsoleSession;
32
33
34
35
36
37 public class EquinoxConsoleContinuationServlet extends HttpServlet implements OnFlushListener
38 {
39
40 private static final long serialVersionUID = 1L;
41 private Map<String,ConsoleUser> _consoleUsers = new HashMap<String, ConsoleUser>();
42 private WebConsoleSession _consoleSession;
43 private EquinoxChattingSupport _support;
44
45
46
47
48 public EquinoxConsoleContinuationServlet()
49 {
50
51 }
52
53
54
55 public EquinoxConsoleContinuationServlet(WebConsoleSession consoleSession, EquinoxChattingSupport support)
56 {
57 _consoleSession = consoleSession;
58 _support = support;
59 }
60 @Override
61 public void init() throws ServletException
62 {
63 if (_consoleSession == null)
64 {
65 _consoleSession = new WebConsoleSession();
66 WebEquinoxToolsActivator.getContext().registerService(ConsoleSession.class.getName(), _consoleSession, null);
67 }
68 if (_support == null)
69 {
70 _support = new EquinoxChattingSupport(_consoleSession);
71 }
72 _consoleSession.addOnFlushListener(this);
73 }
74 @Override
75 public void destroy()
76 {
77 _consoleSession.removeOnFlushListener(this);
78 }
79
80
81
82 @Override
83 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
84 {
85 if (request.getParameter("action")!=null)
86 doPost(request,response);
87 else
88 response.sendRedirect(request.getContextPath() + request.getServletPath()
89 + (request.getPathInfo() != null ? request.getPathInfo() : "") + "/index.html");
90 }
91
92
93 @Override
94 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
95 {
96
97 String action = request.getParameter("action");
98 String message = request.getParameter("message");
99 String username = request.getParameter("user");
100
101 if (action.equals("join"))
102 join(request,response,username);
103 else if (action.equals("poll"))
104 poll(request,response,username);
105 else if (action.equals("chat"))
106 chat(request,response,username,message);
107 }
108
109 private synchronized void join(HttpServletRequest request,HttpServletResponse response,String username)
110 throws IOException
111 {
112 ConsoleUser member = new ConsoleUser(username);
113 _consoleUsers.put(username,member);
114 response.setContentType("text/json;charset=utf-8");
115 PrintWriter out=response.getWriter();
116 out.print("{action:\"join\"}");
117 }
118
119 private synchronized void poll(HttpServletRequest request,HttpServletResponse response,String username)
120 throws IOException
121 {
122 ConsoleUser member = _consoleUsers.get(username);
123 if (member==null)
124 {
125 response.sendError(503);
126 return;
127 }
128
129 synchronized(member)
130 {
131 if (member.getMessageQueue().size()>0)
132 {
133
134 response.setContentType("text/json;charset=utf-8");
135 StringBuilder buf=new StringBuilder();
136
137 buf.append("{\"action\":\"poll\",");
138 buf.append("\"from\":\"");
139 buf.append(member.getMessageQueue().poll());
140 buf.append("\",");
141
142 String message = member.getMessageQueue().poll();
143 int quote=message.indexOf('"');
144 while (quote>=0)
145 {
146 message=message.substring(0,quote)+'\\'+message.substring(quote);
147 quote=message.indexOf('"',quote+2);
148 }
149 buf.append("\"chat\":\"");
150 buf.append(message);
151 buf.append("\"}");
152 byte[] bytes = buf.toString().getBytes("utf-8");
153 response.setContentLength(bytes.length);
154 response.getOutputStream().write(bytes);
155 }
156 else
157 {
158 Continuation continuation = ContinuationSupport.getContinuation(request);
159 if (continuation.isInitial())
160 {
161
162 continuation.setTimeout(20000);
163 continuation.suspend();
164 member.setContinuation(continuation);
165 }
166 else
167 {
168
169 response.setContentType("text/json;charset=utf-8");
170 PrintWriter out=response.getWriter();
171 out.print("{action:\"poll\"}");
172 }
173 }
174 }
175 }
176
177 private synchronized void chat(HttpServletRequest request,HttpServletResponse response,String username,String message)
178 throws IOException
179 {
180 if (!message.endsWith("has joined!"))
181 {
182 _consoleSession.processCommand(message, false);
183 }
184
185 onFlush();
186
187 response.setContentType("text/json;charset=utf-8");
188 PrintWriter out=response.getWriter();
189 out.print("{action:\"chat\"}");
190 }
191
192
193
194
195 public void onFlush()
196 {
197 Queue<String> pendingConsoleOutputMessages = _support.processConsoleOutput(true, this);
198 for (ConsoleUser m:_consoleUsers.values())
199 {
200 synchronized (m)
201 {
202
203
204 m.getMessageQueue().addAll(pendingConsoleOutputMessages);
205
206
207 if (m.getContinuation()!=null)
208 {
209 m.getContinuation().resume();
210 m.setContinuation(null);
211 }
212 }
213 }
214 }
215
216 class ConsoleUser
217 {
218 private String _name;
219 private Continuation _continuation;
220 private Queue<String> _queue = new LinkedList<String>();
221
222 public ConsoleUser(String name)
223 {
224 _name = name;
225 }
226
227 public String getName()
228 {
229 return _name;
230 }
231
232 public void setContinuation(Continuation continuation)
233 {
234 _continuation = continuation;
235 }
236
237 public Continuation getContinuation()
238 {
239 return _continuation;
240 }
241 public Queue<String> getMessageQueue()
242 {
243 return _queue;
244 }
245
246 }
247 }