38
38
public class smalltalk extends AbstractApplication {
39
39
40
40
private static final long TIMEOUT = 1000 ;
41
- private volatile Map <String , Queue <Builder >> sessions ;
42
41
private final Map <String , Map <String , Queue <Builder >>> groups = Collections .synchronizedMap (new HashMap <String , Map <String , Queue <Builder >>>());
43
42
44
43
@ Override
@@ -67,8 +66,9 @@ public smalltalk index() {
67
66
meeting_code = java .util .UUID .randomUUID ().toString ();
68
67
session .setAttribute ("meeting_code" , meeting_code );
69
68
70
- this .sessions = new HashMap <String , Queue <Builder >>();
71
- this .groups .put (meeting_code .toString (), this .sessions );
69
+ final Map <String , Queue <Builder >> sessions = new HashMap <String , Queue <Builder >>();
70
+ sessions .put (session .getId (), new ArrayDeque <Builder >());
71
+ this .groups .put (meeting_code .toString (), sessions );
72
72
73
73
System .out .println ("New meeting generated:" + meeting_code );
74
74
}
@@ -130,24 +130,36 @@ public String start(String name) throws ApplicationException {
130
130
return name ;
131
131
}
132
132
133
- public String update () throws ApplicationException {
133
+ public String update () throws ApplicationException , IOException {
134
134
final HttpServletRequest request = (HttpServletRequest ) this .context .getAttribute ("HTTP_REQUEST" );
135
+ final HttpServletResponse response = (HttpServletResponse ) this .context .getAttribute ("HTTP_RESPONSE" );
135
136
final HttpSession session = request .getSession ();
136
137
final Object meeting_code = session .getAttribute ("meeting_code" );
137
138
138
139
if ( meeting_code != null ) {
139
- this .checkup (meeting_code );
140
-
141
140
Builder message ;
142
- final String sessionId = session .getId ();
143
- synchronized (this .sessions ) {
141
+
142
+ Map <String , Queue <Builder >> sessions ;
143
+ synchronized (this .groups ) {
144
+ if ((sessions = this .groups .get (meeting_code )) == null ) {
145
+ this .groups .put (meeting_code .toString (), new HashMap <String , Queue <Builder >>());
146
+ return "{}" ;
147
+ }
148
+
149
+ final String sessionId = session .getId ();
144
150
do {
145
151
try {
146
- this .sessions .wait (TIMEOUT );
152
+ this .groups .wait (TIMEOUT );
147
153
} catch (InterruptedException e ) {
148
154
throw new ApplicationException (e .getMessage (), e );
149
155
}
150
- } while (this .sessions .get (sessionId ) == null || (message = this .sessions .get (sessionId ).poll ()) == null );
156
+ } while (sessions .get (sessionId ) == null || (message = sessions .get (sessionId ).poll ()) == null );
157
+
158
+ // @Todo
159
+ // To review why the context is not thread-safe.
160
+ // Use response.getWriter() to avoid the inconformity issue.
161
+ response .getWriter ().println (message );
162
+ response .getWriter ().close ();
151
163
152
164
System .out .println ("[" +sessionId +"][" + session .getAttribute ("meeting_code" ) + "]:" + message );
153
165
System .out .println ("-------------" );
@@ -174,19 +186,22 @@ public String save() {
174
186
builder .put ("time" , format .format (new Date ()));
175
187
builder .put ("message" , filter (request .getParameter ("text" )));
176
188
177
- this .checkup (meeting_code );
189
+ Map <String , Queue <Builder >> sessions ;
190
+ synchronized (this .groups ) {
191
+ if ((sessions = this .groups .get (meeting_code )) == null ) {
192
+ this .groups .put (meeting_code .toString (), new HashMap <String , Queue <Builder >>());
193
+ }
178
194
179
- final String sessionId = session .getId ();
180
- synchronized (this .sessions ) {
181
- if (this .sessions .get (sessionId ) == null ) {
182
- this .sessions .put (sessionId , new ArrayDeque <Builder >());
195
+ final String sessionId = session .getId ();
196
+ if (sessions .get (sessionId ) == null ) {
197
+ sessions .put (sessionId , new ArrayDeque <Builder >());
183
198
}
184
199
185
- final Collection <Queue <Builder >> set = this . sessions .values ();
200
+ final Collection <Queue <Builder >> set = sessions .values ();
186
201
final Iterator <Queue <Builder >> iterator = set .iterator ();
187
202
while (iterator .hasNext ()) {
188
203
iterator .next ().add (builder );
189
- this .sessions .notifyAll ();
204
+ this .groups .notifyAll ();
190
205
}
191
206
}
192
207
return builder .toString ();
@@ -212,22 +227,24 @@ public String command() {
212
227
builder .put ("user" , session .getAttribute ("user" ));
213
228
builder .put ("cmd" , request .getParameter ("cmd" ));
214
229
215
- this .checkup (meeting_code );
230
+ Map <String , Queue <Builder >> sessions ;
231
+ synchronized (this .groups ) {
232
+ if ((sessions = this .groups .get (meeting_code )) == null ) {
233
+ this .groups .put (meeting_code .toString (), new HashMap <String , Queue <Builder >>());
234
+ }
216
235
217
- final String sessionId = session .getId ();
218
- synchronized (this .sessions ) {
219
- if (this .sessions .get (sessionId ) == null ) {
220
- this .sessions .put (sessionId , new ArrayDeque <Builder >());
236
+ final String sessionId = session .getId ();
237
+ if (sessions .get (sessionId ) == null ) {
238
+ sessions .put (sessionId , new ArrayDeque <Builder >());
221
239
}
222
240
223
- final Collection <Queue <Builder >> set = this . sessions .values ();
241
+ final Collection <Queue <Builder >> set = sessions .values ();
224
242
final Iterator <Queue <Builder >> iterator = set .iterator ();
225
243
while (iterator .hasNext ()) {
226
244
iterator .next ().add (builder );
227
- this .sessions .notifyAll ();
245
+ this .groups .notifyAll ();
228
246
}
229
247
}
230
-
231
248
return "{}" ;
232
249
}
233
250
@@ -240,7 +257,7 @@ public String upload() throws ApplicationException {
240
257
response .setContentType ("text/html;charset=UTF-8" );
241
258
242
259
// Create path components to save the file
243
- final String path = this .context . getAttribute ("system.directory" ) != null ? this .context . getAttribute ("system.directory" ).toString () + "/files" : "files" ;
260
+ final String path = this .config . get ("system.directory" ) != null ? this .config . get ("system.directory" ).toString () + "/files" : "files" ;
244
261
245
262
final Builders builders = new Builders ();
246
263
try {
@@ -301,15 +318,6 @@ protected smalltalk exit() {
301
318
return this ;
302
319
}
303
320
304
- private void checkup (final Object meeting_code ) {
305
- if ((this .sessions = this .groups .get (meeting_code )) == null ) {
306
- this .sessions = new HashMap <String , Queue <Builder >>();
307
- this .groups .put (meeting_code .toString (), this .sessions );
308
-
309
- this .setVariable ("meeting_code" , meeting_code .toString ());
310
- }
311
- }
312
-
313
321
protected String filter (String text ) {
314
322
text = text .replaceAll ("<script(.*)>(.*)<\\ /script>" , "" );
315
323
return text ;
0 commit comments