View Javadoc

1   /*
2    * Created on Apr 27, 2005, Copyright UC Regents
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); //$NON-NLS-1$
114 	}
115 	
116 	public String getType()
117 	{
118 		return "Interactive Model";
119 	}
120 
121 	// this gets called before the project UI shows up so users don't
122 	// have to wait for it when they click this step -turadg
123 	public void beforeSessionStart()
124 	{
125 		initialize();
126 	}
127 
128 	protected void initialize()
129 	{
130 		if (initialized)
131 			return;
132 		/*
133 		 * if (codeBasePath == null) throw new InvalidPropertyException(this,
134 		 * "codeBasePath"); //$NON-NLS-1$
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 				// TODO Auto-generated catch block
150 				e.printStackTrace();
151 			}
152 			if (logger.isLoggable(Level.CONFIG))
153 			{
154 				logger.config("activityPath = " + activityPath); //$NON-NLS-1$
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); //$NON-NLS-1$
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); //$NON-NLS-1$
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); //$NON-NLS-1$
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 			// TODO Auto-generated catch block
310 			e.printStackTrace();
311 		} catch (UnsupportedRimShapeException e) {
312 			// TODO Auto-generated catch block
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 					// Special case String because the original data
365 					// will be a byte array.
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 				// TODO Auto-generated catch block
396 				logger.severe("BeanContextServices, Class -  : exception: " + e1); //$NON-NLS-1$
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 		// If frame == null then the model was never displayed
415 		// so there should be nothing to save
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 		// TODO Auto-generated method stub
426 		
427 	}
428 
429 	public void sessionStarted(SessionEvent arg0) {
430 		// TODO Auto-generated method stub
431 		
432 	}
433 
434 	public void sessionStopped(SessionEvent arg0) {
435 		stepExit();
436 	}
437 }