View Javadoc

1   /*
2    * ScenarioText.java Created @ Aug 13, 2004
3    * 
4    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands. All rights reserved.
6    * 
7    * See for project information <a href="http://www.simulation.tudelft.nl/">
8    * www.simulation.tudelft.nl </a>.
9    * 
10   * The source code and binary code of this software is proprietary information
11   * of Delft University of Technology.
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 		// we are sending a message to another player
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 	// private methods
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 }