1 /***
2 *
3 */
4 package org.telscenter.pas.steps;
5
6 import java.awt.Component;
7 import java.beans.beancontext.BeanContextServices;
8 import java.io.File;
9 import java.io.FileWriter;
10 import java.io.UnsupportedEncodingException;
11 import java.lang.reflect.Method;
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.net.URLEncoder;
15 import java.util.HashMap;
16 import java.util.Locale;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.TooManyListenersException;
20 import java.util.Map.Entry;
21 import java.util.logging.Level;
22 import java.util.logging.Logger;
23
24 import javax.swing.JOptionPane;
25
26 import net.sf.sail.core.beans.service.SessionService;
27
28 import org.telscenter.pas.ui.browser.BrowserEvent;
29 import org.telscenter.pas.ui.browser.IBrowser;
30 import org.telscenter.pas.ui.browser.IBrowserListener;
31
32 /***
33 * Pas step type that adapts a legacy WISE-2 module, conformant to the <a
34 * href="http://www.telscenter.org/confluence/display/WPS/Module+API">WISE v2
35 * Module API</a> specification.
36 *
37 * This is the API used by the <i>WISE Original Browser-based Learning
38 * Environment</i> aka the <b>WOBBLE</b>.
39 *
40 * @author turadg
41 *
42 */
43
44
45
46 public class WobbleModule extends BrowseWeb {
47
48 private static final long serialVersionUID = 1L;
49
50 /***
51 * Logger for this class
52 */
53 private static final Logger logger = Logger.getLogger(WobbleModule.class
54 .getName());
55
56 /***
57 * We have to use a static variable for this because sail doesn't provide a
58 * session service for our data as far as I know.
59 */
60 protected static boolean isWiseSessionSetup = false;
61
62 SessionService sessionService;
63
64 String moduleOtherData = "";
65
66 int moduleOtherNumber = 0;
67
68 String wiseStepUrl;
69
70 /***
71 *
72 */
73 public WobbleModule() {
74 setMockSettings();
75 }
76
77
78
79 public void setMockSettings() {
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 try {
96
97
98
99
100
101
102
103 setTitle("Discussion 1");
104 setModuleOtherNumber(1006);
105 String studentUrlStr = "http://wise.berkeley.edu/modules/forum/studentDiscussion.php";
106
107 URL studentUrl = new URL(studentUrlStr);
108 setUrl(studentUrl);
109 } catch (MalformedURLException e) {
110
111 e.printStackTrace();
112 }
113 }
114
115
116
117
118
119
120 public Component getComponent() {
121 Component component = super.getComponent();
122 if (!isWiseSessionSetup) {
123
124
125
126 String sessionId = sessionService.getProperty("wise.sessionId",
127 null);
128 String wiseServer = sessionService.getProperty("wise.wiseServer",
129 null);
130 if (sessionId != null && wiseServer != null) {
131 String urlStr = "http://" + wiseServer
132 + "/SAIL/setSessionCookie.php?WISESESSIONID="
133 + sessionId;
134 logger.info("setupcookie url: " + urlStr);
135
136 try {
137 browser.addBrowserListener(new IBrowserListener() {
138 public void downloadCompleted(BrowserEvent event) {
139
140
141
142 browser.removeBrowserListener(this);
143
144
145
146
147
148
149 (new Thread() {
150 public void run() {
151 try {
152 Thread.sleep(1000);
153 } catch (InterruptedException e) {
154
155 e.printStackTrace();
156 }
157 isWiseSessionSetup = true;
158 setBrowserUrl();
159 }
160 }).start();
161 }
162
163 public void documentCompleted(BrowserEvent event) {
164 }
165
166 public void downloadProgress(BrowserEvent event) {
167 }
168 });
169
170
171
172
173
174
175 (new Thread() {
176 public void run() {
177 try {
178 Thread.sleep(1500);
179 if (!isWiseSessionSetup) {
180 isWiseSessionSetup = true;
181 setBrowserUrl();
182 }
183 } catch (InterruptedException e) {
184 e.printStackTrace();
185 }
186 }
187 }).start();
188
189 browser.setUrl(new URL(urlStr));
190
191
192
193 return component;
194 } catch (MalformedURLException e) {
195 logger.log(Level.INFO, "can't setup cookie in wise", e);
196 }
197 } else {
198 logger.info("no wise sessionId, user will have to login in");
199 }
200 }
201
202 setBrowserUrl();
203 return component;
204 }
205
206 protected void setBrowserUrl() {
207
208 Map<String, String> studentModeParameters = getStudentModeParameters(
209 moduleOtherData, moduleOtherNumber);
210 String postData = encodeParameterMap(studentModeParameters);
211
212 String stepUrlStr = getWiseStepUrl();
213
214
215
216
217 if (stepUrlStr == null) {
218 URL origUrl = getUrl();
219 String path = origUrl.getPath();
220 String query = origUrl.getQuery();
221 stepUrlStr = "";
222 if (path != null) {
223 stepUrlStr += path;
224 }
225 if (query != null) {
226 stepUrlStr += query;
227 }
228 }
229
230 String wiseServer = sessionService.getProperty("wise.wiseServer",
231 "wise.berkeley.edu");
232 URL browserUrl;
233 try {
234 URL wiseUrl = new URL("http://" + wiseServer);
235 browserUrl = new URL(wiseUrl, stepUrlStr);
236
237
238 String browserType = browser.getBrowserType();
239 logger.info("browserType: " + browserType);
240 if (browserType == IBrowser.SAFARI) {
241 browserUrl = new URL(browserUrl.toExternalForm() + "?"
242 + postData);
243 logger.info("legacy wise step url: " + browserUrl);
244 try {
245 openExternalBrowser(browserUrl);
246
247
248 File tmpFile = File.createTempFile("loading", ".html");
249 tmpFile.deleteOnExit();
250 FileWriter writer = new FileWriter(tmpFile);
251 writer
252 .append("A browser window should be opening with this step.");
253 writer.close();
254 browser.setUrl(tmpFile.toURL());
255 } catch (Exception exp) {
256 logger.log(Level.WARNING, "Can't open external browser.",
257 exp);
258 JOptionPane
259 .showMessageDialog(
260 null,
261 "Mac OSX currently requires and external "
262 + "browser to display legacy WISE steps. An external brower could not "
263 + "be successfully opened. Please check the logs for more info. The "
264 + "embedded jdic will be used but it is not stable.",
265 "No External Browser",
266 JOptionPane.WARNING_MESSAGE);
267
268
269 browser.setUrl(url, postData);
270 }
271
272 } else {
273 logger.info("legacy wise step url (not including post data): "
274 + browserUrl);
275 browser.setUrl(browserUrl, postData);
276 }
277 } catch (MalformedURLException e) {
278
279 e.printStackTrace();
280 }
281 }
282
283 public void openExternalBrowser(URL url) throws Exception {
284 Class<?> serviceManager = Class.forName("javax.jnlp.ServiceManager");
285 Method lookupMethod = serviceManager.getMethod("lookup",
286 new Class[] { String.class });
287 Object basicService = lookupMethod.invoke(null,
288 new Object[] { "javax.jnlp.BasicService" });
289 Method showDocument = basicService.getClass().getMethod("showDocument",
290 new Class[] { URL.class });
291 showDocument.invoke(basicService, new Object[] { url });
292 return;
293 }
294
295 /***
296 * @param studentModeParameters
297 * @return
298 */
299 private String encodeParameterMap(Map<String, String> studentModeParameters) {
300 StringBuffer sb = new StringBuffer();
301 Set<Entry<String, String>> entrySet = studentModeParameters.entrySet();
302 for (Entry<String, String> pair : entrySet) {
303 String name = pair.getKey();
304 String value = pair.getValue();
305 try {
306 sb.append(URLEncoder.encode(name, "UTF-8"));
307 sb.append("=");
308 sb.append(URLEncoder.encode(value, "UTF-8"));
309 sb.append("&");
310 } catch (UnsupportedEncodingException e) {
311
312 e.printStackTrace();
313 }
314 }
315 return sb.toString();
316 }
317
318 protected Map<String, String> getStudentModeParameters(String otherData,
319 int otherNumber) {
320
321
322 Map<String, String> p = new HashMap<String, String>();
323
324
325 p.put("inWISE", "1");
326
327
328
329 p.put("mode", "1");
330
331
332 addUrlParamFromSession(p, "projectName", "a project for testing");
333
334
335
336 addUrlParamFromSession(p, "projectID", "130670");
337
338
339
340 addUrlParamFromSession(p, "groupID", "130670");
341
342
343
344
345
346
347 addUrlParamFromSession(p, "wiseServer", "wise.berkeley.edu");
348
349
350
351
352 addUrlParamFromSession(p, "language", Locale.getDefault().getLanguage());
353
354
355
356
357 addUrlParamFromSession(p, "groupUsernames", "turadg");
358
359
360
361 addUrlParamFromSession(p, "groupRealnames", "Turadg Aleahmad");
362
363
364
365
366 addUrlParamFromSession(p, "isCurrent", "1");
367
368
369
370 addUrlParamFromSession(p, "teacher", "FIXME teacher");
371
372
373 addUrlParamFromSession(p, "period", "1");
374
375
376 p.put("otherData", otherData);
377
378
379 p.put("otherNumber", otherNumber + "");
380
381
382
383 addUrlParamFromSession(p, "hingeSelection", "FIXME hingeSelection");
384
385
386
387
388 addUrlParamFromSession(p, "iteration", "FIXME iteration");
389
390
391 p.put("style", "1");
392
393 return p;
394 }
395
396 /***
397 * This method uses the sessionService to lookup the key and if it isn't
398 * there then it uses the default value.
399 *
400 * @param p
401 * @param key
402 * @param defaultValue
403 */
404 protected void addUrlParamFromSession(Map<String, String> p, String key,
405 String defaultValue) {
406 p.put(key, sessionService.getProperty("wise." + key, defaultValue));
407 }
408
409 /***
410 * @return the apiOtherData
411 */
412 public String getModuleOtherData() {
413 return moduleOtherData;
414 }
415
416 /***
417 * @param apiOtherData
418 * the apiOtherData to set
419 */
420 public void setModuleOtherData(String apiOtherData) {
421 this.moduleOtherData = apiOtherData;
422 }
423
424 /***
425 * @return the apiOtherNumber
426 */
427 public int getModuleOtherNumber() {
428 return moduleOtherNumber;
429 }
430
431 /***
432 * @param apiOtherNumber
433 * the apiOtherNumber to set
434 */
435 public void setModuleOtherNumber(int apiOtherNumber) {
436 this.moduleOtherNumber = apiOtherNumber;
437 }
438
439 protected void consumeService(BeanContextServices bcs, Class<?> serviceClass) {
440 super.consumeService(bcs, serviceClass);
441 if (serviceClass == SessionService.class) {
442 try {
443 sessionService = (SessionService) bcs.getService(this, this,
444 SessionService.class, this, this);
445 } catch (TooManyListenersException e1) {
446 logger
447 .severe("BeanContextServices, Class - : exception: " + e1);
448 }
449 }
450 }
451
452 public String getWiseStepUrl() {
453 return wiseStepUrl;
454 }
455
456 public void setWiseStepUrl(String wiseStepUrl) {
457 this.wiseStepUrl = wiseStepUrl;
458 }
459 }