1 /***
2 *
3 */
4 package org.telscenter.pas.otrunk;
5
6 import java.awt.BorderLayout;
7 import java.awt.Color;
8 import java.awt.Component;
9 import java.awt.Dimension;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.ComponentEvent;
13 import java.awt.event.ComponentListener;
14 import java.beans.beancontext.BeanContextServices;
15 import java.io.BufferedReader;
16 import java.io.ByteArrayInputStream;
17 import java.io.ByteArrayOutputStream;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileReader;
21 import java.io.InputStream;
22 import java.io.StringReader;
23 import java.net.URL;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Timer;
29 import java.util.TimerTask;
30 import java.util.TooManyListenersException;
31 import java.util.logging.Level;
32 import java.util.logging.Logger;
33
34 import javax.swing.BorderFactory;
35 import javax.swing.JButton;
36 import javax.swing.JLabel;
37 import javax.swing.JOptionPane;
38 import javax.swing.JPanel;
39
40 import net.sf.sail.common.beansupport.IIconProvider;
41 import net.sf.sail.core.beans.event.SessionEvent;
42 import net.sf.sail.core.beans.event.SessionEventListener;
43 import net.sf.sail.core.beans.service.AgentService;
44 import net.sf.sail.core.beans.service.AnnotationService;
45 import net.sf.sail.core.beans.service.SessionService;
46 import net.sf.sail.core.entity.IAgent;
47 import net.sf.sail.core.entity.ISock;
48 import net.sf.sail.core.entity.MismatchedAgentSetSizeException;
49 import net.sf.sail.core.entity.Rim;
50 import net.sf.sail.core.entity.Role;
51 import net.sf.sail.core.entity.UnsupportedRimShapeException;
52
53 import org.apache.commons.io.IOUtils;
54 import org.concord.data.state.OTDataStore;
55 import org.concord.datagraph.state.OTDataAxis;
56 import org.concord.datagraph.state.OTDataCollector;
57 import org.concord.datagraph.state.OTDataGraphable;
58 import org.concord.framework.otrunk.OTControllerService;
59 import org.concord.framework.otrunk.OTObject;
60 import org.concord.framework.otrunk.view.OTFrameManager;
61 import org.concord.framework.otrunk.view.OTViewContext;
62 import org.concord.framework.otrunk.view.OTViewFactory;
63 import org.concord.otrunk.OTMLToXHTMLConverter;
64 import org.concord.otrunk.datamodel.OTDatabase;
65 import org.concord.otrunk.view.OTViewContainerPanel;
66 import org.concord.otrunk.view.OTViewerHelper;
67 import org.concord.otrunk.xml.XMLDatabase;
68 import org.telscenter.pas.beans.IWorkReporter;
69 import org.telscenter.pas.beans.PasStep;
70 import org.telscenter.pas.otrunk.skeleton.OTGenericOTrunkStep;
71 import org.telscenter.pas.service.NavigateAction;
72 import org.xhtmlrenderer.simple.XHTMLPanel;
73
74 import com.lowagie.text.pdf.PdfPCell;
75
76 /***
77 * @author scott
78 *
79 */
80 public class OTrunkStep extends PasStep
81 implements IIconProvider, SessionEventListener, IWorkReporter
82 {
83 /***
84 * Logger for this class
85 */
86 private static final Logger logger = Logger.getLogger(OTrunkStep.class
87 .getName());
88
89 /***
90 * This is not intended to be serialized by the java object serializer
91 * It is intended to be serialized by XMLEncoder
92 */
93 private static final long serialVersionUID = 1L;
94
95 private OTViewerHelper viewerHelper;
96
97 private URL authoredDataURL;
98 private Rim workRim;
99
100 private String typeName = "Otrunk Step";
101
102 private BeanIcons beanIcons;
103
104 private ISock workSock;
105
106 private OTObject target;
107
108 private OTControllerService controllerService;
109
110 private static HashMap<String, Class> supportedTypes = new HashMap<String, Class>();
111
112 private Class stepType;
113
114 private boolean needsSetup = false;
115
116 private Timer timer;
117
118 private boolean needsSockEntryInit = true;
119
120 public OTrunkStep()
121 {
122 viewerHelper = new OTViewerHelper();
123 supportedTypes = new HashMap<String, Class>();
124 }
125
126 public URL getAuthoredDataURL()
127 {
128 return authoredDataURL;
129 }
130
131 public void setAuthoredDataURL(URL url)
132 {
133 authoredDataURL = url;
134 }
135
136 public BeanIcons getBeanIcons()
137 {
138 return beanIcons;
139 }
140
141 public void setBeanIcons(BeanIcons icons)
142 {
143 this.beanIcons = icons;
144 }
145
146 public Component getComponent() {
147 return getComponent(false);
148 }
149
150
151
152
153 public Component getComponent(boolean authoring) {
154 JPanel panel=new JPanel(new BorderLayout(5, 5));
155 OTViewContainerPanel otPanel = null;
156 if (needsSetup) {
157 try {
158 setupStep();
159 } catch (Exception e) {
160 logger.log(Level.SEVERE, "Failed to create OTObject for step", e);
161 }
162 }
163 try {
164 OTObject root = target;
165
166 if(root == null){
167 OTDatabase otDB = viewerHelper.loadOTDatabase(getAuthoredDataURL());
168 viewerHelper.loadOTrunk(otDB, panel);
169
170
171
172
173 Object lastEntry = null;
174 if(workSock != null && workSock.size() > 0){
175 lastEntry = workSock.peek();
176 }
177 if(lastEntry != null){
178 OTDatabase userDB = null;
179 if(lastEntry instanceof String) {
180 StringReader reader = new StringReader((String)lastEntry);
181
182
183
184 userDB = viewerHelper.loadOTDatabase(reader, null);
185
186 } else if(lastEntry instanceof byte[]){
187 ByteArrayInputStream inStream = new ByteArrayInputStream((byte[])lastEntry);
188
189 userDB = viewerHelper.loadOTDatabase(inStream, null);
190 }
191
192 if(userDB != null){
193 viewerHelper.loadUserData(userDB, null);
194 if(userDB instanceof XMLDatabase ){
195 ((XMLDatabase)userDB).setDirty(false);
196 }
197 } else {
198 viewerHelper.newAnonUserData();
199 }
200 } else {
201 viewerHelper.newAnonUserData();
202 }
203
204
205 root = viewerHelper.getRootObject();
206 otPanel = viewerHelper.createViewContainerPanel();
207 } else {
208 OTViewContext viewContext =
209 (OTViewContext) controllerService.getService(OTViewContext.class);
210
211 OTFrameManager frameManager =
212 (OTFrameManager) viewContext.getViewService(OTFrameManager.class);
213 otPanel = new OTViewContainerPanel(frameManager);
214 otPanel.setTopLevelContainer(true);
215 OTViewFactory viewFactory = viewContext.createChildViewFactory();
216 otPanel.setOTViewFactory(viewFactory);
217 }
218
219 panel.setLayout(new BorderLayout());
220
221 panel.add(otPanel, BorderLayout.CENTER);
222
223 if(authoring == true) {
224 otPanel.setViewMode("authoring");
225 }
226
227 otPanel.setCurrentObject(root);
228
229 JButton save = new JButton("Save");
230 save.addActionListener(new ActionListener(){
231
232 public void actionPerformed(ActionEvent e) {
233 saveDataInternal();
234 JOptionPane.showMessageDialog(null, "Your data has been saved", "Saved", JOptionPane.INFORMATION_MESSAGE);
235 }
236 });
237
238 timer = new Timer();
239 long delay = 60*1000;
240 timer.scheduleAtFixedRate(new TimerTask() {
241 @Override
242 public void run() {
243
244 saveDataInternal();
245 }
246 }, delay, delay);
247
248
249 JPanel savePanel = new JPanel();
250 savePanel.add(save);
251 panel.add(savePanel, BorderLayout.SOUTH);
252 } catch (Exception e) {
253
254 e.printStackTrace();
255 }
256
257
258 return panel;
259 }
260
261 private void saveDataInternal() {
262 saveDataInternal(true);
263 }
264
265 private void saveDataInternal(boolean replace)
266 {
267 if (needsSockEntryInit) {
268
269 replace = false;
270 }
271
272 OTDatabase userDB = viewerHelper.getUserOtDB();
273
274
275
276 if(userDB instanceof XMLDatabase &&
277 !((XMLDatabase)userDB).isDirty()){
278 return;
279 }
280
281 try {
282 if(workSock != null && userDB != null){
283 byte [] bytes = new byte [1];
284
285
286
287
288
289 if(getWorkRim().getShape() == bytes.getClass()){
290 ByteArrayOutputStream out = new ByteArrayOutputStream();
291 viewerHelper.saveOTDatabase(userDB, out);
292 bytes = out.toByteArray();
293 workSock.add(bytes, replace);
294 if(userDB instanceof XMLDatabase){
295 ((XMLDatabase)userDB).setDirty(false);
296 }
297 } else {
298 String userData = viewerHelper.saveOTDatabase(userDB);
299 workSock.add(userData, replace);
300 }
301 needsSockEntryInit = false;
302 } else {
303 System.err.println("No sock in OTrunkStep - cannot save data");
304 }
305
306 } catch (Exception e1) {
307
308 e1.printStackTrace();
309 }
310
311 }
312
313 public Rim getWorkRim() {
314 return workRim;
315 }
316
317 public void setWorkRim(Rim workRim) {
318 this.workRim = workRim;
319 }
320
321
322 protected void consumeService(BeanContextServices bcs, Class<? extends Object> serviceClass) {
323 if (serviceClass == AgentService.class) {
324 try {
325 final AgentService p = (AgentService) bcs.getService(this,
326 this, AgentService.class, this, this);
327 IAgent agent = p.getAgentsInRole(Role.RUN_WORKGROUP).getSingle();
328 if(workRim != null && agent != null){
329 workSock = p.getSock(workRim, agent);
330 }
331 } catch (TooManyListenersException e) {
332 e.printStackTrace();
333 } catch (MismatchedAgentSetSizeException e) {
334 e.printStackTrace();
335 } catch (UnsupportedRimShapeException e) {
336 e.printStackTrace();
337 }
338 }
339 if (serviceClass == SessionService.class) {
340 try {
341 SessionService sessionService = (SessionService) bcs.getService(this, this,
342 SessionService.class, this, this);
343 sessionService.addSessionEventListener(this);
344 } catch (TooManyListenersException e1) {
345
346 logger.severe("BeanContextServices, Class - : exception: " + e1);
347 }
348 }
349
350 }
351
352 public URL getIcon(int iconKind) {
353 BeanIcons icons = getBeanIcons();
354 if(icons == null) {
355 return null;
356 }
357 return icons.getIcon(iconKind);
358 }
359
360 public static HashMap<String, Class> getSupportedTypes() {
361 supportedTypes.put("Quick Draw", org.concord.graph.util.state.OTDrawingTool.class);
362 supportedTypes.put("Data Graph", org.concord.datagraph.state.OTDataCollector.class);
363 supportedTypes.put("Concord Multi Tool", org.concord.otrunk.view.document.OTCompoundDoc.class);
364 return supportedTypes;
365 }
366
367 public void setType(Class type) {
368 this.stepType = type;
369 this.needsSetup = true;
370
371
372 for (Map.Entry<String, Class> entry : supportedTypes.entrySet()) {
373 if( entry.getValue().equals(type )) {
374 this.typeName = entry.getKey();
375 }
376 }
377 }
378
379 public void setupStep() throws Exception {
380
381
382
383 OTGenericOTrunkStep otStep = (OTGenericOTrunkStep) controllerService.getOTObject(this);
384 OTObject obj = otStep.getOTObjectService().createObject(stepType);
385 otStep.setTarget(obj);
386 this.setTarget(obj);
387 if (stepType == OTDataCollector.class) {
388 OTDataAxis yAxis = (OTDataAxis) otStep.getOTObjectService().createObject(OTDataAxis.class);
389 OTDataAxis xAxis = (OTDataAxis) otStep.getOTObjectService().createObject(OTDataAxis.class);
390 yAxis.setMin(0);
391 yAxis.setMax(100);
392 yAxis.setLabel("");
393 yAxis.setUnits("");
394 xAxis.setMin(0);
395 xAxis.setMax(100);
396 xAxis.setLabel("unknown");
397 xAxis.setUnits("");
398 ((OTDataCollector)obj).setXDataAxis(xAxis);
399 ((OTDataCollector)obj).setYDataAxis(yAxis);
400 OTDataGraphable graphable = (OTDataGraphable) otStep.getOTObjectService().createObject(OTDataGraphable.class);
401 graphable.setDataStore((OTDataStore) otStep.getOTObjectService().createObject(OTDataStore.class));
402 ((OTDataCollector)obj).setSource(graphable);
403 }
404 }
405
406 public String getType() {
407 return typeName;
408 }
409
410 public void stepExit() {
411 if (timer != null) {
412 timer.cancel();
413 }
414 saveDataInternal();
415 }
416
417 public void sessionInitiated(SessionEvent e) {
418 }
419
420 public void sessionStarted(SessionEvent e) {
421 }
422
423 public void sessionStopped(SessionEvent e) {
424 stepExit();
425 }
426
427 public List<JLabel> getCurrentAnswers() {
428
429 return null;
430 }
431
432 public List<String> getCurrentPrompts() {
433
434 return null;
435 }
436
437 public List<JPanel> getCurrentStepParts() {
438
439 return null;
440 }
441
442 public Map<String, String> getEntityToPromptMap() {
443
444 return null;
445 }
446
447 public Integer getPossibleScore() {
448
449 return null;
450 }
451
452 public JPanel getReportForLearner() {
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470 OTMLToXHTMLConverter oTMLToXHTMLConverter = null;
471 File outputFile = new File("output.txt");
472
473 System.out.println("Initial outputFile length: " + outputFile.length());
474 OTObject otObject = null;
475 Thread oTMLToXHTMLConverterThread = null;
476 try {
477
478
479
480
481
482
483
484
485
486
487
488 otObject = viewerHelper.getRootObject();
489 oTMLToXHTMLConverter = new OTMLToXHTMLConverter(viewerHelper.getViewFactory(), otObject);
490 oTMLToXHTMLConverter.setXHTMLParams(outputFile, 1000, 1000);
491 oTMLToXHTMLConverterThread = new Thread (oTMLToXHTMLConverter);
492 oTMLToXHTMLConverterThread.start();
493
494 } catch(Exception e) {
495 System.out.println("Exception: " + e);
496 }
497
498 JLabel workLabel = new JLabel("The junk in yr trunk otrunk");
499 JPanel p = new JPanel();
500 p.add(workLabel);
501
502
503 final XHTMLPanel panel = new XHTMLPanel();
504
505
506
507 panel.setOpaque(false);
508 panel.setBorder(BorderFactory.createMatteBorder(5, 4, 3, 2, Color.RED));
509
510
511 panel.setPreferredSize(new Dimension());
512 panel.addComponentListener(new ComponentListener() {
513
514 public void componentHidden(ComponentEvent e) {
515
516
517 }
518
519 public void componentMoved(ComponentEvent e) {
520
521
522 }
523
524 public void componentResized(ComponentEvent e) {
525
526
527 }
528
529 public void componentShown(ComponentEvent e) {
530
531
532 }
533 });
534
535
536
537 String xhtmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"><head><title> Transitional DTD XHTML Example </title></head><body bgcolor=\"#FFFFFF\" link=\"#000000\" text=\"red\"><p>This is a transitional XHTML example</p></body></html>";
538
539 InputStream stream = null;
540 try {
541
542 stream = IOUtils.toInputStream(xhtmlString);
543
544
545 StringBuffer xhtml = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\"><html>");
546
547
548
549 BufferedReader reader = new BufferedReader(
550 new FileReader("output.txt"));
551 char[] buf = new char[1024];
552 int numRead=0;
553 while((numRead=reader.read(buf)) != -1){
554 xhtml.append(buf, 0, numRead);
555 }
556 reader.close();
557 xhtml.append("</img></html>");
558
559 int offset = xhtml.indexOf("<img");
560
561
562 stream = IOUtils.toInputStream(xhtml.toString());
563
564 System.out.println("Ending outputFile length: " + outputFile.length());
565
566 FileInputStream fis = new FileInputStream(outputFile);
567
568 FileReader fr = new FileReader(outputFile);
569
570
571 System.out.println(xhtml);
572 panel.setDocument(stream, null);
573
574 } catch (NullPointerException e) {
575 e.printStackTrace();
576 } catch (Exception e) {
577 e.printStackTrace();
578 } finally {
579 IOUtils.closeQuietly(stream);
580 }
581
582
583
584
585
586 return panel;
587 }
588
589 public JPanel getReportForLearner(NavigateAction navigateAction) {
590
591 return null;
592 }
593
594 public PdfPCell getReportForLearnerPDF() {
595
596 return null;
597 }
598
599 public JPanel getReportForLearnerWithAnnotations(
600 NavigateAction navigateAction) {
601
602 return null;
603 }
604
605 public JPanel getReportForLearnerWithAnnotations() {
606
607 return null;
608 }
609
610 public void initStepParts() {
611
612
613 }
614
615 public void setPossibleScore(Integer possibleScore) {
616
617
618 }
619
620 public PdfPCell getReportForLearnerPDF(AnnotationService annotationService) {
621
622 return null;
623 }
624
625 public void setTarget(OTObject target) {
626 this.target = target;
627 }
628
629 public void setControllerService(OTControllerService controllerService) {
630 this.controllerService = controllerService;
631 }
632
633 }