1
2
3
4 package org.telscenter.pas.pedagogica;
5
6 import java.awt.BorderLayout;
7 import java.awt.Component;
8 import java.awt.Dimension;
9 import java.awt.FlowLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.beans.beancontext.BeanContextServices;
13 import java.io.File;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.net.MalformedURLException;
17 import java.net.URL;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.Map;
21 import java.util.TooManyListenersException;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
24
25 import javax.swing.JButton;
26 import javax.swing.JLabel;
27 import javax.swing.JPanel;
28 import javax.swing.JScrollPane;
29
30 import net.sf.sail.core.beans.event.SessionEvent;
31 import net.sf.sail.core.beans.event.SessionEventListener;
32 import net.sf.sail.core.beans.service.AgentService;
33 import net.sf.sail.core.beans.service.SessionService;
34 import net.sf.sail.core.entity.IAgent;
35 import net.sf.sail.core.entity.ISock;
36 import net.sf.sail.core.entity.MismatchedAgentSetSizeException;
37 import net.sf.sail.core.entity.Rim;
38 import net.sf.sail.core.entity.Role;
39 import net.sf.sail.core.entity.UnsupportedRimShapeException;
40 import net.sf.sail.core.util.BinaryUtils;
41
42 import org.concord.pedagogica.engine.Activity;
43 import org.concord.pedagogica.ui.ActivityFrame;
44 import org.concord.pedagogica.ui.RunActivity;
45 import org.telscenter.pas.steps.AbstractUrlStep;
46 import org.telscenter.pas.steps.IntroductionHtmlAware;
47 import org.xhtmlrenderer.extend.NamespaceHandler;
48 import org.xhtmlrenderer.simple.FSScrollPane;
49 import org.xhtmlrenderer.simple.XHTMLPanel;
50 import org.xhtmlrenderer.simple.extend.XhtmlNamespaceHandler;
51
52 /***
53 * Implementation of the PAS step type, <i>Pedagogica</i>.
54 *
55 * @author turadg
56 */
57 public class PedagogicaStep extends AbstractUrlStep implements
58 IntroductionHtmlAware, SessionEventListener
59 {
60 /***
61 * Logger for this class
62 */
63 private static final Logger logger = Logger.getLogger(PedagogicaStep.class
64 .getName());
65
66 private AgentService agentService;
67 private SessionService sessionService;
68
69 private Map rimMap;
70
71 private Map sockMap = new HashMap();
72
73 private RunActivity runActivity;
74
75 private String activityPath;
76
77 private Activity activity;
78 private ActivityFrame frame;
79
80 private Boolean authoring;
81
82 private static final long serialVersionUID = 1L;
83
84 private Content content;
85
86 private String codeBasePath;
87
88 private boolean initialized;
89 private int enterCount = 0;
90
91 private String introductionHtml;
92
93 public PedagogicaStep()
94 {
95 }
96
97 public Component getComponent()
98 {
99 if (!initialized)
100 beforeSessionStart();
101 return content;
102 }
103
104 public String getCodeBase()
105 {
106 return codeBasePath;
107 }
108
109 public void setCodeBase(String path)
110 {
111 Object old = this.codeBasePath;
112 this.codeBasePath = path;
113 firePropertyChange("codeBase", old, codeBasePath);
114 }
115
116 public String getType()
117 {
118 return "Interactive Model";
119 }
120
121
122
123 public void beforeSessionStart()
124 {
125 initialize();
126 }
127
128 protected void initialize()
129 {
130 if (initialized)
131 return;
132
133
134
135
136 URL stepUrl = getUrl();
137 content = new Content();
138 String htmlText = getIntroductionHtml();
139 content.setHtmlText(htmlText);
140 if (stepUrl != null)
141 {
142 try
143 {
144 File tempFile = BinaryUtils.tempFileForUrl(getUrl());
145 activityPath = tempFile.toString();
146 }
147 catch (IOException e)
148 {
149
150 e.printStackTrace();
151 }
152 if (logger.isLoggable(Level.CONFIG))
153 {
154 logger.config("activityPath = " + activityPath);
155 }
156
157 runActivity = new RunActivity();
158
159 if (activityPath != null)
160 {
161 runActivity.setActivityPath(activityPath);
162 }
163 if (authoring != null)
164 {
165 runActivity.setAuthoringMode(authoring.booleanValue());
166 }
167 runActivity.setErrorSilent(true);
168 initialized = true;
169 }
170 else
171 {
172
173 }
174 }
175
176 public class Content extends JPanel implements ActionListener
177 {
178 protected JLabel noContentLabel = new JLabel("No Pedagogica Content Specified");
179 protected JPanel activityPanel = new JPanel();
180 protected XHTMLPanel htmlDisplay = new XHTMLPanel();
181 protected JScrollPane scroll = new FSScrollPane(htmlDisplay);
182 protected JPanel buttonPanel = new JPanel(new FlowLayout());
183 protected JButton showButton = new JButton("Launch");
184 protected ActionListener showListener = new ActionListener()
185 {
186 public void actionPerformed(ActionEvent event)
187 {
188 if (frame == null)
189 {
190 frame = (ActivityFrame) runActivity.getFrame();
191 if (frame != null)
192 frame.setExitOnClose(false);
193 }
194 if (frame != null)
195 {
196 frame.setVisibleEnabled(true);
197 frame.setVisible(true);
198 }
199 }
200 };
201 private NamespaceHandler nameSpaceHandler = new XhtmlNamespaceHandler();
202
203 public Content()
204 {
205 setPreferredSize(new Dimension(800, 600));
206 setLayout(new BorderLayout());
207 add(scroll, "Center");
208 add(buttonPanel, "South");
209 buttonPanel.add(showButton);
210 showButton.addActionListener(showListener);
211 }
212
213 public void setHtmlText(String text)
214 {
215 htmlDisplay.setDocumentFromString(text, "http://wise.berkeley.edu", nameSpaceHandler );
216 }
217
218 public JPanel getActivityPanel()
219 {
220 return activityPanel;
221 }
222
223 public void addNotify()
224 {
225 super.addNotify();
226 }
227
228 public void actionPerformed(ActionEvent event)
229 {
230 }
231 }
232
233 public String getIntroductionHtml()
234 {
235 return introductionHtml;
236 }
237
238 public void setIntroductionHtml(String introductionHtml)
239 {
240 Object old = this.introductionHtml;
241 this.introductionHtml = introductionHtml;
242 firePropertyChange("introductionHtml", old, this.introductionHtml);
243 }
244
245 protected InputStream getURLStream(URL url)
246 {
247 try
248 {
249 return url.openStream();
250 }
251 catch (IOException e)
252 {
253 logger.severe("URL - : exception: " + e);
254 }
255 return null;
256 }
257
258 protected InputStream getURLStream(String urlString)
259 {
260 try
261 {
262 URL url = new URL(urlString);
263 return getURLStream(url);
264 }
265 catch (MalformedURLException e)
266 {
267 logger.severe("String - : exception: " + e);
268 }
269 return null;
270 }
271
272 public Map getRimMap()
273 {
274 if (rimMap == null)
275 rimMap = new HashMap();
276 return rimMap;
277 }
278
279 public void setRimMap(Map map)
280 {
281 rimMap = map;
282 }
283
284 public Rim getRim(String name)
285 {
286 return (Rim) getRimMap().get(name);
287 }
288
289 public void setRim(String name, Rim rim)
290 {
291 getRimMap().put(name, rim);
292 }
293
294 protected void createSocks()
295 {
296
297 Iterator entries = getRimMap().entrySet().iterator();
298 try {
299 IAgent agent = agentService.getAgentsInRole(Role.RUN_WORKGROUP).getSingle();
300 while (entries.hasNext())
301 {
302 Map.Entry entry = (Map.Entry) entries.next();
303 String key = (String) entry.getKey();
304 Rim rim = (Rim) rimMap.get(key);
305 ISock sock = agentService.getSock(rim, agent);
306 sockMap.put(key, sock);
307 }
308 } catch (MismatchedAgentSetSizeException e) {
309
310 e.printStackTrace();
311 } catch (UnsupportedRimShapeException e) {
312
313 e.printStackTrace();
314 }
315 }
316
317 public void restoreSockData()
318 {
319 Iterator rimNames = getRimMap().keySet().iterator();
320 createSocks();
321 while (rimNames.hasNext())
322 {
323 String rimName = (String) rimNames.next();
324 ISock sock = (ISock) sockMap.get(rimName);
325 if (sock == null)
326 {
327 logger.warning("No sock found for rim: " + rimName);
328 }
329 else
330 {
331 if (! sock.isEmpty())
332 {
333 byte [] data = null;
334 Object sockData = sock.peek();
335 if (sockData.getClass() == String.class)
336 data = ((String) sockData).getBytes();
337 else
338 data = (byte []) sockData;
339 runActivity.setSavedState(rimName, data);
340 }
341 }
342 }
343 }
344
345 public void saveSockData()
346 {
347 Iterator rimNames = getRimMap().keySet().iterator();
348 createSocks();
349 while (rimNames.hasNext())
350 {
351 String rimName = (String) rimNames.next();
352 Rim rim = (Rim) rimMap.get(rimName);
353 ISock sock = (ISock) sockMap.get(rimName);
354 if (sock == null)
355 {
356 logger.warning("No sock found for rim: " + rimName);
357 }
358 else
359 {
360 byte[] data = runActivity.getSavedState(rimName);
361 if (data != null)
362 {
363 Object sockData = data;
364
365
366 if (rim.getShape() == String.class)
367 sockData = new String(data);
368 sock.add(sockData);
369 }
370 }
371 }
372 }
373
374 protected void consumeService(BeanContextServices bcs, Class serviceClass)
375 {
376 if (serviceClass == AgentService.class)
377 {
378 try
379 {
380 final AgentService p = (AgentService) bcs.getService(this,
381 this, AgentService.class, this, this);
382 agentService = p;
383 }
384 catch (TooManyListenersException e)
385 {
386 e.printStackTrace();
387 }
388 }
389 if (serviceClass == SessionService.class) {
390 try {
391 sessionService = (SessionService) bcs.getService(this, this,
392 SessionService.class, this, this);
393 sessionService.addSessionEventListener(this);
394 } catch (TooManyListenersException e1) {
395
396 logger.severe("BeanContextServices, Class - : exception: " + e1);
397 }
398 }
399 }
400
401 public void stepEnter()
402 {
403 if (initialized && enterCount == 0)
404 {
405 restoreSockData();
406 runActivity.start(false);
407 activity = runActivity.getActivity();
408 }
409 enterCount++;
410 }
411
412 public void stepExit()
413 {
414
415
416 if (frame != null && activity != null)
417 {
418 frame.setVisible(false);
419 activity.save();
420 saveSockData();
421 }
422 }
423
424 public void sessionInitiated(SessionEvent arg0) {
425
426
427 }
428
429 public void sessionStarted(SessionEvent arg0) {
430
431
432 }
433
434 public void sessionStopped(SessionEvent arg0) {
435 stepExit();
436 }
437 }