1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gscg.common.interactionlayer.messaging;
15
16 import java.io.IOException;
17 import java.io.ObjectOutputStream;
18 import java.io.Serializable;
19 import java.rmi.RemoteException;
20 import java.text.DateFormat;
21 import java.util.ArrayList;
22 import java.util.Calendar;
23 import java.util.Timer;
24 import java.util.TimerTask;
25
26 import nl.tudelft.simulation.dsol.experiment.TimeUnit;
27 import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
28 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
29 import nl.tudelft.simulation.event.Event;
30 import nl.tudelft.simulation.event.EventInterface;
31 import nl.tudelft.simulation.event.EventListenerInterface;
32 import nl.tudelft.simulation.event.EventProducer;
33 import nl.tudelft.simulation.event.EventType;
34 import nl.tudelft.simulation.logger.Logger;
35 import nl.tudelft.simulation.naming.InitialEventContext;
36
37 import org.gscg.common.gui.exceptions.ReceivedUnknownEventException;
38 import org.gscg.common.interactionlayer.AnnounceInterface;
39 import org.gscg.common.interactionlayer.GlobalInteractionLayerInterface;
40 import org.gscg.common.interactionlayer.dataobjects.NewsMessage;
41 import org.gscg.gameleader.interactionlayer.GameLeaderInteractionLayer;
42 import org.gscg.singleuser.interactionlayer.SingleUserInteractionLayerInterface;
43
44 /***
45 * <p>
46 *
47 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
48 * Delft, the Netherlands. All rights reserved.
49 *
50 * See for project information <a href="http://www.simulation.tudelft.nl/">
51 * www.simulation.tudelft.nl </a>.
52 *
53 * The source code and binary code of this software is proprietary information
54 * of Delft University of Technology.
55 *
56 *
57 * @author <a
58 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
59 * van Houten </a>
60 * @version $Revision: 1.2 $ $Date: 2005/08/09 15:43:42 $
61 * @since 1.0.0
62 *
63 */
64 public class ScenarioText extends EventProducer implements AnnounceInterface,
65 EventListenerInterface, Serializable
66 {
67 /*** the serial version uid */
68 private static final long serialVersionUID = 11L;
69
70 /*** the scenario text for this class */
71 private static ScenarioText scenarioText = null;
72
73 /*** the name of this object in the context */
74 public static final String CONTEXT_NAME = "SCENARIO_TEXT";
75
76 /*** the small news message event; this event is for a news bar */
77 public static final EventType SMALL_NEWS_MESSAGE_EVENT = new EventType(
78 "SMALL_NEWS_MESSAGE_EVENT");
79
80 /*** the sent small news message event */
81 public static final EventType GAME_LEADER_SENT_SMALL_NEWS_MESSAGE_EVENT = new EventType(
82 "GAME_LEADER_SENT_SMALL_NEWS_MESSAGE_EVENT");
83
84 /*** the large news message event; this event is for a message panel */
85 public static final EventType LARGE_NEWS_MESSAGE_EVENT = new EventType(
86 "LARGE_NEWS_MESSAGE_EVENT");
87
88 /*** the cache large news message event; this event is for a message panel */
89 public static final EventType CACHE_LARGE_NEWS_MESSAGE_EVENT = new EventType(
90 "CACHE_LARGE_NEWS_MESSAGE_EVENT");
91
92 /*** the history */
93 private ArrayList history = new ArrayList();
94
95 /*** the simulator */
96 private SimulatorInterface simulator = null;
97
98 /*** the start time */
99 private long startTime = 0L;
100
101 /*** the calendar */
102 private Calendar calendar = Calendar.getInstance();
103
104 /*** the date formatter */
105 private DateFormat dateFormat = DateFormat.getDateInstance();
106
107 /*** the time unit */
108 private TimeUnitInterface timeUnit = null;
109
110 /***
111 * constructs a new ScenarioText
112 *
113 * @param simulator the simulator to use
114 */
115 public ScenarioText(final SimulatorInterface simulator)
116 {
117 super();
118 ScenarioText.scenarioText = this;
119 this.simulator = simulator;
120 try
121 {
122 this.startTime = simulator.getReplication().getRunControl()
123 .getTreatment().getStartTime();
124 this.timeUnit = this.simulator.getReplication().getRunControl()
125 .getTreatment().getTimeUnit();
126
127 new InitialEventContext().bind(ScenarioText.CONTEXT_NAME, this);
128 } catch (Exception exception)
129 {
130 Logger.severe(this, "<init>", exception);
131 }
132 }
133
134 /***
135 * Method addInteractionLayer adds an interaction layer to the list of
136 * requestForQuotes of the scenario texts
137 *
138 * @param layer the interaction layer
139 */
140 public void addInteractionLayer(final GlobalInteractionLayerInterface layer)
141 {
142 this.addListener(layer, ScenarioText.SMALL_NEWS_MESSAGE_EVENT);
143 this.addListener(layer, ScenarioText.LARGE_NEWS_MESSAGE_EVENT);
144 this.addListener(layer, ScenarioText.CACHE_LARGE_NEWS_MESSAGE_EVENT);
145
146 if (SingleUserInteractionLayerInterface.class.isAssignableFrom(layer
147 .getClass()))
148 {
149 try
150 {
151 ((SingleUserInteractionLayerInterface) layer)
152 .addEventType(ScenarioText.SMALL_NEWS_MESSAGE_EVENT);
153 ((SingleUserInteractionLayerInterface) layer)
154 .addEventType(ScenarioText.LARGE_NEWS_MESSAGE_EVENT);
155 ((SingleUserInteractionLayerInterface) layer)
156 .addEventType(ScenarioText.CACHE_LARGE_NEWS_MESSAGE_EVENT);
157 } catch (RemoteException remoteException)
158 {
159 Logger.severe(this, "addInteractionLayer", remoteException);
160 }
161 }
162
163 if (layer instanceof GameLeaderInteractionLayer)
164 {
165 ((GameLeaderInteractionLayer) layer).addListener(this,
166 ScenarioText.GAME_LEADER_SENT_SMALL_NEWS_MESSAGE_EVENT);
167 }
168 }
169
170 /***
171 * Method fireNewsMessageEvent.
172 *
173 * @param i i
174 */
175 public void fireNewsMessageEvent(final Integer i)
176 {
177 try
178 {
179 double time = TimeUnit.convert(this.simulator.getSimulatorTime(),
180 this.timeUnit, TimeUnitInterface.MILLISECOND);
181 this.calendar.setTimeInMillis(this.startTime + (long) time);
182 } catch (RemoteException remoteException)
183 {
184 Logger.severe(this, "fireNewsMessageEvent", remoteException);
185 }
186 String date = this.dateFormat.format(this.calendar.getTime());
187 String[] data = new String[]{"title", date, "content", "no_region", ""};
188 this.fireEvent(new Event(ScenarioText.LARGE_NEWS_MESSAGE_EVENT, this,
189 data));
190 this.history.add(data);
191 this.fireEvent(new Event(ScenarioText.SMALL_NEWS_MESSAGE_EVENT, this,
192 " >>> GAME LEADER: Attention, " + i.intValue()
193 + " days left in the game"));
194 }
195
196 /***
197 * Fires a large news message event with the given title and conten.
198 * Furthermore, a small news message is sent indicating to players that a
199 * large news message has been published.
200 *
201 * @param title the title of the large news message
202 * @param content the content for the large news message
203 * @param summary the summary of the large news message
204 * @param region the region for the message, e.g. asia or europe
205 * @param type the type of message, e.g. money, fire or graph (business)
206 */
207 public void fireNewsMessageEvent(final String title, final String content,
208 final String summary, final String region, final String type)
209 {
210 try
211 {
212 double time = TimeUnit.convert(this.simulator.getSimulatorTime(),
213 this.timeUnit, TimeUnitInterface.MILLISECOND);
214 this.calendar.setTimeInMillis(this.startTime + (long) time);
215 } catch (RemoteException remoteException)
216 {
217 Logger.severe(this, "fireNewsMessageEvent", remoteException);
218 }
219 String date = this.dateFormat.format(this.calendar.getTime());
220 String[] data = new String[]{title, date, content, summary, region,
221 type};
222 this.history.add(data);
223 this.fireEvent(new Event(ScenarioText.LARGE_NEWS_MESSAGE_EVENT, this,
224 data));
225 this
226 .fireEvent(new Event(ScenarioText.SMALL_NEWS_MESSAGE_EVENT,
227 this,
228 " >>> GAME LEADER: Attention, a large news message has been published"));
229
230 new TimedNewsMessageSender(this).scheduleTask();
231 }
232
233
234 /***
235 * @param eventType the event type
236 * @param announce indicates whether it is announce (=true) or not
237 * @param singleUserInteractionLayer the single user interaction layer
238 */
239 public void announce(final EventType eventType, final boolean announce,
240 final SingleUserInteractionLayerInterface singleUserInteractionLayer)
241 {
242 if (eventType.equals(ScenarioText.CACHE_LARGE_NEWS_MESSAGE_EVENT))
243 {
244 ArrayList clone = (ArrayList) this.history.clone();
245 try
246 {
247 singleUserInteractionLayer.notifyAnnounced(new Event(
248 ScenarioText.CACHE_LARGE_NEWS_MESSAGE_EVENT, this,
249 clone));
250 } catch (RemoteException remoteException)
251 {
252 Logger.severe(this, "announce", remoteException);
253 }
254 return;
255 }
256 new ReceivedUnknownEventException(this, "announce 1", eventType);
257 }
258
259 /***
260 * @see org.gscg.common.interactionlayer.AnnounceInterface#announce(nl.tudelft.simulation.event.EventType,
261 * boolean)
262 */
263 public void announce(final EventType eventType, final boolean announce)
264 {
265 new ReceivedUnknownEventException(this, "announce 2", eventType);
266 }
267
268 /***
269 * @see nl.tudelft.simulation.event.EventListenerInterface#notify(nl.tudelft.simulation.event.EventInterface)
270 */
271 public void notify(final EventInterface event) throws RemoteException
272 {
273
274 if (event.getType().equals(
275 ScenarioText.GAME_LEADER_SENT_SMALL_NEWS_MESSAGE_EVENT))
276
277 {
278 NewsMessage message = (NewsMessage) event.getContent();
279 this.fireEvent(new Event(ScenarioText.SMALL_NEWS_MESSAGE_EVENT,
280 this, " >>> GAME LEADER: " + message.getContent()));
281 new TimedNewsMessageSender(this).scheduleTask();
282 return;
283 }
284 new ReceivedUnknownEventException(this, "notify", event.getType());
285 }
286
287 /***
288 * @return Returns the instance of the scenario text
289 */
290 public static ScenarioText getScenarioText()
291 {
292 return ScenarioText.scenarioText;
293 }
294
295
296
297
298 /***
299 * writes a serializable method to stream
300 *
301 * @param out the outputstream
302 * @throws IOException on IOException
303 */
304 private synchronized void writeObject(final ObjectOutputStream out)
305 throws IOException
306 {
307 out.defaultWriteObject();
308 }
309
310 /***
311 * reads a serializable method from stream
312 *
313 * @param in the inputstream
314 */
315 private synchronized void readObject(final java.io.ObjectInputStream in)
316 {
317 try
318 {
319 in.defaultReadObject();
320 ScenarioText.scenarioText = this;
321 } catch (Exception exception)
322 {
323 Logger.severe(this, "readObject", exception);
324 }
325 }
326
327 /***
328 *
329 * <p>
330 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628
331 * BX Delft, the Netherlands. All rights reserved.
332 *
333 * See for project information <a href="http://www.simulation.tudelft.nl/">
334 * www.simulation.tudelft.nl </a>.
335 *
336 * The source code and binary code of this software is proprietary
337 * information of Delft University of Technology.
338 *
339 * @author <a
340 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
341 * van Houten </a>
342 * @version $Revision: 1.2 $ $Date: 2005/08/09 15:43:42 $
343 * @since 1.1.2
344 */
345 private class TimedNewsMessageSender implements Serializable
346 {
347 /*** the serial version uid */
348 private static final long serialVersionUID = 11L;
349
350 /*** the timer */
351 private transient Timer timer = null;
352
353 /*** the owner */
354 private ScenarioText owner = null;
355
356 /***
357 * constructs a new TimedAnimationRefresher
358 *
359 * @param owner the owner
360 */
361 public TimedNewsMessageSender(final ScenarioText owner)
362
363 {
364 this.timer = new Timer();
365 this.owner = owner;
366 }
367
368 /***
369 * Method scheduleTask schedules a new timer task
370 */
371 protected void scheduleTask()
372 {
373 SendEmptyNewsMessageTask task = new SendEmptyNewsMessageTask(
374 this.owner);
375 this.timer.schedule(task, 60000);
376 }
377
378 /***
379 * writes a serializable method to stream
380 *
381 * @param out the outputstream
382 * @throws IOException on IOException
383 */
384 private synchronized void writeObject(final ObjectOutputStream out)
385 throws IOException
386 {
387 out.writeObject(this.owner);
388 }
389
390 /***
391 * reads a serializable method from stream
392 *
393 * @param in the inputstream
394 */
395 private synchronized void readObject(final java.io.ObjectInputStream in)
396 {
397 try
398 {
399 this.owner = (ScenarioText) in.readObject();
400 this.timer = new Timer();
401 } catch (Exception exception)
402 {
403 Logger.severe(this, "readObject", exception);
404 }
405 }
406
407
408 /***
409 * A taks to send an empty message.
410 * <p>
411 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5,
412 * 2628 BX Delft, the Netherlands. All rights reserved.
413 *
414 * See for project information <a
415 * href="http://www.simulation.tudelft.nl/"> www.simulation.tudelft.nl
416 * </a>.
417 *
418 * The source code and binary code of this software is proprietary
419 * information of Delft University of Technology.
420 *
421 * @author <a
422 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
423 * van Houten </a>
424 * @version $Revision: 1.2 $ $Date: 2005/08/09 15:43:42 $
425 * @since 1.1.2
426 */
427 private class SendEmptyNewsMessageTask extends TimerTask
428 {
429 /*** the owner */
430 private ScenarioText owner = null;
431
432 /***
433 * constructs a new SendEmptyNewsMessageTask
434 *
435 * @param owner the owner
436 */
437 public SendEmptyNewsMessageTask(final ScenarioText owner)
438 {
439 super();
440 this.owner = owner;
441 }
442
443 /***
444 * @see java.lang.Runnable#run()
445 */
446 public void run()
447 {
448 try
449 {
450 this.owner.fireEvent(new Event(
451 ScenarioText.SMALL_NEWS_MESSAGE_EVENT, this, ""));
452 } catch (Exception exception)
453 {
454 Logger.severe(this, "SendEmptyNewsMessageTask", exception);
455 }
456 }
457 }
458 }
459 }