1 /***
2 *
3 */
4 package org.telscenter.pas.steps;
5
6 import java.awt.BorderLayout;
7 import java.awt.Color;
8 import java.awt.Component;
9 import java.awt.event.MouseEvent;
10 import java.awt.event.MouseListener;
11 import java.beans.beancontext.BeanContextServices;
12 import java.io.IOException;
13 import java.io.StringReader;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.TooManyListenersException;
19 import java.util.logging.Level;
20 import java.util.logging.Logger;
21
22 import javax.swing.BorderFactory;
23 import javax.swing.JComponent;
24 import javax.swing.JLabel;
25 import javax.swing.JPanel;
26 import javax.swing.JScrollPane;
27 import javax.swing.JTextArea;
28 import javax.swing.border.CompoundBorder;
29
30 import net.miginfocom.swing.MigLayout;
31 import net.sf.sail.core.beans.service.AgentService;
32 import net.sf.sail.core.beans.service.AnnotationService;
33 import net.sf.sail.core.beans.service.SessionService;
34 import net.sf.sail.core.entity.AgentSet;
35 import net.sf.sail.core.entity.IAgent;
36 import net.sf.sail.core.entity.ISock;
37 import net.sf.sail.core.entity.MismatchedAgentSetSizeException;
38 import net.sf.sail.core.entity.Rim;
39 import net.sf.sail.core.entity.Role;
40 import net.sf.sail.core.entity.User;
41 import net.sf.sail.jaxb.extension.BlockInteractionType;
42
43 import org.imsglobal.xsd.imsqti_v2p0.AssessmentItemType;
44 import org.imsglobal.xsd.imsqti_v2p0.ChoiceInteractionType;
45 import org.imsglobal.xsd.imsqti_v2p0.PromptType;
46 import org.imsglobal.xsd.imsqti_v2p0.ResponseDeclarationType;
47 import org.imsglobal.xsd.imsqti_v2p0.SimpleChoiceType;
48 import org.telscenter.pas.beans.IWorkReporter;
49 import org.telscenter.pas.beans.PasStep;
50 import org.telscenter.pas.common.ui.CommonUI;
51 import org.telscenter.pas.service.NavigateAction;
52 import org.telscenter.pas.ui.pdf.PDFUtil;
53 import org.telscenter.pas.ui.util.PasColors;
54 import org.telscenter.pas.util.AnnotationUtils;
55
56 import com.lowagie.text.Element;
57 import com.lowagie.text.Font;
58 import com.lowagie.text.Paragraph;
59 import com.lowagie.text.html.simpleparser.HTMLWorker;
60 import com.lowagie.text.html.simpleparser.StyleSheet;
61 import com.lowagie.text.pdf.PdfPCell;
62 import com.lowagie.text.pdf.PdfPTable;
63
64 /***
65 * This step uses qti bindings project
66 *
67 * @author aperritano
68 *
69 */
70 abstract public class JaxbQtiStep extends PasStep implements IWorkReporter, IAssessmentType{
71
72 private static final Logger logger = Logger.getLogger(JaxbQtiStep.class
73 .getName());
74
75 public AssessmentItemType assessmentItem;
76
77 protected transient Map<ResponseDeclarationType, ISock<String>> responseDeclarationToSocks = new HashMap<ResponseDeclarationType, ISock<String>>();
78
79
80 protected transient Map<String, Object> responses = new HashMap<String, Object>();
81
82 protected transient AgentService agentService;
83
84 protected transient SessionService sessionService;
85
86 private List<JPanel> currentStepParts;
87
88 private List<String> currentPrompts;
89
90 private List<JLabel> answer;
91
92 private boolean injectPrompt = false;
93
94 protected transient Map<ResponseDeclarationType, Rim> responseDeclarationsToRims = null;
95
96 protected boolean lockStudentAnswers = true;
97
98 private Integer possibleScore;
99
100 private boolean isTabbed = false;
101
102 private boolean submitted = false;
103
104 public void initStepParts(){
105 this.currentPrompts = new ArrayList<String>();
106 this.currentStepParts = new ArrayList<JPanel>();
107 this.answer = new ArrayList<JLabel>();
108 }
109
110
111
112
113 public boolean canLockAnswers() {
114 return false;
115 }
116
117 /***
118 * This switch enables/disables locking of student answers
119 *
120 * @param lockStudentAnswers the lockStudentAnswers to set
121 */
122 public void setLockStudentAnswers(boolean lockStudentAnswers) {
123 Object old = this.lockStudentAnswers;
124 this.lockStudentAnswers = lockStudentAnswers;
125 pcSupport.firePropertyChange("lockStudentAnswers", old, lockStudentAnswers);
126 }
127
128 /***
129 * @return the lockStudentAnswers
130 */
131 public boolean isLockStudentAnswers() {
132 return lockStudentAnswers;
133 }
134
135 protected void consumeService(BeanContextServices bcs, Class<? extends Object> serviceClass) {
136 if (serviceClass == SessionService.class) {
137 try {
138 sessionService = (SessionService) bcs.getService(this, this,
139 SessionService.class, this, this);
140 } catch (TooManyListenersException e) {
141
142 logger
143 .severe("BeanContextServices, Class - : exception: " + e);
144 }
145 } else if (serviceClass == AgentService.class) {
146 try {
147 agentService = (AgentService) bcs.getService(this, this,
148 AgentService.class, this, this);
149 } catch (TooManyListenersException e) {
150
151 logger
152 .severe("BeanContextServices, Class - : exception: " + e);
153 }
154
155 }
156
157 if (agentService != null && sessionService != null)
158 bindResponsesToSocks();
159 }
160
161 /************************************** SAVING DATA ***********************************************************/
162
163
164
165
166
167
168
169 /***
170 * Binds response id to socks
171 */
172 protected void bindResponsesToSocks() {
173 User user = sessionService.getUsers().iterator().next();
174 AgentSet agentsOfUser = agentService.getAgentsOfUser(user);
175 AgentSet agentsOfUserInWorkgroup = agentsOfUser
176 .select(Role.RUN_WORKGROUP);
177 IAgent agent;
178 try {
179 agent = agentsOfUserInWorkgroup.getSingle();
180 } catch (MismatchedAgentSetSizeException e1) {
181 logger.severe("exception: " + e1);
182 return;
183 }
184
185
186
187 if( assessmentItem == null)
188 return;
189
190
191 if( assessmentItem
192 .getResponseDeclaration() != null ) {
193 List<ResponseDeclarationType> responseDeclarations = assessmentItem
194 .getResponseDeclaration();
195 for (ResponseDeclarationType rd : responseDeclarations) {
196
197
198
199 Rim rim = responseDeclarationsToRims.get(rd);
200 if (rim != null) {
201
202 try {
203 ISock<String> sock = agentService.getSock(rim, agent);
204 responseDeclarationToSocks.put(rd, sock);
205
206 if (!sock.isEmpty()) {
207
208 submitted= true;
209 responses.put(rd.getIdentifier(), sock.peek());
210 }
211 } catch (Exception e) {
212 logger.severe("exception: " + e);
213 }
214 }
215 }
216 }
217
218 }
219
220
221
222 /***
223 * @param rd
224 * @return
225 */
226 public static String lastAnswer(
227 Map<ResponseDeclarationType, ISock<String>> responseDeclarationToSocks,
228 final ResponseDeclarationType rd) {
229 final ISock<String> sock = responseDeclarationToSocks.get(rd);
230
231 if (sock == null || sock.isEmpty())
232 return null;
233
234 return sock.peek();
235 }
236
237
238
239 /***
240 * @param assessmentItem
241 * TODO
242 * @param responses
243 * TODO
244 * @param responseDeclarationToSocks
245 * TODO
246 */
247 public static void saveAssessmentItem(AssessmentItemType assessmentItem,
248 Map<String, Object> responses,
249 Map<ResponseDeclarationType, ISock<String>> responseDeclarationToSocks) {
250 List<ResponseDeclarationType> reponseDeclarations = assessmentItem.getResponseDeclaration();
251
252 for (ResponseDeclarationType rd : reponseDeclarations) {
253 Object responseContent = responses.get(rd.getIdentifier());
254
255
256 if (responseContent == null) {
257 JaxbQtiStudentAssessment.logger
258 .severe("no response for declaration " + rd.getIdentifier() + " - : exception: " + null);
259 continue;
260 }
261
262 ISock<String> sock = responseDeclarationToSocks.get(rd);
263 if (sock == null) {
264 JaxbQtiStudentAssessment.logger
265 .severe("no sock for " + rd + " - : exception: " + null);
266 continue;
267 }
268
269 if (responseContent instanceof SimpleChoiceType) {
270 SimpleChoiceType simpleChoice = (SimpleChoiceType) responseContent;
271
272 saveData(responseDeclarationToSocks, rd, sock, simpleChoice
273 .getIdentifier());
274 } else if (responseContent instanceof String) {
275
276 saveData(responseDeclarationToSocks, rd, sock, (String) responseContent);
277 } else {
278 throw new RuntimeException("unsupported choice type "
279 + responseContent);
280 }
281 }
282 }
283
284 public static void saveData(
285 Map<ResponseDeclarationType, ISock<String>> responseDeclarationToSocks,
286 ResponseDeclarationType rd, ISock<String> sock, String data) {
287
288 if (sock.isEmpty() == false && sock.peek() != null) {
289 if (data.equals(sock.peek())) {
290 logger.warning("DUPICATE ASSESSMENT ENTRY DATA NOT SAVED");
291 return;
292 }
293 }
294
295 sock.add(data);
296 logger.info("ASSESSMENT ENTRY DATA SAVED");
297 responseDeclarationToSocks.put(rd, sock);
298
299 }
300
301 /*****************************************************************************************************************/
302
303 /***
304 * @return itemPanel
305 */
306 private JPanel createEmptyReportPanel() {
307 JPanel itemPanel = new JPanel();
308 itemPanel.setLayout(new BorderLayout(0, 0));
309 itemPanel.setOpaque(false);
310 JLabel noNoteTakenLabel = createNoNoteTakenLabel();
311 itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
312 return itemPanel;
313 }
314
315 /***
316 * @return label
317 */
318 private JLabel createNoNoteTakenLabel() {
319 JLabel noNoteTakenLabel = new JLabel(Messages
320 .getString("Note.NOTE_NOT_TAKEN"));
321 noNoteTakenLabel.setFont(noNoteTakenLabel.getFont().deriveFont(
322 14.0f));
323 noNoteTakenLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0,
324 0));
325 noNoteTakenLabel.setOpaque(false);
326 return noNoteTakenLabel;
327 }
328
329 private String getAnswer(ResponseDeclarationType rd, BlockInteractionType bi){
330 String answer = lastAnswer(
331 this.getResponseDeclarationToSocks(), rd);
332
333 if (answer == null || answer.trim() == "") {
334 answer = Messages.getString("Note.NOT_ANSWERED");
335
336 } else if (bi instanceof ChoiceInteractionType) {
337 ChoiceInteractionType ci = (ChoiceInteractionType) bi;
338
339 List<SimpleChoiceType> simpleChoices = ci.getSimpleChoice();
340 for (SimpleChoiceType sc : simpleChoices) {
341 if (sc.getIdentifier().equals(answer)) {
342
343 answer = sc.getContent().toString();
344 }
345 }
346 }
347 return answer;
348 }
349
350
351 /***
352 * @param htmlPromptPanel
353 * @param answer
354 * @param navigateAction
355 * @return
356 */
357 private JPanel createAnswerAreaWithOUTAnnotations(JComponent htmlPromptPanel, String answer, final NavigateAction navigateAction) {
358
359 JPanel commentPanel = new JPanel(new BorderLayout(0,0));
360
361 JTextArea textArea = new JTextArea(0, 0);
362
363 textArea.setSize(400, textArea.getPreferredSize().height);
364 textArea.setLineWrap(true);
365 textArea.setWrapStyleWord(true);
366 textArea.setEditable(false);
367
368 textArea.setName("answerArea");
369 textArea.setText(answer);
370
371 commentPanel.add(new JScrollPane(textArea),BorderLayout.CENTER);
372 commentPanel.setBackground(Color.BLUE);
373
374 if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
375 textArea.setForeground(Color.RED);
376
377 }else{
378 textArea.setForeground(Color.BLACK);
379 }
380
381 if( navigateAction != null ) {
382 textArea.addMouseListener(new MouseListener(){
383
384 public void mouseClicked(MouseEvent e) {
385 navigateAction.actionPerformed(null);
386
387 }
388
389 public void mouseEntered(MouseEvent e) {
390
391
392 }
393
394 public void mouseExited(MouseEvent e) {
395
396
397 }
398
399 public void mousePressed(MouseEvent e) {
400
401
402 }
403
404 public void mouseReleased(MouseEvent e) {
405
406
407 }});
408 }
409 return commentPanel;
410 }
411
412
413 /***
414 * @param htmlPromptPanel
415 * @param answer
416 * @param navigateAction
417 * @return
418 */
419 private JPanel createAnswerAreaWithAnnotations(JComponent htmlPromptPanel, String answer, final NavigateAction navigateAction) {
420
421
422 JPanel commentPanel = new JPanel(new BorderLayout(0,0));
423
424 JTextArea textArea = new JTextArea(0, 0);
425
426 textArea.setSize(400, textArea.getPreferredSize().height);
427 textArea.setLineWrap(true);
428 textArea.setWrapStyleWord(true);
429 textArea.setEditable(false);
430
431 textArea.setText(answer);
432
433 commentPanel.add(new JScrollPane(textArea),BorderLayout.CENTER);
434 commentPanel.setBackground(Color.BLUE);
435
436 if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
437 textArea.setForeground(Color.RED);
438 }else{
439 textArea.setForeground(Color.BLACK);
440 }
441 textArea.addMouseListener(new MouseListener(){
442
443 public void mouseClicked(MouseEvent e) {
444 navigateAction.actionPerformed(null);
445 }
446
447 public void mouseEntered(MouseEvent e) {
448
449
450 }
451
452 public void mouseExited(MouseEvent e) {
453
454
455 }
456
457 public void mousePressed(MouseEvent e) {
458
459
460 }
461
462 public void mouseReleased(MouseEvent e) {
463
464
465 }});
466 return commentPanel;
467 }
468
469
470
471
472
473
474
475 private JTextArea getAnswerArea(String answer){
476 JTextArea answerArea = new JTextArea(50, 300);
477 answer = wrapInlineText(answer, 100);
478 answer = extractBody(answer);
479 answerArea.setText(answer);
480 answerArea.setOpaque(true);
481 answerArea.setBackground(PasColors.noteReportTextAreaColor);
482 if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
483 answerArea.setForeground(Color.RED);
484 }else if (answer == null || answer.trim() == "") {
485 answer = Messages.getString("Note.NOT_ANSWERED");
486 answerArea.setForeground(Color.RED);
487 }else{
488 answerArea.setForeground(Color.BLACK);
489 }
490
491 answerArea.setBorder(CommonUI.createEtchedBorder());
492 answerArea.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
493 return answerArea;
494
495 }
496
497 private String wrapInlineText(String inlineFeedbackText, int adjustedWidth){
498 String initHtml = "<html><body>";
499 String finalHtml = "</body></html>";
500 String finalStr = "";
501 int lastIndex = 0;
502
503 inlineFeedbackText = inlineFeedbackText.trim();
504
505
506 if(adjustedWidth > 10){
507
508 while(inlineFeedbackText.length() > adjustedWidth){
509 String substri = inlineFeedbackText.substring(0,adjustedWidth);
510 lastIndex = substri.lastIndexOf(" ");
511 finalStr = finalStr + substri.substring(0,lastIndex) + "\n";
512 inlineFeedbackText = inlineFeedbackText.substring((int)lastIndex, inlineFeedbackText.length());
513
514 }
515 }
516
517 return initHtml + finalStr + inlineFeedbackText.substring(0,inlineFeedbackText.length()) + finalHtml;
518 }
519
520 /***
521 *
522 * Extracts the text in between the <body>...</body>
523 */
524 protected String extractBody(String prompt) {
525 int start = prompt.indexOf("<body>");
526 int end = prompt.indexOf("</body>");
527
528 String extractedBody = "";
529
530 if (start != -1 && end != -1) {
531 extractedBody = prompt.substring(start+6, end);
532 return extractedBody;
533 }
534 return prompt;
535 }
536
537
538
539 /********************************************************************************************************************/
540 /********************************** REPORT FOR LEARNER *************************************************************/
541
542
543
544
545
546
547 /***
548 * Assessment needs to navigate back to its step with an part of its component has been clicked on
549 *
550 * @param NavigateAction - the ability to go to a step
551 *
552 */
553 public JPanel getReportForLearner(final org.telscenter.pas.service.NavigateAction navigateAction) {
554
555 if (logger.isLoggable(Level.CONFIG)) {
556 logger.config("start");
557 }
558
559 JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
560
561 rootPanel.setBackground(PasColors.showReportsActivityBackgroundColor);
562 JPanel panel = new JPanel();
563 panel.setBackground(PasColors.showReportsActivityBackgroundColor);
564 MigLayout m1 = new MigLayout("insets 0 4 0 0");
565 panel.setLayout(m1);
566
567 List<ResponseDeclarationType> responseDeclarations = assessmentItem
568 .getResponseDeclaration();
569
570 if (responseDeclarations.isEmpty()) {
571 JPanel itemPanel = createEmptyReportPanel();
572 panel.add(itemPanel);
573 } else {
574 int iterator = 1;
575 String oldPrompt="";
576
577 for (ResponseDeclarationType rd : responseDeclarations) {
578 BlockInteractionType bi = getInteractionByResponseDeclaration(rd);
579 oldPrompt = bi.getPrompt().toString();
580 setBiPrompt(responseDeclarations, iterator, bi);
581 iterator++;
582
583 JComponent htmlPromptPanel = JaxbQtiStepUI.createPromptPanel(bi);
584 bi.getPrompt().getContent().add(oldPrompt);
585
586 JPanel questionAnswerPanel = new JPanel();
587 questionAnswerPanel.setLayout(new BorderLayout(0, 0));
588
589 String answer = getAnswer(rd,bi);
590
591 JPanel answerArea = createAnswerAreaWithOUTAnnotations(htmlPromptPanel, answer, navigateAction);
592
593
594 htmlPromptPanel.addMouseListener(new MouseListener(){
595
596 public void mouseClicked(MouseEvent e) {
597 navigateAction.actionPerformed(null);
598
599 }
600
601 public void mouseEntered(MouseEvent e) {
602
603
604 }
605
606 public void mouseExited(MouseEvent e) {
607
608
609 }
610
611 public void mousePressed(MouseEvent e) {
612
613
614 }
615
616 public void mouseReleased(MouseEvent e) {
617
618
619 }});
620
621
622 questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
623 questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
624
625 questionAnswerPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1));
626 panel.add(questionAnswerPanel, "wrap");
627 CompoundBorder compoundBorder = createCompoundBorder();
628
629
630
631
632 }
633 }
634 rootPanel.add(panel, BorderLayout.CENTER);
635
636 if (logger.isLoggable(Level.CONFIG)) {
637 logger.config("end");
638 }
639 return rootPanel;
640 };
641
642 /***
643 * Not needed any more use the one with navigation action
644 *
645 */
646 public JPanel getReportForLearner() {
647 if (logger.isLoggable(Level.CONFIG)) {
648 logger.config("start");
649 }
650
651 JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
652
653 rootPanel.setBackground(PasColors.showReportsActivityBackgroundColor);
654 JPanel panel = new JPanel();
655 panel.setBackground(PasColors.showReportsActivityBackgroundColor);
656 MigLayout m1 = new MigLayout("insets 0 4 0 0");
657 panel.setLayout(m1);
658
659 List<ResponseDeclarationType> responseDeclarations = assessmentItem
660 .getResponseDeclaration();
661
662 if (responseDeclarations.isEmpty()) {
663 JPanel itemPanel = createEmptyReportPanel();
664 panel.add(itemPanel);
665 } else {
666 int iterator = 1;
667 String oldPrompt="";
668
669 for (ResponseDeclarationType rd : responseDeclarations) {
670 BlockInteractionType bi = getInteractionByResponseDeclaration(rd);
671 oldPrompt = bi.getPrompt().toString();
672 setBiPrompt(responseDeclarations, iterator, bi);
673 iterator++;
674
675 JComponent htmlPromptPanel = JaxbQtiStepUI.createPromptPanel(bi);
676 bi.getPrompt().getContent().add(oldPrompt);
677
678 JPanel questionAnswerPanel = new JPanel();
679 questionAnswerPanel.setLayout(new BorderLayout(0, 0));
680
681 String answer = getAnswer(rd,bi);
682
683 JPanel answerArea = createAnswerAreaWithOUTAnnotations(htmlPromptPanel, answer, null);
684
685
686
687
688 htmlPromptPanel.setName("promptPanel");
689 questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
690 questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
691
692 questionAnswerPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1));
693 panel.add(questionAnswerPanel, "wrap");
694 CompoundBorder compoundBorder = createCompoundBorder();
695
696
697
698
699 }
700 }
701 rootPanel.add(panel, BorderLayout.CENTER);
702
703 if (logger.isLoggable(Level.CONFIG)) {
704 logger.config("end");
705 }
706 return rootPanel;
707 }
708
709
710 public PdfPCell getReportForLearnerPDF(AnnotationService annotationService) {
711 if (logger.isLoggable(Level.CONFIG)) {
712 logger.config("start");
713 }
714
715 int defaultFont = Font.TIMES_ROMAN;
716 PdfPTable table = PDFUtil.createStepTitle(this.getTitle());
717 PdfPTable questionAnswerTable = new PdfPTable(1);
718
719 List<ResponseDeclarationType> reponseDeclarations = assessmentItem
720 .getResponseDeclaration();
721
722 if (reponseDeclarations.isEmpty()) {
723 PdfPCell noNoteTaken = new PdfPCell(new Paragraph(Messages
724 .getString("Note.NOTE_NOT_TAKEN")));
725
726 } else {
727 PdfPCell questionAnswerTableCell = null;
728 Font font = new Font(defaultFont, 14, Font.NORMAL);
729 font.setColor(PasColors.showAllWorkTextColor);
730
731 ResponseDeclarationType lastRd = null;
732 for (ResponseDeclarationType rd : reponseDeclarations) {
733 BlockInteractionType bi = JaxbQtiStep
734 .getInteractionByResponseDeclaration(
735 getAssessmentItem().getItemBody()
736 .getBlockElementGroup(), rd);
737 String prompt = null;
738 String answer = null;
739
740 if (bi == null) {
741 prompt = null;
742 } else {
743 prompt = bi.getPrompt().toString();
744 }
745
746 PdfPCell noteQuestionCell = null;
747 if (prompt == null) {
748 prompt = Messages.getString("Note.ERROR_PROMPT_NOT_FOUND");
749
750 noteQuestionCell = new PdfPCell(new Paragraph(prompt, font));
751 noteQuestionCell.setBorderWidthBottom(0.0f);
752 noteQuestionCell.setGrayFill(0.8f);
753 } else {
754
755 StringReader stringReader = new StringReader(prompt);
756 List<Element> p = null;
757 try {
758 StyleSheet st = new StyleSheet();
759 st.loadTagStyle("body", "face", "Times New Roman");
760
761 st.loadTagStyle("body", "font-size", "6,0");
762
763 p = HTMLWorker.parseToList(stringReader, st);
764
765 } catch (IOException e) {
766 e.printStackTrace();
767 }
768
769 stringReader.close();
770
771 noteQuestionCell = new PdfPCell();
772 for (Element e : p) {
773 noteQuestionCell.addElement(e);
774 }
775
776 noteQuestionCell.setBorderWidthBottom(0.0f);
777 noteQuestionCell.setGrayFill(0.8f);
778 }
779
780
781
782 if (bi == null) {
783 answer = null;
784 } else {
785 answer = lastAnswer(this.getResponseDeclarationToSocks(),
786 rd);
787 }
788
789 if (answer == null) {
790 answer = Messages.getString("Note.NOT_ANSWERED");
791 } else if (bi instanceof ChoiceInteractionType) {
792 ChoiceInteractionType ci = (ChoiceInteractionType) bi;
793
794 List<SimpleChoiceType>simpleChoices = ci.getSimpleChoice();
795 for (SimpleChoiceType choice : simpleChoices) {
796 if (choice.getIdentifier().equals(answer)) {
797 answer = choice.getContent().toString();
798 }
799 }
800 }
801
802 PdfPCell noteAnswerCell = new PdfPCell(new Paragraph(answer,
803 font));
804 noteAnswerCell.setBorderWidthTop(0.0f);
805
806
807
808 questionAnswerTable.addCell(noteQuestionCell);
809 questionAnswerTable.addCell(noteAnswerCell);
810
811
812 questionAnswerTableCell = new PdfPCell(questionAnswerTable);
813 questionAnswerTableCell.setPaddingLeft(9.0f);
814 questionAnswerTableCell.setBorderWidth(0.0f);
815 lastRd = rd;
816 }
817 table.addCell(questionAnswerTableCell);
818
819 if( annotationService != null && annotationService.isAvailable() == true ) {
820 Font commentFontHeading = new Font(defaultFont, 10, Font.BOLD);
821 Font commentFontText = new Font(defaultFont, 10, Font.ITALIC);
822
823
824 PdfPCell headerCommentCell = new PdfPCell(new Paragraph("Comments & Score",
825 commentFontHeading));
826 headerCommentCell.setBorderWidthTop(0.0f);
827 headerCommentCell.setPaddingLeft(9.0f);
828 headerCommentCell.setBorderWidth(0.0f);
829
830 String processTheAnnotations = AnnotationUtils.processTheAnnotations(this, sessionService, agentService, annotationService);
831
832 String comments = null;
833 if( processTheAnnotations != null && processTheAnnotations != AnnotationUtils.TEACHER_HAS_NOT_COMMENTED_YET ) {
834 comments = processTheAnnotations;
835 } else {
836 comments = AnnotationUtils.TEACHER_HAS_NOT_COMMENTED_YET;
837 }
838
839
840 PdfPCell noteCommentCell = new PdfPCell(new Paragraph(comments,
841 commentFontText));
842 noteCommentCell.setBorderWidthTop(0.0f);
843 noteCommentCell.setPaddingLeft(9.0f);
844 noteCommentCell.setBorderWidth(0.0f);
845
846 String processScore = AnnotationUtils.processScore(this, sessionService, agentService, annotationService);
847
848 String score = null;
849 if( processScore != null && processScore != AnnotationUtils.UNSCORED ) {
850 score = processScore + " of " + this.getPossibleScore();
851
852 } else {
853 score = AnnotationUtils.UNSCORED;
854 }
855 PdfPCell noteScoreCell = new PdfPCell(new Paragraph(score,
856 commentFontText));
857 noteScoreCell.setBorderWidthTop(0.0f);
858 noteScoreCell.setPaddingLeft(9.0f);
859 noteScoreCell.setBorderWidth(0.0f);
860
861 table.addCell(headerCommentCell);
862 table.addCell(noteCommentCell);
863 table.addCell(noteScoreCell);
864
865
866
867
868
869
870
871
872
873 }
874
875 }
876 PdfPCell mainCell = new PdfPCell(table);
877 mainCell.setBorder(0);
878
879 if (logger.isLoggable(Level.CONFIG)) {
880 logger.config("end");
881 }
882
883 return mainCell;
884 }
885
886 /***
887 * Assessment needs to navigate back to its step with an part of its component has been clicked on
888 *
889 * @param NavigateAction - the ability to go to a step
890 *
891 */
892 public JPanel getReportForLearnerWithAnnotations(
893 final NavigateAction navigateAction) {
894 if (logger.isLoggable(Level.CONFIG)) {
895 logger.config("start");
896 }
897 JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
898 rootPanel.setBackground(Color.GREEN);
899
900 JPanel panel = new JPanel();
901
902 MigLayout m1 = new MigLayout("wrap 1");
903
904 panel.setLayout(m1);
905
906
907 List<ResponseDeclarationType> responseDeclarations = assessmentItem
908 .getResponseDeclaration();
909
910 if (responseDeclarations.isEmpty()) {
911 JPanel itemPanel = new JPanel();
912 itemPanel.setLayout(new BorderLayout(0, 0));
913
914 JLabel noNoteTakenLabel = createNoNoteTakenLabel();
915 itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
916 System.out.println("RD IS NOT LOADED");
917 panel.add(itemPanel);
918 } else {
919 int iterator = 1;
920 PromptType oldPrompt= null;
921 String prompt = "";
922
923 for (ResponseDeclarationType rd : responseDeclarations) {
924 BlockInteractionType bi = (BlockInteractionType) getInteractionByResponseDeclaration(rd);
925 oldPrompt = bi.getPrompt();
926 int index = oldPrompt.getContent().toString().indexOf("Part");
927 int index2 = oldPrompt.getContent().toString().indexOf("Partner");
928
929
930 iterator++;
931 JComponent htmlPromptPanel = JaxbQtiStepUI.createPromptPanel(bi);
932
933 htmlPromptPanel.addMouseListener(new MouseListener(){
934
935 public void mouseClicked(MouseEvent e) {
936 navigateAction.actionPerformed(null);
937
938 }
939
940 public void mouseEntered(MouseEvent e) {
941
942
943 }
944
945 public void mouseExited(MouseEvent e) {
946
947
948 }
949
950 public void mousePressed(MouseEvent e) {
951
952
953 }
954
955 public void mouseReleased(MouseEvent e) {
956
957
958 }});
959
960 bi.setPrompt(oldPrompt);
961 JPanel questionAnswerPanel = new JPanel();
962 questionAnswerPanel.setLayout(new BorderLayout(0, 0));
963
964 String answer = getAnswer(rd,bi);
965
966 JPanel answerArea = createAnswerAreaWithAnnotations(htmlPromptPanel, answer, navigateAction);
967
968 htmlPromptPanel.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
969
970 questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
971 questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
972
973 setCurrentStepPart(questionAnswerPanel);
974
975
976 panel.add(questionAnswerPanel);
977 CompoundBorder compoundBorder = createCompoundBorder();
978 panel.setBorder(compoundBorder);
979
980
981 }
982 }
983 rootPanel.add(panel, BorderLayout.CENTER);
984
985 if (logger.isLoggable(Level.CONFIG)) {
986 logger.config("end");
987 }
988
989 return rootPanel;
990 }
991
992 /***
993 * Note used any more
994 */
995 public JPanel getReportForLearnerWithAnnotations() {
996 if (logger.isLoggable(Level.CONFIG)) {
997 logger.config("start");
998 }
999 JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
1000 rootPanel.setBackground(Color.GREEN);
1001
1002 JPanel panel = new JPanel();
1003
1004 MigLayout m1 = new MigLayout("wrap 1");
1005
1006 panel.setLayout(m1);
1007
1008
1009 List<ResponseDeclarationType> responseDeclarations = assessmentItem
1010 .getResponseDeclaration();
1011
1012 if (responseDeclarations.isEmpty()) {
1013 JPanel itemPanel = new JPanel();
1014 itemPanel.setLayout(new BorderLayout(0, 0));
1015
1016 JLabel noNoteTakenLabel = createNoNoteTakenLabel();
1017 itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
1018 System.out.println("RD IS NOT LOADED");
1019 panel.add(itemPanel);
1020 } else {
1021 int iterator = 1;
1022 PromptType oldPrompt= null;
1023 String prompt = "";
1024
1025 for (ResponseDeclarationType rd : responseDeclarations) {
1026 BlockInteractionType bi = (BlockInteractionType) getInteractionByResponseDeclaration(rd);
1027 oldPrompt = bi.getPrompt();
1028 int index = oldPrompt.toString().indexOf("Part");
1029 int index2 = oldPrompt.toString().indexOf("Partner");
1030
1031 iterator++;
1032 JComponent htmlPromptPanel = JaxbQtiStepUI.createPromptPanel(bi);
1033 bi.setPrompt(oldPrompt);
1034 JPanel questionAnswerPanel = new JPanel();
1035 questionAnswerPanel.setLayout(new BorderLayout(0, 0));
1036
1037 String answer = getAnswer(rd,bi);
1038
1039 JPanel answerArea = createAnswerAreaWithAnnotations(htmlPromptPanel, answer, null);
1040
1041 htmlPromptPanel.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
1042
1043 questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
1044 questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
1045
1046 setCurrentStepPart(questionAnswerPanel);
1047
1048
1049 panel.add(questionAnswerPanel);
1050 CompoundBorder compoundBorder = createCompoundBorder();
1051 panel.setBorder(compoundBorder);
1052
1053
1054 }
1055 }
1056 rootPanel.add(panel, BorderLayout.CENTER);
1057
1058 if (logger.isLoggable(Level.CONFIG)) {
1059 logger.config("end");
1060 }
1061
1062 return rootPanel;
1063 }
1064
1065 /*****************************************************************************************************************/
1066 /********************************** SETTERS AND GETTERS *********************************************************/
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 /***
1082 * @param responseDeclarations
1083 * @param iterator
1084 * @param filteredPrompt
1085 * @param bi
1086 */
1087 private void setBiPrompt(List<ResponseDeclarationType> responseDeclarations, int iterator, BlockInteractionType bi) {
1088 String oldPrompt = bi.getPrompt().toString();
1089 int index = oldPrompt.indexOf("Part");
1090 int index2 = oldPrompt.indexOf("Partner");
1091 String filteredPrompt = extractBody(oldPrompt);
1092
1093 if(responseDeclarations.size() > 1){
1094 if((index < 0) || (index==index2)){
1095 bi.getPrompt().getContent().add("<html><body> Part " + iterator + " : " + filteredPrompt + "</body></html>");
1096
1097 }else{
1098 bi.getPrompt().getContent().add("<html><body>" + filteredPrompt + "</body></html>");
1099 }
1100 }else{
1101 bi.getPrompt().getContent().add("<html><body>" + filteredPrompt + "</body></html>");
1102 }
1103 }
1104
1105 public AssessmentItemType getAssessmentItem() {
1106 return assessmentItem;
1107 }
1108
1109 public void setAssessmentItem(AssessmentItemType assessmentItem) {
1110 Object old = this.assessmentItem;
1111 this.assessmentItem = assessmentItem;
1112 firePropertyChange("assessmentItem", old, assessmentItem);
1113 }
1114
1115 abstract public Component getComponent();
1116
1117 /***
1118 * @return the responses
1119 */
1120 public Map<String, Object> getResponses() {
1121 return responses;
1122 }
1123
1124 /***
1125 * Given choiceInteraction, returns student's last choice, if any
1126 *
1127 * @param interaction
1128 * @return String student's answer
1129 */
1130 public static String getStudentAnswer(JaxbQtiStep assessment,
1131 BlockInteractionType interaction) {
1132 List<ResponseDeclarationType> reponseDeclarations = assessment
1133 .getAssessmentItem().getResponseDeclaration();
1134 for (ResponseDeclarationType rd : reponseDeclarations) {
1135 if (rd.getIdentifier().equals(interaction.getResponseIdentifier())) {
1136 String studentAnswer = JaxbQtiStep.lastAnswer(assessment
1137 .getResponseDeclarationToSocks(), rd);
1138 return studentAnswer;
1139 }
1140 }
1141 return null;
1142 }
1143
1144
1145 private void setCurrentStepPart(JPanel currentPart){
1146 List<JPanel> currentStepParts = this.currentStepParts;
1147 currentStepParts.add(currentPart);
1148 this.currentStepParts = currentStepParts;
1149 }
1150
1151 public List<JPanel> getCurrentStepParts(){
1152 return this.currentStepParts;
1153 }
1154
1155 private void setCurrentPrompt(String currentPrompt){
1156 List<String> currentPrompts = this.currentPrompts;
1157 currentPrompts.add(currentPrompt);
1158 this.currentPrompts = currentPrompts;
1159 }
1160
1161 public List<String> getCurrentPrompts(){
1162 return this.currentPrompts;
1163 }
1164
1165 private void setCurrentAnswer(JLabel answerArea){
1166 List<JLabel> currentAnswers = this.answer;
1167 currentAnswers.add(answerArea);
1168 this.answer = currentAnswers;
1169 }
1170
1171 public List<JLabel> getCurrentAnswers(){
1172 return this.answer;
1173 }
1174
1175 /***
1176 * @return
1177 */
1178 private CompoundBorder createCompoundBorder() {
1179 CompoundBorder compoundBorder = BorderFactory
1180 .createCompoundBorder(BorderFactory.createEmptyBorder(
1181 0, 8, 0, 0), BorderFactory.createLineBorder(
1182 PasColors.noteReportLineBorderColor, 1));
1183 return compoundBorder;
1184 }
1185
1186 private BlockInteractionType getInteractionByResponseDeclaration(ResponseDeclarationType rd){
1187 return JaxbQtiStep
1188 .getInteractionByResponseDeclaration(
1189 getAssessmentItem().getItemBody()
1190 .getBlockElementGroup() , rd);
1191 }
1192
1193 public static BlockInteractionType getInteractionByResponseDeclaration(
1194 List interactions, ResponseDeclarationType rd) {
1195
1196 for (Object interaction : interactions) {
1197
1198 BlockInteractionType bi = (BlockInteractionType)interaction;
1199
1200 if (bi.getResponseIdentifier().equals(rd.getIdentifier())) {
1201 return bi;
1202 }
1203 }
1204
1205 return null;
1206 }
1207
1208 abstract public String getType();
1209
1210 /***
1211 * @return the responseDeclarationToSocks
1212 */
1213 public Map<ResponseDeclarationType, ISock<String>> getResponseDeclarationToSocks() {
1214 return responseDeclarationToSocks;
1215 }
1216
1217 /***
1218 * @see org.telscenter.pas.beans.IWorkReporter#getEntityToPromptMap()
1219 */
1220 public Map<String, String> getEntityToPromptMap() {
1221 Map<String, String> rimToPromptMap = new HashMap<String, String>();
1222 List<ResponseDeclarationType> responseDeclarations = assessmentItem
1223 .getResponseDeclaration();
1224 for (ResponseDeclarationType responseDeclaration : responseDeclarations) {
1225
1226 Rim rim = responseDeclarationsToRims.get(responseDeclaration);
1227
1228
1229
1230 String rimname = rim.getName();
1231 BlockInteractionType bi = getInteractionByResponseDeclaration(responseDeclaration);
1232 String prompt = bi.getPrompt().getContent().toString();
1233
1234 rimToPromptMap.put(rimname, prompt);
1235 }
1236 return rimToPromptMap;
1237 }
1238
1239 /***
1240 * @return the injectPrompt
1241 */
1242 public boolean isInjectPrompt() {
1243 return injectPrompt;
1244 }
1245
1246 /***
1247 * @param injectPrompt the injectPrompt to set
1248 */
1249 public void setInjectPrompt(boolean injectPrompt) {
1250 this.injectPrompt = injectPrompt;
1251 Object old = this.injectPrompt;
1252 firePropertyChange("injectPrompt", old, injectPrompt);
1253 }
1254
1255 public Integer getPossibleScore() {
1256 return possibleScore;
1257 }
1258
1259 public void setPossibleScore(Integer possibleScore) {
1260 this.possibleScore = possibleScore;
1261 }
1262
1263 public boolean getTabbed() {
1264 return isTabbed;
1265 }
1266
1267 public void setTabbed(boolean isTabbed) {
1268 this.isTabbed = isTabbed;
1269 }
1270
1271 public AgentService getAgentService() {
1272 return agentService;
1273 }
1274
1275
1276 public SessionService getSessionService() {
1277 return sessionService;
1278 }
1279
1280 public boolean isSubmitted() {
1281 return this.submitted;
1282 }
1283
1284 public void setSubmitted(boolean hasSubmitted) {
1285 this.submitted = hasSubmitted;
1286 }
1287
1288 /***
1289 * Sets the response declarations to rims this is called from who creates the step
1290 *
1291 * @param rd
1292 * @param rim
1293 */
1294 public void setResponseDeclarationsToRims(Map<ResponseDeclarationType, Rim> responseDeclarationsToRims) {
1295 Object old = responseDeclarationsToRims;
1296 this.responseDeclarationsToRims = responseDeclarationsToRims;
1297 firePropertyChange("responseDeclarationsToRims", old, responseDeclarationsToRims);
1298 }
1299
1300 /***
1301 * Response Declarations, gettem
1302 *
1303 * @return rd
1304 */
1305 public Map<ResponseDeclarationType, Rim> getResponseDeclarationsToRims() {
1306 return this.responseDeclarationsToRims;
1307 }
1308
1309 public void addRdToRim( ResponseDeclarationType rd, Rim rim) {
1310 if( this.responseDeclarationsToRims == null ) {
1311 this.responseDeclarationsToRims = new HashMap<ResponseDeclarationType, Rim>();
1312 }
1313
1314 this.responseDeclarationsToRims.put(rd, rim);
1315 }
1316
1317 public boolean hasInlineFeedback() {
1318 return false;
1319 }
1320 }