1 package debugger.gui.debugging;
2
3 import debugger.gui.*;
4 import debugger.gui.debugging.debugviews.*;
5 import debugger.resources.*;
6 import debugger.resources.pr.*;
7
8 import javax.swing.*;
9 import javax.swing.text.*;
10
11 import java.awt.*;
12 import java.awt.event.*;
13 import java.util.*;
14
15 import gate.*;
16 import gate.util.*;
17 import gate.Document;
18
19
23 public class JapeDebuggingPanel extends JPanel {
24 private JPanel rulePanel;
25 private JLabel phaseName;
26 private JLabel ruleName;
27 private JTextPane selectedTextPane;
28 private JTextPane rulePane;
29 private JButton nextAnnotationButton;
30 private JButton previousAnnotationButton;
31
32 private PhaseModel currentPhaseModel;
33 private RuleModel currentRuleModel;
34 private TraceContainer traceContainer;
35 private Document document;
36 private int currentStartOffset;
37 private int currentEndOffset;
38 private TraceContainer currentTraces;
39 private RuleTrace currentRuleTrace;
40 private AnnotationSet currentAnnotationCut;
41
42 public JapeDebuggingPanel() {
43 initGui();
44 }
45
46 private void initGui() {
47 this.setLayout(new GridBagLayout());
48 GridBagConstraints c = new GridBagConstraints();
49
50 c.gridx = 0;
51 c.gridy = 0;
52 c.weightx = 0;
53 c.weighty = 0;
54 c.gridwidth = 1;
55 c.fill = GridBagConstraints.HORIZONTAL;
56 this.add(getUpperPanel(), c);
57
58 c.gridx = 0;
59 c.gridy = 1;
60 c.weightx = 1;
61 c.weighty = 1;
62 c.gridwidth = 1;
63 c.fill = GridBagConstraints.BOTH;
64
65 JScrollPane ruleScrollPane = new JScrollPane(getRulePane(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
66 ruleScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule Text"));
67
68 JScrollPane panelScrollPane = new JScrollPane(getRulePanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
69 panelScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule"));
70
71 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panelScrollPane, ruleScrollPane);
72 splitPane.setDividerLocation(200);
73 this.add(splitPane, c);
77 c.gridy = 2;
78 c.weighty = 0;
79 c.fill = GridBagConstraints.NONE;
80 }
82
83 private JTextPane getRulePane() {
84 if (rulePane == null) {
85 rulePane = new JTextPane();
86 rulePane.setEditorKit(new StyledEditorKit());
87 rulePane.setDocument(new SyntaxDocument());
88 rulePane.setEditable(false);
89 rulePane.setCaret(new DefaultCaret() {
91 protected void adjustVisibility(Rectangle nloc) {
92 }
93 });
94 }
95 return rulePane;
96 }
97
98 private JComponent getSelectedTextPane() {
99 selectedTextPane = new JTextPane();
100 selectedTextPane.setEditable(false);
101 selectedTextPane.setCaret(new DefaultCaret() {
103 protected void adjustVisibility(Rectangle nloc) {
104 }
105 });
106 nextAnnotationButton = new JButton("Next");
107 previousAnnotationButton = new JButton("Previous");
108 JPanel panel = new JPanel(new GridBagLayout());
109 GridBagConstraints c = new GridBagConstraints();
110 c.fill = GridBagConstraints.BOTH;
111 c.gridx = 0;
112 c.gridy = 0;
113 c.weightx = 1;
114 c.weighty = 1;
115 c.fill = GridBagConstraints.NONE;
117 c.gridx = 0; c.weightx = 0;
119 c.weighty = 0;
120 panel.add(previousAnnotationButton, c);
121 previousAnnotationButton.setEnabled(false);
122 previousAnnotationButton.addActionListener(new ActionListener() {
123 public void actionPerformed(ActionEvent e) {
124 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
125 int index = currentTraces.lastIndexOf(currentRuleTrace);
126 if (index > 0) {
127 updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index - 1));
128 currentRuleTrace = (RuleTrace) currentTraces.get(index - 1);
129 }
130 if (index - 1 == 0) {
131 previousAnnotationButton.setEnabled(false);
132 } else {
133 previousAnnotationButton.setEnabled(true);
134 }
135 if (index < currentTraces.size() && currentTraces.size() > 1) {
136 nextAnnotationButton.setEnabled(true);
137 }
138 }
139 GuiFactory.getResourceView().repaint();
140 }
141 });
142 c.gridx = 1; panel.add(nextAnnotationButton, c);
144 nextAnnotationButton.setEnabled(false);
145 nextAnnotationButton.addActionListener(new ActionListener() {
146 public void actionPerformed(ActionEvent e) {
147 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
148 int index = currentTraces.lastIndexOf(currentRuleTrace);
149 if (index + 1 < currentTraces.size()) {
150 updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index + 1));
151 currentRuleTrace = (RuleTrace) currentTraces.get(index + 1);
152 }
153 if (index + 2 >= currentTraces.size()) {
154 nextAnnotationButton.setEnabled(false);
155 } else {
156 nextAnnotationButton.setEnabled(true);
157 }
158 if (index + 1 > 0) {
159 previousAnnotationButton.setEnabled(true);
160 }
161 GuiFactory.getResourceView().repaint();
162 }
163 }
164 });
165 return panel;
166 }
167
168 private JComponent getRulePanel() {
169 if (rulePanel == null) {
170 rulePanel = new JPanel();
171 }
172 return rulePanel;
173 }
174
175 private JComponent getUpperPanel() {
176 JPanel panel = new JPanel(new GridBagLayout());
177 GridBagConstraints c = new GridBagConstraints();
178 c.gridx = 0;
179 c.gridy = 0;
180 c.weightx = 0;
181 c.weighty = 0;
182 c.anchor = GridBagConstraints.WEST;
183 c.insets = new Insets(0, 4, 0, 0);
184 panel.add(new JLabel("Rule: "), c);
185
186 c.gridx = 1;
187 ruleName = new JLabel();
188 panel.add(ruleName, c);
189
190 c.gridx = 2;
191 c.weightx = 1;
192 panel.add(new JPanel(), c);
193 c.gridx = 3;
194 c.weightx = 0;
195 panel.add(new JPanel(), c);
196 c.gridx = 3;
197 c.gridwidth = 2;
198 panel.add(new JPanel(), c);
199
200 c.gridx = 0;
201 c.gridy = 1;
202 c.weightx = 1;
203 c.gridwidth = 3;
204 panel.add(new JPanel(), c);
205
206 c.gridwidth = 1;
207 c.gridx = 3;
208 c.weightx = 0;
209 c.anchor = GridBagConstraints.EAST;
210 panel.add(new JLabel("Phase: "), c);
211
212 c.gridx = 4;
213 phaseName = new JLabel();
214 panel.add(phaseName, c);
215
216 c.gridx = 0;
217 c.gridy = 2;
218 c.weightx = 0;
219 c.weighty = 0;
220 c.gridwidth = 2;
221 c.fill = GridBagConstraints.NONE;
222 c.anchor = GridBagConstraints.WEST;
223 c.insets = new Insets(0, 0, 4, 0);
224 panel.add(getSelectedTextPane(), c);
225
226 return panel;
227 }
228
229
236 public void setText(int startOffset, int endOffset, Document document) {
237 TraceContainer traceContainer = ResourcesFactory.getPhaseController().getRuleTrace();
238 traceContainer = traceContainer.getTraceByOffset(new Long(startOffset), new Long(endOffset));
239 try {
240 this.selectedTextPane.setText(document.getContent().getContent(new Long(startOffset), new Long(endOffset)).toString());
241 } catch (InvalidOffsetException e) {
242 e.printStackTrace();
243 }
244 this.traceContainer = traceContainer;
245 this.document = document;
246 this.currentStartOffset = startOffset;
247 this.currentEndOffset = endOffset;
248 this.updateRulePanel(null, null);
250 this.repaint();
252 }
253
254
268 private JComponent createAnnotationPanel(AnnotationSet annotations, String annotationsType, RuleTrace ruleTrace, boolean withHighlighting) {
269 JPanel panel = new JPanel(new GridBagLayout());
270 GridBagConstraints c = new GridBagConstraints();
271
272 c.gridx = 0;
273 c.gridy = 0;
274 c.weightx = 0;
275 c.weighty = 0;
276 c.gridwidth = 1;
277 c.gridheight = 1;
278 c.anchor = GridBagConstraints.WEST;
279 c.fill = GridBagConstraints.NONE;
280
281 AnnotationSet annotationsToHighlight = null;
283 if (ruleTrace != null) {
284 annotationsToHighlight = ruleTrace.getAnnotations();
285 }
286
287 long lastNodeOffset = 0;
288 if (annotationsToHighlight != null) {
289 lastNodeOffset = annotationsToHighlight.lastNode().getOffset().longValue();
290 }
291
292 HashSet annotationsToShowSet = new HashSet();
294 if (annotations != null) {
295 annotationsToShowSet.addAll(annotations);
296 }
297
298 HashSet tokensNotToBeIncluded = new HashSet();
300 for (Iterator it = annotationsToShowSet.iterator(); it.hasNext();) {
301 Annotation currentAnnotation = (Annotation) it.next();
302 AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
303 if (containedTokens != null) {
304 tokensNotToBeIncluded.addAll(containedTokens);
305 }
306 }
307 AnnotationSet tokenAnnotationSet = currentAnnotationCut.get("Token", new Long(currentStartOffset), new Long(currentEndOffset));
308 if (tokenAnnotationSet != null) {
309 for (Iterator it = tokenAnnotationSet.iterator(); it.hasNext();) {
310 Annotation currentAnnotation = (Annotation) it.next();
311 if (!tokensNotToBeIncluded.contains(currentAnnotation)) {
312 annotationsToShowSet.add(currentAnnotation);
313 }
314 }
315 }
316
318 ArrayList list = new ArrayList(annotationsToShowSet);
320 Collections.sort(list, new OffsetComparator());
321
327 Collections.sort(list, new Comparator() {
328 public int compare(Object o1, Object o2) {
329 Annotation a1 = (Annotation) o1;
330 Annotation a2 = (Annotation) o2;
331 long offset1 = a1.getStartNode().getOffset().longValue();
332 long offset2 = a2.getStartNode().getOffset().longValue();
333 long length1 = a1.getEndNode().getOffset().longValue() - offset1;
334 long length2 = a2.getEndNode().getOffset().longValue() - offset2;
335 if (offset1 > offset2) {
336 return 1;
337 }
338 if (offset1 < offset2) {
339 return -1;
340 }
341 if (offset1 == offset2) {
342 if (length1 > length2)
343 return -1;
344 else if (length1 < length2)
345 return 1;
346 else
347 return 0;
348 }
349 return 0;
350 }
351 });
352
354 ArrayList annotationsToIgnore = new ArrayList();
357 boolean isRedSet = false;
358
359 int x = 0;
360 for (Iterator it = list.iterator(); it.hasNext();) {
361 Annotation currentAnnotation = (Annotation) it.next();
362
363 AnnotationSet containedAnnotationsOfTheSameType = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get(annotationsType);
365 if (containedAnnotationsOfTheSameType != null) {
366 for (Iterator iter = containedAnnotationsOfTheSameType.iterator(); iter.hasNext();) {
367 Annotation ann = (Annotation) iter.next();
368 if (!ann.equals(currentAnnotation)) {
369 annotationsToIgnore.add(ann);
370 }
371 }
372 }
373
374 AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
376 ArrayList containedTokensList = null;
377 if (containedTokens != null) {
378 containedTokensList = new ArrayList(containedTokens);
379 } else {
380 containedTokensList = new ArrayList();
381 }
382 Collections.sort(containedTokensList, new OffsetComparator());
383
384 int order = 0;
386 if (!annotationsToIgnore.contains(currentAnnotation)) {
387 for (Iterator iter = containedTokensList.iterator(); iter.hasNext();) {
389 Annotation currentTokenAnnotation = (Annotation) iter.next();
390 String text = (String) currentTokenAnnotation.getFeatures().get("string");
391 PrimaryTextPanel textPanel = new PrimaryTextPanel(text, false, PrimaryTextPanel.OPEN_NONE);
392 if (containedAnnotationsOfTheSameType != null) {
393 textPanel.setAnnotations(new ArrayList(containedAnnotationsOfTheSameType));
394 } else {
395 ArrayList arr = new ArrayList();
396 arr.add(currentAnnotation);
397 textPanel.setAnnotations(arr);
398 }
399 if (containedTokens.size() == 1) {
400 textPanel.setOpenMode(PrimaryTextPanel.OPEN_NONE);
401 } else if (order == 0 && containedTokens.size() > 1) {
402 textPanel.setOpenMode(PrimaryTextPanel.OPEN_RIGHT);
403 } else if (order == (containedTokens.size() - 1)) {
404 textPanel.setOpenMode(PrimaryTextPanel.OPEN_LEFT);
405 } else {
406 textPanel.setOpenMode(PrimaryTextPanel.OPEN_BOTH);
407 }
408
409 if (currentTokenAnnotation.equals(currentAnnotation) && !annotationsType.equals("Token")) {
411 textPanel.setTextVisible(false);
412 }
413 if (annotationsToHighlight != null && annotationsToHighlight.contains(currentAnnotation) && textPanel.isTextVisible() && withHighlighting) {
414 textPanel.setHighlighted(true);
415 }
416 if (containedAnnotationsOfTheSameType != null) {
417 for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
418 Annotation a = (Annotation) iterator.next();
419 if (annotationsToHighlight != null && annotationsToHighlight.contains(a) && textPanel.isTextVisible()) {
420 int startOffset = a.getStartNode().getOffset().intValue();
421 int endOffset = a.getEndNode().getOffset().intValue();
422 int tokenStartOffset = currentTokenAnnotation.getStartNode().getOffset().intValue();
423 int tokenEndOffset = currentTokenAnnotation.getEndNode().getOffset().intValue();
424 if (startOffset <= tokenStartOffset && tokenEndOffset <= endOffset && endOffset >= tokenStartOffset && withHighlighting) {
425 textPanel.setHighlighted(true);
426 }
427 }
428 }
429 }
430 if (ruleTrace != null && !ruleTrace.isFinished() && currentAnnotation.getStartNode().getOffset().longValue() >= lastNodeOffset
431 && !isRedSet && textPanel.isTextVisible() && withHighlighting) {
432 textPanel.setRed(true);
433 if (textPanel.getOpenMode() == PrimaryTextPanel.OPEN_NONE || textPanel.getOpenMode() == PrimaryTextPanel.OPEN_LEFT) {
434 isRedSet = true;
435 }
436 }
437
439 String toolTipText = "";
441 FeatureMap featureMap = null;
442 if (ruleTrace != null) {
443 featureMap = ruleTrace.getPattern(currentAnnotation);
444 }
445 if (featureMap == null && containedAnnotationsOfTheSameType != null) {
446 if (ruleTrace != null) {
447 for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
448 featureMap = ruleTrace.getPattern((Annotation) iterator.next());
449 if (featureMap != null)
450 break;
451 }
452 }
453 }
454 if (featureMap != null) {
455 for (Iterator i = featureMap.keySet().iterator(); i.hasNext();) {
456 toolTipText = toolTipText + " " + annotationsType + ".";
457 Object key = i.next();
458 toolTipText = toolTipText + key + "=" + featureMap.get(key);
459 }
460 if (featureMap.keySet().isEmpty()) {
461 toolTipText = annotationsType;
462 }
463 }
464 if (featureMap != null && textPanel.isTextVisible() && (textPanel.isHighlighted() || textPanel.isRed())
465 && withHighlighting) {
466 textPanel.setToolTipText(toolTipText);
467 }
468
470 c.gridx = x;
471 panel.add(textPanel, c);
472 order++;
473 x++;
474 }
475 }
476 }
477 return panel;
478 }
479
480
485 public void updateRulePanel(RuleModel ruleModel, RuleTrace currentTrace) {
486 if (ruleModel != null) {
487 rulePane.setText(ruleModel.getRuleText());
488 }
489 RuleTrace ruleTrace = null;
490 if (currentTrace == null && traceContainer != null) {
491 if (traceContainer != null) {
492 TraceContainer traces = traceContainer.getTraceByRuleModel(ruleModel);
493 if (traces.size() > 0) {
494 ruleTrace = (RuleTrace) traces.iterator().next();
495 }
496 previousAnnotationButton.setEnabled(false);
497 nextAnnotationButton.setEnabled(false);
498 if (traces.size() > 1) {
499 nextAnnotationButton.setEnabled(true);
500 }
501 currentTraces = traces;
502 currentRuleTrace = ruleTrace;
503 }
504 } else {
505 ruleTrace = currentTrace;
506 currentRuleTrace = ruleTrace;
507 }
508 if (traceContainer != null) {
509 currentAnnotationCut = traceContainer.getPhaseCut(currentPhaseModel);
510 JPanel panel = new JPanel();
511 panel.setLayout(new GridBagLayout());
512 GridBagConstraints c = new GridBagConstraints();
513 int i = 0;
514 c.anchor = GridBagConstraints.WEST;
515 c.insets = new Insets(2, 4, 2, 4);
516 if (currentPhaseModel != null) {
518 for (Iterator it = currentPhaseModel.getInput().iterator(); it.hasNext();) {
519 String input = (String) it.next();
520 c.fill = GridBagConstraints.NONE;
521 c.gridx = 0;
522 c.weightx = 0;
523 c.gridy = i++;
524 panel.add(new JLabel(input), c);
525 c.gridx = 1;
526 if (currentAnnotationCut != null) {
527 panel.add(createAnnotationPanel(currentAnnotationCut.get(input, new Long(currentStartOffset), new Long(currentEndOffset)), input, ruleTrace, true), c);
528 } else {
529 panel.add(new JLabel("No annotations of type " + input + " available"), c);
530 }
531 c.gridx = 2;
532 c.weightx = 1;
533 c.fill = GridBagConstraints.HORIZONTAL;
534 panel.add(new JPanel(), c);
535 }
536 }
537
539 c.gridx = 0;
541 c.gridy = i;
542 c.weightx = 0;
543 c.weighty = 0;
544 c.gridwidth = 2;
545 panel.add(new JPanel() {
546 {
547 this.setBackground(Color.black);
548 }
549
550 public Dimension getPreferredSize() {
551 return getMaximumSize();
552 }
553
554 public Dimension getMaximumSize() {
555 return new Dimension(20, 2);
556 }
557 },
558 c);
559 c.gridx = 1;
560 c.weightx = 1;
561 c.gridy = i++;
562 panel.add(new JPanel(), c);
563
565 c.fill = GridBagConstraints.NONE;
567 c.gridx = 0;
568 c.weightx = 0;
569 c.gridy = i++;
570 panel.add(new JLabel(""), c);
571 c.gridx = 1;
572 if (document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token") != null) {
573 if (currentAnnotationCut == null) {
574 currentAnnotationCut = document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token");
575 }
576 panel.add(createAnnotationPanel(document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token"), "Token", ruleTrace, false), c);
577 } else {
578 panel.add(new JLabel("No annotations of type Token available"), c);
579 }
580 c.gridx = 2;
581 c.weightx = 1;
582 c.fill = GridBagConstraints.HORIZONTAL;
583 panel.add(new JPanel(), c);
584
586 c.gridx = 0;
588 c.gridy = i++;
589 c.weightx = 0;
590 c.weighty = 1;
591 panel.add(new JPanel(), c);
592
593 getRulePanel().removeAll();
595 getRulePanel().setLayout(new BorderLayout());
596 getRulePanel().add(panel, BorderLayout.CENTER);
597 this.revalidate();
598
599 }
612 }
619
620
627 public void setCurrentRule(RuleModel ruleModel) {
628 currentRuleModel = ruleModel;
629 currentPhaseModel = ruleModel.getParentPhase();
630 phaseName.setText(currentPhaseModel.getName() + " Control = " + currentPhaseModel.getControl());
631 ruleName.setText(ruleModel.getName());
632 }
633
634
641 public void setCurrentPhase(PhaseModel phaseModel) {
642 currentPhaseModel = phaseModel;
643 phaseName.setText(currentPhaseModel.getName() + " Control = " + currentPhaseModel.getControl());
644 if (currentRuleModel != null && !currentRuleModel.getParentPhase().equals(currentPhaseModel)) {
645 getRulePanel().removeAll();
646 getRulePanel().add(new JLabel("No rule currently selected."));
647 }
648 ruleName.setText("");
649 }
650
651
655 public RuleTrace getCurrentRuleTrace() {
656 return currentRuleTrace;
657 }
658
659
663 public RuleModel getCurrentRuleModel() {
664 return currentRuleModel;
665 }
666 }
667