1 package debugger.gui.debugging;
2
3 import debugger.gui.GuiFactory;
4 import debugger.gui.debugging.debugviews.PrimaryTextPanel;
5 import debugger.resources.ResourcesFactory;
6 import debugger.resources.pr.PhaseModel;
7 import debugger.resources.pr.RuleModel;
8 import debugger.resources.pr.RuleTrace;
9 import debugger.resources.pr.TraceContainer;
10 import gate.Annotation;
11 import gate.AnnotationSet;
12 import gate.Document;
13 import gate.FeatureMap;
14 import gate.util.InvalidOffsetException;
15 import gate.util.OffsetComparator;
16
17 import javax.swing.*;
18 import javax.swing.text.DefaultCaret;
19 import javax.swing.text.StyledEditorKit;
20 import java.awt.*;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.util.*;
24
25
32
33 public class TraceHistoryPanel extends JPanel {
34 private JPanel rulePanel;
35 private JLabel phaseName;
36 private JLabel ruleName;
37 private JTextPane selectedTextPane;
38 private JTextPane rulePane;
39 private JButton nextAnnotationButton;
40 private JButton previousAnnotationButton;
41
42 private PhaseModel currentPhaseModel;
43 private RuleModel currentRuleModel;
44 private TraceContainer traceContainer;
45 private Document document;
46 private int currentStartOffset;
47 private int currentEndOffset;
48 private TraceContainer currentTraces;
49 private RuleTrace currentRuleTrace;
50 private AnnotationSet currentAnnotationCut;
51
52 public TraceHistoryPanel() {
53 initGui();
54 }
55
56 private void initGui() {
57 this.setLayout(new GridBagLayout());
58 GridBagConstraints c = new GridBagConstraints();
59
60 c.gridx = 0;
61 c.gridy = 0;
62 c.weightx = 0;
63 c.weighty = 0;
64 c.gridwidth = 1;
65 c.fill = GridBagConstraints.HORIZONTAL;
66 this.add(getUpperPanel(), c);
67
68 c.gridx = 0;
69 c.gridy = 1;
70 c.weightx = 1;
71 c.weighty = 1;
72 c.gridwidth = 1;
73 c.fill = GridBagConstraints.BOTH;
74
75 JScrollPane ruleScrollPane = new JScrollPane(getRulePane(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
76 ruleScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule Text"));
77
78 JScrollPane panelScrollPane = new JScrollPane(getRulePanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
79 panelScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule"));
80
81 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panelScrollPane, ruleScrollPane);
82 splitPane.setDividerLocation(200);
83 this.add(splitPane, c);
87 c.gridy = 2;
88 c.weighty = 0;
89 c.fill = GridBagConstraints.NONE;
90 }
92
93 private JTextPane getRulePane() {
94 if (rulePane == null) {
95 rulePane = new JTextPane();
96 rulePane.setEditorKit(new StyledEditorKit());
97 rulePane.setDocument(new SyntaxDocument());
98 rulePane.setEditable(false);
99 rulePane.setCaret(new DefaultCaret() {
101 protected void adjustVisibility(Rectangle nloc) {
102 }
103 });
104 }
105 return rulePane;
106 }
107
108 private JComponent getSelectedTextPane() {
109 selectedTextPane = new JTextPane();
110 selectedTextPane.setEditable(false);
111 selectedTextPane.setCaret(new DefaultCaret() {
113 protected void adjustVisibility(Rectangle nloc) {
114 }
115 });
116 nextAnnotationButton = new JButton("Next");
117 previousAnnotationButton = new JButton("Previous");
118 JPanel panel = new JPanel(new GridBagLayout());
119 GridBagConstraints c = new GridBagConstraints();
120 c.fill = GridBagConstraints.BOTH;
121 c.gridx = 0;
122 c.gridy = 0;
123 c.weightx = 1;
124 c.weighty = 1;
125 c.fill = GridBagConstraints.NONE;
127 c.gridx = 0; c.weightx = 0;
129 c.weighty = 0;
130 panel.add(previousAnnotationButton, c);
131 previousAnnotationButton.setEnabled(false);
132 previousAnnotationButton.addActionListener(new ActionListener() {
133 public void actionPerformed(ActionEvent e) {
134 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
135 int index = currentTraces.lastIndexOf(currentRuleTrace);
136 if (index > 0) {
137 updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index - 1));
138 currentRuleTrace = (RuleTrace) currentTraces.get(index - 1);
139 }
140 if (index - 1 == 0) {
141 previousAnnotationButton.setEnabled(false);
142 } else {
143 previousAnnotationButton.setEnabled(true);
144 }
145 if (index < currentTraces.size() && currentTraces.size() > 1) {
146 nextAnnotationButton.setEnabled(true);
147 }
148 }
149 GuiFactory.getResourceView().repaint();
150 }
151 });
152 c.gridx = 1; panel.add(nextAnnotationButton, c);
154 nextAnnotationButton.setEnabled(false);
155 nextAnnotationButton.addActionListener(new ActionListener() {
156 public void actionPerformed(ActionEvent e) {
157 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
158 int index = currentTraces.lastIndexOf(currentRuleTrace);
159 if (index + 1 < currentTraces.size()) {
160 updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index + 1));
161 currentRuleTrace = (RuleTrace) currentTraces.get(index + 1);
162 }
163 if (index + 2 >= currentTraces.size()) {
164 nextAnnotationButton.setEnabled(false);
165 } else {
166 nextAnnotationButton.setEnabled(true);
167 }
168 if (index + 1 > 0) {
169 previousAnnotationButton.setEnabled(true);
170 }
171 GuiFactory.getResourceView().repaint();
172 }
173 }
174 });
175 return panel;
176 }
177
178 private JComponent getRulePanel() {
179 if (rulePanel == null) {
180 rulePanel = new JPanel();
181 }
182 return rulePanel;
183 }
184
185 private JComponent getUpperPanel() {
186 JPanel panel = new JPanel(new GridBagLayout());
187 GridBagConstraints c = new GridBagConstraints();
188 c.gridx = 0;
189 c.gridy = 0;
190 c.weightx = 0;
191 c.weighty = 0;
192 c.anchor = GridBagConstraints.WEST;
193 c.insets = new Insets(0, 4, 0, 0);
194 panel.add(new JLabel("Rule: "), c);
195
196 c.gridx = 1;
197 ruleName = new JLabel();
198 panel.add(ruleName, c);
199
200 c.gridx = 2;
201 c.weightx = 1;
202 panel.add(new JPanel(), c);
203 c.gridx = 3;
204 c.weightx = 0;
205 panel.add(new JPanel(), c);
206 c.gridx = 3;
207 c.gridwidth = 2;
208 panel.add(new JPanel(), c);
209
210 c.gridx = 0;
211 c.gridy = 1;
212 c.weightx = 1;
213 c.gridwidth = 3;
214 panel.add(new JPanel(), c);
215
216 c.gridwidth = 1;
217 c.gridx = 3;
218 c.weightx = 0;
219 c.anchor = GridBagConstraints.EAST;
220 panel.add(new JLabel("Phase: "), c);
221
222 c.gridx = 4;
223 phaseName = new JLabel();
224 panel.add(phaseName, c);
225
226 c.gridx = 0;
227 c.gridy = 2;
228 c.weightx = 0;
229 c.weighty = 0;
230 c.gridwidth = 2;
231 c.fill = GridBagConstraints.NONE;
232 c.anchor = GridBagConstraints.WEST;
233 c.insets = new Insets(0, 0, 4, 0);
234 panel.add(getSelectedTextPane(), c);
235
236 return panel;
237 }
238
239
246 public void setText(int startOffset, int endOffset, Document document) {
247 TraceContainer traceContainer = ResourcesFactory.getPhaseController().getRuleTrace();
248 traceContainer = traceContainer.getTraceByOffset(new Long(startOffset), new Long(endOffset));
249 try {
250 this.selectedTextPane.setText(
251 document.getContent().getContent(new Long(min(startOffset,
252 document.getContent().size().longValue() - 1L)),
253 new Long(min(endOffset,
254 document.getContent().size().longValue() - 1L)))
255 .toString());
256 } catch (InvalidOffsetException e) {
257 System.out.println("Start offset = "+startOffset+
258 "End offset = "+endOffset);
259 System.out.println("Document size = "+document.getContent().size());
260 e.printStackTrace();
261 }
262 this.traceContainer = traceContainer;
263 this.document = document;
264 this.currentStartOffset = startOffset;
265 this.currentEndOffset = endOffset;
266 this.updateRulePanel(null, null);
268 this.repaint();
270 }
271
272
279 private long min(long a, long b) {
280 if (a < b)
281 return a;
282 else
283 return b;
284 }
285
286
300 private JComponent createAnnotationPanel(AnnotationSet annotations, String annotationsType, RuleTrace ruleTrace, boolean withHighlighting) {
301 JPanel panel = new JPanel(new GridBagLayout());
302 GridBagConstraints c = new GridBagConstraints();
303
304 c.gridx = 0;
305 c.gridy = 0;
306 c.weightx = 0;
307 c.weighty = 0;
308 c.gridwidth = 1;
309 c.gridheight = 1;
310 c.anchor = GridBagConstraints.WEST;
311 c.fill = GridBagConstraints.NONE;
312
313 AnnotationSet annotationsToHighlight = null;
315 if (ruleTrace != null) {
316 annotationsToHighlight = ruleTrace.getAnnotations();
317 }
318
319 long lastNodeOffset = 0;
320 if (annotationsToHighlight != null) {
321 lastNodeOffset = annotationsToHighlight.lastNode().getOffset().longValue();
322 }
323
324 HashSet annotationsToShowSet = new HashSet();
326 if (annotations != null) {
327 annotationsToShowSet.addAll(annotations);
328 }
329
330 HashSet tokensNotToBeIncluded = new HashSet();
332 for (Iterator it = annotationsToShowSet.iterator(); it.hasNext();) {
333 Annotation currentAnnotation = (Annotation) it.next();
334 AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
335 if (containedTokens != null) {
336 tokensNotToBeIncluded.addAll(containedTokens);
337 }
338 }
339 AnnotationSet tokenAnnotationSet = currentAnnotationCut.get("Token", new Long(currentStartOffset), new Long(currentEndOffset));
340 if (tokenAnnotationSet != null) {
341 for (Iterator it = tokenAnnotationSet.iterator(); it.hasNext();) {
342 Annotation currentAnnotation = (Annotation) it.next();
343 if (!tokensNotToBeIncluded.contains(currentAnnotation)) {
344 annotationsToShowSet.add(currentAnnotation);
345 }
346 }
347 }
348
350 ArrayList list = new ArrayList(annotationsToShowSet);
352 Collections.sort(list, new OffsetComparator());
353
359 Collections.sort(list, new Comparator() {
360 public int compare(Object o1, Object o2) {
361 Annotation a1 = (Annotation) o1;
362 Annotation a2 = (Annotation) o2;
363 long offset1 = a1.getStartNode().getOffset().longValue();
364 long offset2 = a2.getStartNode().getOffset().longValue();
365 long length1 = a1.getEndNode().getOffset().longValue() - offset1;
366 long length2 = a2.getEndNode().getOffset().longValue() - offset2;
367 if (offset1 > offset2) {
368 return 1;
369 }
370 if (offset1 < offset2) {
371 return -1;
372 }
373 if (offset1 == offset2) {
374 if (length1 > length2)
375 return -1;
376 else if (length1 < length2)
377 return 1;
378 else
379 return 0;
380 }
381 return 0;
382 }
383 });
384
386 ArrayList annotationsToIgnore = new ArrayList();
389 boolean isRedSet = false;
390
391 int x = 0;
392 for (Iterator it = list.iterator(); it.hasNext();) {
393 Annotation currentAnnotation = (Annotation) it.next();
394
395 AnnotationSet containedAnnotationsOfTheSameType = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get(annotationsType);
397 if (containedAnnotationsOfTheSameType != null) {
398 for (Iterator iter = containedAnnotationsOfTheSameType.iterator(); iter.hasNext();) {
399 Annotation ann = (Annotation) iter.next();
400 if (!ann.equals(currentAnnotation)) {
401 annotationsToIgnore.add(ann);
402 }
403 }
404 }
405
406 AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
408 ArrayList containedTokensList = null;
409 if (containedTokens != null) {
410 containedTokensList = new ArrayList(containedTokens);
411 } else {
412 containedTokensList = new ArrayList();
413 }
414 Collections.sort(containedTokensList, new OffsetComparator());
415
416 int order = 0;
418 if (!annotationsToIgnore.contains(currentAnnotation)) {
419 for (Iterator iter = containedTokensList.iterator(); iter.hasNext();) {
421 Annotation currentTokenAnnotation = (Annotation) iter.next();
422 String text = (String) currentTokenAnnotation.getFeatures().get("string");
423 PrimaryTextPanel textPanel = new PrimaryTextPanel(text, false, PrimaryTextPanel.OPEN_NONE);
424 if (containedAnnotationsOfTheSameType != null) {
425 textPanel.setAnnotations(new ArrayList(containedAnnotationsOfTheSameType));
426 } else {
427 ArrayList arr = new ArrayList();
428 arr.add(currentAnnotation);
429 textPanel.setAnnotations(arr);
430 }
431 if (containedTokens.size() == 1) {
432 textPanel.setOpenMode(PrimaryTextPanel.OPEN_NONE);
433 } else if (order == 0 && containedTokens.size() > 1) {
434 textPanel.setOpenMode(PrimaryTextPanel.OPEN_RIGHT);
435 } else if (order == (containedTokens.size() - 1)) {
436 textPanel.setOpenMode(PrimaryTextPanel.OPEN_LEFT);
437 } else {
438 textPanel.setOpenMode(PrimaryTextPanel.OPEN_BOTH);
439 }
440
441 if (currentTokenAnnotation.equals(currentAnnotation) && !annotationsType.equals("Token")) {
443 textPanel.setTextVisible(false);
444 }
445 if (annotationsToHighlight != null && annotationsToHighlight.contains(currentAnnotation) && textPanel.isTextVisible() && withHighlighting) {
446 textPanel.setHighlighted(true);
447 }
448 if (containedAnnotationsOfTheSameType != null) {
449 for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
450 Annotation a = (Annotation) iterator.next();
451 if (annotationsToHighlight != null && annotationsToHighlight.contains(a) && textPanel.isTextVisible()) {
452 int startOffset = a.getStartNode().getOffset().intValue();
453 int endOffset = a.getEndNode().getOffset().intValue();
454 int tokenStartOffset = currentTokenAnnotation.getStartNode().getOffset().intValue();
455 int tokenEndOffset = currentTokenAnnotation.getEndNode().getOffset().intValue();
456 if (startOffset <= tokenStartOffset && tokenEndOffset <= endOffset && endOffset >= tokenStartOffset && withHighlighting) {
457 textPanel.setHighlighted(true);
458 }
459 }
460 }
461 }
462 if (ruleTrace != null && !ruleTrace.isFinished() && currentAnnotation.getStartNode().getOffset().longValue() >= lastNodeOffset
463 && !isRedSet && textPanel.isTextVisible() && withHighlighting) {
464 textPanel.setRed(true);
465 if (textPanel.getOpenMode() == PrimaryTextPanel.OPEN_NONE || textPanel.getOpenMode() == PrimaryTextPanel.OPEN_LEFT) {
466 isRedSet = true;
467 }
468 }
469
471 String toolTipText = "";
473 FeatureMap featureMap = null;
474 if (ruleTrace != null) {
475 featureMap = ruleTrace.getPattern(currentAnnotation);
476 }
477 if (featureMap == null && containedAnnotationsOfTheSameType != null) {
478 if (ruleTrace != null) {
479 for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
480 featureMap = ruleTrace.getPattern((Annotation) iterator.next());
481 if (featureMap != null)
482 break;
483 }
484 }
485 }
486 if (featureMap != null) {
487 for (Iterator i = featureMap.keySet().iterator(); i.hasNext();) {
488 toolTipText = toolTipText + " " + annotationsType + ".";
489 Object key = i.next();
490 toolTipText = toolTipText + key + "=" + featureMap.get(key);
491 }
492 if (featureMap.keySet().isEmpty()) {
493 toolTipText = annotationsType;
494 }
495 }
496 if (featureMap != null && textPanel.isTextVisible() && (textPanel.isHighlighted() || textPanel.isRed())
497 && withHighlighting) {
498 textPanel.setToolTipText(toolTipText);
499 }
500
502 c.gridx = x;
503 panel.add(textPanel, c);
504 order++;
505 x++;
506 }
507 }
508 }
509 return panel;
510 }
511
512
517 public void updateRulePanel(RuleModel ruleModel, RuleTrace currentTrace) {
518 if (ruleModel != null) {
519 rulePane.setText(ruleModel.getRuleText());
520 }
521 RuleTrace ruleTrace = null;
522 if (currentTrace == null && traceContainer != null) {
523 if (traceContainer != null) {
524 TraceContainer traces = traceContainer.getTraceByRuleModel(ruleModel);
525 if (traces.size() > 0) {
526 ruleTrace = (RuleTrace) traces.iterator().next();
527 }
528 previousAnnotationButton.setEnabled(false);
529 nextAnnotationButton.setEnabled(false);
530 if (traces.size() > 1) {
531 nextAnnotationButton.setEnabled(true);
532 }
533 currentTraces = traces;
534 currentRuleTrace = ruleTrace;
535 }
536 } else {
537 ruleTrace = currentTrace;
538 currentRuleTrace = ruleTrace;
539 }
540 if (traceContainer != null) {
541 currentAnnotationCut = traceContainer.getPhaseCut(currentPhaseModel);
542 JPanel panel = new JPanel();
543 panel.setLayout(new GridBagLayout());
544 GridBagConstraints c = new GridBagConstraints();
545 int i = 0;
546 c.anchor = GridBagConstraints.WEST;
547 c.insets = new Insets(2, 4, 2, 4);
548 if (currentPhaseModel != null) {
550 for (Iterator it = currentPhaseModel.getInput().iterator(); it.hasNext();) {
551 String input = (String) it.next();
552 c.fill = GridBagConstraints.NONE;
553 c.gridx = 0;
554 c.weightx = 0;
555 c.gridy = i++;
556 panel.add(new JLabel(input), c);
557 c.gridx = 1;
558 if (currentAnnotationCut != null) {
559 panel.add(createAnnotationPanel(currentAnnotationCut.get(input, new Long(currentStartOffset), new Long(currentEndOffset)), input, ruleTrace, true), c);
560 } else {
561 panel.add(new JLabel("No annotations of type " + input + " available"), c);
562 }
563 c.gridx = 2;
564 c.weightx = 1;
565 c.fill = GridBagConstraints.HORIZONTAL;
566 panel.add(new JPanel(), c);
567 }
568 }
569
571 c.gridx = 0;
573 c.gridy = i;
574 c.weightx = 0;
575 c.weighty = 0;
576 c.gridwidth = 2;
577 panel.add(new JPanel() {
578 {
579 this.setBackground(Color.black);
580 }
581
582 public Dimension getPreferredSize() {
583 return getMaximumSize();
584 }
585
586 public Dimension getMaximumSize() {
587 return new Dimension(20, 2);
588 }
589 },
590 c);
591 c.gridx = 1;
592 c.weightx = 1;
593 c.gridy = i++;
594 panel.add(new JPanel(), c);
595
597 c.fill = GridBagConstraints.NONE;
599 c.gridx = 0;
600 c.weightx = 0;
601 c.gridy = i++;
602 panel.add(new JLabel(""), c);
603 c.gridx = 1;
604 if (document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token") != null) {
605 if (currentAnnotationCut == null) {
606 currentAnnotationCut = document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token");
607 }
608 panel.add(createAnnotationPanel(document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token"), "Token", ruleTrace, false), c);
609 } else {
610 panel.add(new JLabel("No annotations of type Token available"), c);
611 }
612 c.gridx = 2;
613 c.weightx = 1;
614 c.fill = GridBagConstraints.HORIZONTAL;
615 panel.add(new JPanel(), c);
616
618 c.gridx = 0;
620 c.gridy = i++;
621 c.weightx = 0;
622 c.weighty = 1;
623 panel.add(new JPanel(), c);
624
625 getRulePanel().removeAll();
627 getRulePanel().setLayout(new BorderLayout());
628 getRulePanel().add(panel, BorderLayout.CENTER);
629 this.revalidate();
630
631 }
644 }
651
652
659 public void setCurrentRule(RuleModel ruleModel) {
660 currentRuleModel = ruleModel;
661 currentPhaseModel = ruleModel.getParentPhase();
662 phaseName.setText(currentPhaseModel.getName() + " Control = " + currentPhaseModel.getControl());
663 ruleName.setText(ruleModel.getName());
664 }
665
666
673 public void setCurrentPhase(PhaseModel phaseModel) {
674 currentPhaseModel = phaseModel;
675 phaseName.setText(currentPhaseModel.getName() + " Control = " + currentPhaseModel.getControl());
676 if (currentRuleModel != null && !currentRuleModel.getParentPhase().equals(currentPhaseModel)) {
677 getRulePanel().removeAll();
678 getRulePanel().add(new JLabel("No rule currently selected."));
679 }
680 ruleName.setText("");
681 }
682
683
687 public RuleTrace getCurrentRuleTrace() {
688 return currentRuleTrace;
689 }
690
691
695 public RuleModel getCurrentRuleModel() {
696 return currentRuleModel;
697 }
698 }
699