2010-10-26 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug309042
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / wizards / CustomTxtParserInputWizardPage.java
1 package org.eclipse.linuxtools.tmf.ui.wizards;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.text.ParseException;
7 import java.text.SimpleDateFormat;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Date;
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Scanner;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18 import java.util.regex.PatternSyntaxException;
19
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.jface.viewers.ColumnLabelProvider;
23 import org.eclipse.jface.viewers.ISelection;
24 import org.eclipse.jface.viewers.ISelectionChangedListener;
25 import org.eclipse.jface.viewers.IStructuredSelection;
26 import org.eclipse.jface.viewers.ITreeContentProvider;
27 import org.eclipse.jface.viewers.SelectionChangedEvent;
28 import org.eclipse.jface.viewers.StructuredSelection;
29 import org.eclipse.jface.viewers.TreeViewer;
30 import org.eclipse.jface.viewers.Viewer;
31 import org.eclipse.jface.wizard.WizardPage;
32 import org.eclipse.linuxtools.tmf.ui.TmfUiPlugin;
33 import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomTxtTraceDefinition;
34 import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomTxtTraceDefinition.Cardinality;
35 import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputData;
36 import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputLine;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.browser.Browser;
39 import org.eclipse.swt.browser.TitleEvent;
40 import org.eclipse.swt.browser.TitleListener;
41 import org.eclipse.swt.custom.SashForm;
42 import org.eclipse.swt.custom.ScrolledComposite;
43 import org.eclipse.swt.custom.StyleRange;
44 import org.eclipse.swt.custom.StyledText;
45 import org.eclipse.swt.events.ModifyEvent;
46 import org.eclipse.swt.events.ModifyListener;
47 import org.eclipse.swt.events.SelectionAdapter;
48 import org.eclipse.swt.events.SelectionEvent;
49 import org.eclipse.swt.events.SelectionListener;
50 import org.eclipse.swt.events.VerifyEvent;
51 import org.eclipse.swt.events.VerifyListener;
52 import org.eclipse.swt.graphics.Color;
53 import org.eclipse.swt.graphics.Font;
54 import org.eclipse.swt.graphics.FontData;
55 import org.eclipse.swt.graphics.Image;
56 import org.eclipse.swt.layout.FillLayout;
57 import org.eclipse.swt.layout.GridData;
58 import org.eclipse.swt.layout.GridLayout;
59 import org.eclipse.swt.widgets.Button;
60 import org.eclipse.swt.widgets.Combo;
61 import org.eclipse.swt.widgets.Composite;
62 import org.eclipse.swt.widgets.Display;
63 import org.eclipse.swt.widgets.Group;
64 import org.eclipse.swt.widgets.Label;
65 import org.eclipse.swt.widgets.Shell;
66 import org.eclipse.swt.widgets.Text;
67
68 public class CustomTxtParserInputWizardPage extends WizardPage {
69
70 private static final String DEFAULT_REGEX = "\\s*(.*\\S)";
71 private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
72 private static final String SIMPLE_DATE_FORMAT_URL = "http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#skip-navbar_top";
73 private static final String PATTERN_URL = "http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#sum";
74 private static final Image lineImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/line_icon.gif");
75 private static final Image addImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/add_button.gif");
76 private static final Image addNextImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/addnext_button.gif");
77 private static final Image addChildImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/addchild_button.gif");
78 private static final Image deleteImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/delete_button.gif");
79 private static final Image moveUpImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/moveup_button.gif");
80 private static final Image moveDownImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/movedown_button.gif");
81 private static final Image helpImage = TmfUiPlugin.getDefault().getImageFromPath("/icons/help_button.gif");
82 private static final Color COLOR_BLACK = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
83 private static final Color COLOR_LIGHT_GREEN = new Color(Display.getDefault(), 192, 255, 192);
84 private static final Color COLOR_GREEN = Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
85 private static final Color COLOR_LIGHT_YELLOW = new Color(Display.getDefault(), 255, 255, 192);
86 private static final Color COLOR_YELLOW = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
87 private static final Color COLOR_LIGHT_MAGENTA = new Color(Display.getDefault(), 255, 192, 255);
88 private static final Color COLOR_MAGENTA = Display.getCurrent().getSystemColor(SWT.COLOR_MAGENTA);
89 private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192);
90 private static final Color COLOR_TEXT_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
91 private static final Color COLOR_WIDGET_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
92
93 private ISelection selection;
94 private CustomTxtTraceDefinition definition;
95 private String editDefinitionName;
96 private String defaultDescription;
97 private Line selectedLine;
98 private Composite container;
99 private Text logtypeText;
100 private Text timestampOutputFormatText;
101 private Text timestampPreviewText;
102 private ScrolledComposite treeScrolledComposite;
103 private ScrolledComposite lineScrolledComposite;
104 private TreeViewer treeViewer;
105 private Composite treeContainer;
106 private Composite lineContainer;
107 @SuppressWarnings("unused")
108 private Group addLineGroup;
109 private StyledText inputText;
110 private Font fixedFont;
111 private UpdateListener updateListener;
112 private Browser helpBrowser;
113
114 // variables used recursively through line traversal
115 @SuppressWarnings("unused")
116 private String timeStampValue;
117 private String timeStampFormat;
118 private boolean timestampFound;
119
120 protected CustomTxtParserInputWizardPage(ISelection selection, CustomTxtTraceDefinition definition) {
121 super("CustomParserWizardPage");
122 if (definition == null) {
123 setTitle("New Custom Text Parser");
124 defaultDescription = "Create a new custom parser for text log files";
125 } else {
126 setTitle("Edit Custom Text Parser");
127 defaultDescription = "Edit an existing custom parser for text log files";
128 }
129 setDescription(defaultDescription);
130 this.selection = selection;
131 this.definition = definition;
132 if (definition != null) {
133 this.editDefinitionName = definition.definitionName;
134 }
135 }
136
137 @Override
138 public void createControl(Composite parent) {
139 container = new Composite(parent, SWT.NULL);
140 container.setLayout(new GridLayout());
141
142 updateListener = new UpdateListener();
143
144 Composite headerComposite = new Composite(container, SWT.FILL);
145 GridLayout headerLayout = new GridLayout(5, false);
146 headerLayout.marginHeight = 0;
147 headerLayout.marginWidth = 0;
148 headerComposite.setLayout(headerLayout);
149 headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
150
151 Label logtypeLabel = new Label(headerComposite, SWT.NULL);
152 logtypeLabel.setText("Log type:");
153
154 logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
155 logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT));
156 logtypeText.addModifyListener(updateListener);
157
158 Label timestampFormatLabel = new Label(headerComposite, SWT.NULL);
159 timestampFormatLabel.setText("Time Stamp format:");
160
161 timestampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
162 timestampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
163 timestampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT);
164 timestampOutputFormatText.addModifyListener(updateListener);
165
166 Button dateFormatHelpButton = new Button(headerComposite, SWT.PUSH);
167 dateFormatHelpButton.setImage(helpImage);
168 dateFormatHelpButton.setToolTipText("Date Format Help");
169 dateFormatHelpButton.addSelectionListener(new SelectionAdapter() {
170 @Override
171 public void widgetSelected(SelectionEvent e) {
172 openHelpShell(SIMPLE_DATE_FORMAT_URL);
173 }
174 });
175
176 Label timestampPreviewLabel = new Label(headerComposite, SWT.NULL);
177 timestampPreviewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1));
178 timestampPreviewLabel.setText("Preview:");
179
180 timestampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
181 timestampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
182 timestampPreviewText.setText("*no matching timestamp*");
183
184 Composite buttonBar = new Composite(container, SWT.NONE);
185 GridLayout buttonBarLayout = new GridLayout(5, false);
186 buttonBarLayout.marginHeight = 0;
187 buttonBarLayout.marginWidth = 0;
188 buttonBar.setLayout(buttonBarLayout);
189
190 Button removeButton = new Button(buttonBar, SWT.PUSH);
191 removeButton.setImage(deleteImage);
192 removeButton.setToolTipText("Remove line");
193 removeButton.addSelectionListener(new SelectionAdapter() {
194 @Override
195 public void widgetSelected(SelectionEvent e) {
196 if (treeViewer.getSelection().isEmpty() || selectedLine == null) return;
197 removeLine();
198 InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
199 if (inputLine.parentInput == null) {
200 definition.inputs.remove(inputLine);
201 } else {
202 inputLine.parentInput.childrenInputs.remove(inputLine);
203 }
204 treeViewer.refresh();
205 validate();
206 updatePreviews();
207 }
208 });
209 Button addNextButton = new Button(buttonBar, SWT.PUSH);
210 addNextButton.setImage(addNextImage);
211 addNextButton.setToolTipText("Add next line");
212 addNextButton.addSelectionListener(new SelectionAdapter() {
213 @Override
214 public void widgetSelected(SelectionEvent e) {
215 InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null);
216 if (((List<?>) treeViewer.getInput()).size() == 0) {
217 definition.inputs.add(inputLine);
218 } else if (treeViewer.getSelection().isEmpty()) {
219 return;
220 } else {
221 InputLine previousInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
222 if (previousInputLine.parentInput == null) {
223 for (int i = 0; i < definition.inputs.size(); i++) {
224 if (definition.inputs.get(i).equals(previousInputLine)) {
225 definition.inputs.add(i + 1, inputLine);
226 }
227 }
228 } else {
229 previousInputLine.addNext(inputLine);
230 }
231 }
232 treeViewer.refresh();
233 treeViewer.setSelection(new StructuredSelection(inputLine), true);
234 }
235 });
236 Button addChildButton = new Button(buttonBar, SWT.PUSH);
237 addChildButton.setImage(addChildImage);
238 addChildButton.setToolTipText("Add child line");
239 addChildButton.addSelectionListener(new SelectionAdapter() {
240 @Override
241 public void widgetSelected(SelectionEvent e) {
242 InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null);
243 if (((List<?>) treeViewer.getInput()).size() == 0) {
244 definition.inputs.add(inputLine);
245 } else if (treeViewer.getSelection().isEmpty()) {
246 return;
247 } else {
248 InputLine parentInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
249 parentInputLine.addChild(inputLine);
250 }
251 treeViewer.refresh();
252 treeViewer.setSelection(new StructuredSelection(inputLine), true);
253 }
254 });
255 Button moveUpButton = new Button(buttonBar, SWT.PUSH);
256 moveUpButton.setImage(moveUpImage);
257 moveUpButton.setToolTipText("Move up");
258 moveUpButton.addSelectionListener(new SelectionAdapter() {
259 @Override
260 public void widgetSelected(SelectionEvent e) {
261 if (treeViewer.getSelection().isEmpty()) return;
262 InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
263 if (inputLine.parentInput == null) {
264 for (int i = 1; i < definition.inputs.size(); i++) {
265 if (definition.inputs.get(i).equals(inputLine)) {
266 definition.inputs.add(i - 1 , definition.inputs.remove(i));
267 break;
268 }
269 }
270 } else {
271 inputLine.moveUp();
272 }
273 treeViewer.refresh();
274 validate();
275 updatePreviews();
276 }
277 });
278 Button moveDownButton = new Button(buttonBar, SWT.PUSH);
279 moveDownButton.setImage(moveDownImage);
280 moveDownButton.setToolTipText("Move down");
281 moveDownButton.addSelectionListener(new SelectionAdapter() {
282 @Override
283 public void widgetSelected(SelectionEvent e) {
284 if (treeViewer.getSelection().isEmpty()) return;
285 InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
286 if (inputLine.parentInput == null) {
287 for (int i = 0; i < definition.inputs.size() - 1; i++) {
288 if (definition.inputs.get(i).equals(inputLine)) {
289 definition.inputs.add(i + 1 , definition.inputs.remove(i));
290 break;
291 }
292 }
293 } else {
294 inputLine.moveDown();
295 }
296 treeViewer.refresh();
297 validate();
298 updatePreviews();
299 }
300 });
301
302 SashForm vSash = new SashForm(container, SWT.VERTICAL);
303 vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
304 vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
305
306 SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL);
307 hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
308
309 treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL);
310 GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
311 gd.heightHint = 200;
312 gd.widthHint = 200;
313 treeScrolledComposite.setLayoutData(gd);
314 treeContainer = new Composite(treeScrolledComposite, SWT.NONE);
315 treeContainer.setLayout(new FillLayout());
316 treeScrolledComposite.setContent(treeContainer);
317 treeScrolledComposite.setExpandHorizontal(true);
318 treeScrolledComposite.setExpandVertical(true);
319
320 treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER);
321 treeViewer.setContentProvider(new InputLineTreeNodeContentProvider());
322 treeViewer.setLabelProvider(new InputLineTreeLabelProvider());
323 treeViewer.addSelectionChangedListener(new InputLineTreeSelectionChangedListener());
324 treeContainer.layout();
325
326 treeScrolledComposite.setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
327
328 lineScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL);
329 lineScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
330 lineContainer = new Composite(lineScrolledComposite, SWT.NONE);
331 GridLayout linesLayout = new GridLayout();
332 linesLayout.marginHeight = 1;
333 linesLayout.marginWidth = 0;
334 lineContainer.setLayout(linesLayout);
335 lineScrolledComposite.setContent(lineContainer);
336 lineScrolledComposite.setExpandHorizontal(true);
337 lineScrolledComposite.setExpandVertical(true);
338
339 if (definition == null) {
340 definition = new CustomTxtTraceDefinition();
341 definition.inputs.add(new InputLine(Cardinality.ZERO_OR_MORE, DEFAULT_REGEX,
342 Arrays.asList(new InputData(CustomTxtTraceDefinition.TAG_MESSAGE, CustomTxtTraceDefinition.ACTION_SET))));
343 }
344 loadDefinition(definition);
345 treeViewer.expandAll();
346 lineContainer.layout();
347
348 lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
349
350 hSash.setWeights(new int[] {1, 2});
351
352 Composite sashBottom = new Composite(vSash, SWT.NONE);
353 GridLayout sashBottomLayout = new GridLayout(3, false);
354 sashBottomLayout.marginHeight = 0;
355 sashBottomLayout.marginWidth = 0;
356 sashBottom.setLayout(sashBottomLayout);
357
358 Label previewLabel = new Label(sashBottom, SWT.NULL);
359 previewLabel.setText("Preview input");
360 previewLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
361
362 Button highlightAllButton = new Button(sashBottom, SWT.PUSH);
363 highlightAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
364 highlightAllButton.setText("Highlight All");
365 highlightAllButton.addSelectionListener(new SelectionAdapter() {
366 @Override
367 public void widgetSelected(SelectionEvent e) {
368 updatePreviews(true);
369 }
370 });
371
372 Button legendButton = new Button(sashBottom, SWT.PUSH);
373 legendButton.setImage(helpImage);
374 legendButton.setToolTipText("Preview Legend");
375 legendButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
376 legendButton.addSelectionListener(new SelectionAdapter() {
377 @Override
378 public void widgetSelected(SelectionEvent e) {
379 openLegend();
380 }
381 });
382
383 inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
384 if (fixedFont == null) {
385 if (System.getProperty("os.name").contains("Windows")) {
386 fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL));
387 } else {
388 fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL));
389 }
390 }
391 inputText.setFont(fixedFont);
392 gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
393 gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y;
394 gd.widthHint = 800;
395 inputText.setLayoutData(gd);
396 inputText.setText(getSelectionText());
397 inputText.addModifyListener(updateListener);
398
399 vSash.setWeights(new int[] {hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y});
400
401 setControl(container);
402
403 validate();
404 updatePreviews();
405 }
406
407 private class InputLineTreeNodeContentProvider implements ITreeContentProvider {
408
409 @Override
410 public Object[] getElements(Object inputElement) {
411 return ((List<?>) inputElement).toArray();
412 }
413
414 @Override
415 public Object[] getChildren(Object parentElement) {
416 InputLine inputLine = (InputLine) parentElement;
417 if (inputLine.childrenInputs == null) return new InputLine[0];
418 return inputLine.childrenInputs.toArray();
419 }
420
421 @Override
422 public boolean hasChildren(Object element) {
423 InputLine inputLine = (InputLine) element;
424 return (inputLine.childrenInputs != null && inputLine.childrenInputs.size() > 0);
425 }
426
427 @Override
428 public void dispose() {
429 }
430
431 @Override
432 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
433 }
434
435 @Override
436 public Object getParent(Object element) {
437 InputLine inputLine = (InputLine) element;
438 return inputLine.parentInput;
439 }
440 }
441
442 private class InputLineTreeLabelProvider extends ColumnLabelProvider {
443
444 @Override
445 public Image getImage(Object element) {
446 return lineImage;
447 }
448
449 @Override
450 public String getText(Object element) {
451 InputLine inputLine = (InputLine) element;
452 if (inputLine.parentInput == null) {
453 return "Root Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex();
454 } else {
455 return "Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex();
456 }
457 }
458 }
459
460 private class InputLineTreeSelectionChangedListener implements ISelectionChangedListener {
461 @Override
462 public void selectionChanged(SelectionChangedEvent event) {
463 if (selectedLine != null) {
464 selectedLine.dispose();
465 }
466 if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) {
467 IStructuredSelection selection = (IStructuredSelection) event.getSelection();
468 InputLine inputLine = (InputLine) selection.getFirstElement();
469 selectedLine = new Line(lineContainer, getName(inputLine), inputLine);
470 lineContainer.layout();
471 lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
472 container.layout();
473 validate();
474 updatePreviews();
475 }
476 }
477 }
478
479 /* (non-Javadoc)
480 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
481 */
482 @Override
483 public void dispose() {
484 if (fixedFont != null) {
485 fixedFont.dispose();
486 fixedFont = null;
487 }
488 super.dispose();
489 }
490
491 private void loadDefinition(CustomTxtTraceDefinition def) {
492 logtypeText.setText(def.definitionName);
493 timestampOutputFormatText.setText(def.timeStampOutputFormat);
494 treeViewer.setInput(def.inputs);
495 if (def.inputs.size() > 0) {
496 InputLine inputLine = def.inputs.get(0);
497 treeViewer.setSelection(new StructuredSelection(inputLine));
498 }
499 }
500
501 private String getName(InputLine inputLine) {
502 if (inputLine.parentInput == null) {
503 return Integer.toString(definition.inputs.indexOf(inputLine)+1);
504 }
505 return getName(inputLine.parentInput) + "." + Integer.toString(inputLine.parentInput.childrenInputs.indexOf(inputLine)+1);
506 }
507
508 public List<String> getInputNames() {
509 List<String> inputs = new ArrayList<String>();
510 for (InputLine inputLine : definition.inputs) {
511 for (String inputName : getInputNames(inputLine)) {
512 if (!inputs.contains(inputName)) {
513 inputs.add(inputName);
514 }
515 }
516 }
517 return inputs;
518 }
519
520 public List<String> getInputNames(InputLine inputLine) {
521 List<String> inputs = new ArrayList<String>();
522 if (inputLine.columns != null) {
523 for (InputData inputData : inputLine.columns) {
524 String inputName = inputData.name;
525 if (!inputs.contains(inputName)) {
526 inputs.add(inputName);
527 }
528 }
529 }
530 if (inputLine.childrenInputs != null) {
531 for (InputLine childInputLine : inputLine.childrenInputs) {
532 for (String inputName : getInputNames(childInputLine)) {
533 if (!inputs.contains(inputName)) {
534 inputs.add(inputName);
535 }
536 }
537 }
538 }
539 return inputs;
540 }
541
542 private void removeLine() {
543 selectedLine.dispose();
544 selectedLine = null;
545 lineContainer.layout();
546 lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
547 container.layout();
548 }
549
550 // private void removeAddLineButton() {
551 // addLineGroup.dispose();
552 // }
553
554 private String getSelectionText() {
555 if (this.selection instanceof IStructuredSelection) {
556 Object selection = ((IStructuredSelection)this.selection).getFirstElement();
557 if (selection instanceof IFile) {
558 IFile file = (IFile)selection;
559 try {
560 BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()));
561 StringBuilder sb = new StringBuilder();
562 String line = null;
563 while ((line = reader.readLine()) != null) {
564 sb.append(line + "\n");
565 }
566 return sb.toString();
567 } catch (CoreException e) {
568 return "";
569 } catch (IOException e) {
570 return "";
571 }
572 }
573 }
574 return "";
575 }
576
577 private void updatePreviews() {
578 updatePreviews(false);
579 }
580
581 private void updatePreviews(boolean updateAll) {
582 if (inputText == null) {
583 // early update during construction
584 return;
585 }
586 inputText.setStyleRanges(new StyleRange[] {});
587
588 Scanner scanner = new Scanner(inputText.getText());
589 scanner.useDelimiter("\n");
590 int rawPos = 0;
591 String skip; // skip starting delimiters
592 if ((skip = scanner.findWithinHorizon("\\A\n+", 0)) != null) {
593 rawPos += skip.length();
594 }
595
596 timeStampFormat = null;
597 if (selectedLine != null) {
598 for (InputGroup input : selectedLine.inputs) {
599 input.previewText.setText("*no matching line*");
600 }
601 }
602
603 Map<String, String> data = new HashMap<String, String>();
604 int rootLineMatches = 0;
605 String firstEntryTimeStamp = null;
606 String firstEntryTimeStampInputFormat = null;
607 String log = null;
608 event:
609 while (log != null || scanner.hasNext()) {
610 if (rootLineMatches > 0 && !updateAll) {
611 break;
612 }
613 if (log == null) {
614 log = scanner.next();
615 }
616 int length = log.length();
617 for (InputLine rootInputLine : definition.inputs) {
618 Pattern pattern;
619 try {
620 pattern = rootInputLine.getPattern();
621 } catch (PatternSyntaxException e) {
622 continue;
623 }
624 Matcher matcher = pattern.matcher(log);
625 if (matcher.find()) {
626 rootLineMatches++;
627 inputText.setStyleRange(new StyleRange(rawPos, length,
628 COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
629 data = new HashMap<String, String>();
630 timeStampFormat = null;
631 updatePreviewLine(rootInputLine, matcher, data, rawPos, rootLineMatches);
632 if (rootLineMatches == 1) {
633 firstEntryTimeStamp = data.get(CustomTxtTraceDefinition.TAG_TIMESTAMP);
634 firstEntryTimeStampInputFormat = timeStampFormat;
635 }
636 HashMap<InputLine, Integer> countMap = new HashMap<InputLine, Integer>();
637 InputLine currentInput = null;
638 if (rootInputLine.childrenInputs != null && rootInputLine.childrenInputs.size() > 0) {
639 currentInput = rootInputLine.childrenInputs.get(0);
640 countMap.put(currentInput, 0);
641 }
642 rawPos += length + 1; // +1 for \n
643 while (scanner.hasNext()) {
644 log = scanner.next();
645 length = log.length();
646 boolean processed = false;
647 if (currentInput == null) {
648 for (InputLine input : definition.inputs) {
649 matcher = input.getPattern().matcher(log);
650 if (matcher.find()) {
651 continue event;
652 }
653 }
654 } else {
655 if (countMap.get(currentInput) >= currentInput.getMinCount()) {
656 List<InputLine> nextInputs = currentInput.getNextInputs(countMap);
657 if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) {
658 for (InputLine input : definition.inputs) {
659 matcher = input.getPattern().matcher(log);
660 if (matcher.find()) {
661 continue event;
662 }
663 }
664 }
665 for (InputLine input : nextInputs) {
666 matcher = input.getPattern().matcher(log);
667 if (matcher.find()) {
668 inputText.setStyleRange(new StyleRange(rawPos, length,
669 COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
670 currentInput = input;
671 updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);
672 if (countMap.get(currentInput) == null) {
673 countMap.put(currentInput, 1);
674 } else {
675 countMap.put(currentInput, countMap.get(currentInput) + 1);
676 }
677 Iterator<InputLine> iter = countMap.keySet().iterator();
678 while (iter.hasNext()) {
679 InputLine inputLine = iter.next();
680 if (inputLine.level > currentInput.level) {
681 iter.remove();
682 }
683 }
684 if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
685 currentInput = currentInput.childrenInputs.get(0);
686 countMap.put(currentInput, 0);
687 } else {
688 if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
689 if (currentInput.getNextInputs(countMap).size() > 0) {
690 currentInput = currentInput.getNextInputs(countMap).get(0);
691 if (countMap.get(currentInput) == null) {
692 countMap.put(currentInput, 0);
693 }
694 iter = countMap.keySet().iterator();
695 while (iter.hasNext()) {
696 InputLine inputLine = iter.next();
697 if (inputLine.level > currentInput.level) {
698 iter.remove();
699 }
700 }
701 } else {
702 currentInput = null;
703 }
704 }
705 }
706 processed = true;
707 break;
708 }
709 }
710 }
711 if (! processed) {
712 matcher = currentInput.getPattern().matcher(log);
713 if (matcher.find()) {
714 inputText.setStyleRange(new StyleRange(rawPos, length,
715 COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
716 updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);
717 countMap.put(currentInput, countMap.get(currentInput) + 1);
718 if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
719 currentInput = currentInput.childrenInputs.get(0);
720 countMap.put(currentInput, 0);
721 } else {
722 if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
723 if (currentInput.getNextInputs(countMap).size() > 0) {
724 currentInput = currentInput.getNextInputs(countMap).get(0);
725 if (countMap.get(currentInput) == null) {
726 countMap.put(currentInput, 0);
727 }
728 Iterator<InputLine> iter = countMap.keySet().iterator();
729 while (iter.hasNext()) {
730 InputLine inputLine = iter.next();
731 if (inputLine.level > currentInput.level) {
732 iter.remove();
733 }
734 }
735 } else {
736 currentInput = null;
737 }
738 }
739 }
740 }
741 }
742 }
743 rawPos += length + 1; // +1 for \n
744 }
745
746 break;
747 }
748 }
749 rawPos += length + 1; // +1 for \n
750 log = null;
751 }
752 scanner.close();
753 if (rootLineMatches == 1) {
754 firstEntryTimeStamp = data.get(CustomTxtTraceDefinition.TAG_TIMESTAMP);
755 firstEntryTimeStampInputFormat = timeStampFormat;
756 }
757 if (firstEntryTimeStamp == null) {
758 timestampPreviewText.setText("*no timestamp group*");
759 if (selectedLine != null) {
760 for (InputGroup group : selectedLine.inputs) {
761 if (group.tagCombo.getText().equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
762 timestampPreviewText.setText("*no matching timestamp*");
763 break;
764 }
765 }
766 }
767 } else {
768 try {
769 SimpleDateFormat dateFormat = new SimpleDateFormat(firstEntryTimeStampInputFormat);
770 Date date = dateFormat.parse(firstEntryTimeStamp);
771 dateFormat = new SimpleDateFormat(timestampOutputFormatText.getText().trim());
772 timestampPreviewText.setText(dateFormat.format(date));
773 } catch (ParseException e) {
774 timestampPreviewText.setText("*parse exception* [" + firstEntryTimeStamp + "] <> [" + firstEntryTimeStampInputFormat + "]");
775 } catch (IllegalArgumentException e) {
776 timestampPreviewText.setText("*parse exception* [Illegal Argument]");
777 }
778
779 }
780 }
781
782 private void updatePreviewLine(InputLine line, Matcher matcher, Map<String, String> data, int rawPos, int rootLineMatches) {
783 for (int i = 0; i < line.columns.size(); i++) {
784 InputData input = line.columns.get(i);
785 if (i < matcher.groupCount() && matcher.group(i+1) != null) {
786 if (line.parentInput == null) {
787 inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
788 COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
789 } else {
790 inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
791 COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
792 }
793 String value = matcher.group(i+1).trim();
794 if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {
795 if (selectedLine.inputs.get(i).previewText.getText().equals("*no matching line*")) {
796 selectedLine.inputs.get(i).previewText.setText(value);
797 }
798 }
799 if (value.length() == 0) {
800 continue;
801 }
802 if (input.action == CustomTxtTraceDefinition.ACTION_SET) {
803 data.put(input.name, value);
804 if (input.name.equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
805 timeStampFormat = input.format;
806 }
807 } else if (input.action == CustomTxtTraceDefinition.ACTION_APPEND) {
808 String s = data.get(input.name);
809 if (s != null) {
810 data.put(input.name, s + value);
811 } else {
812 data.put(input.name, value);
813 }
814 if (input.name.equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
815 if (timeStampFormat != null) {
816 timeStampFormat += input.format;
817 } else {
818 timeStampFormat = input.format;
819 }
820 }
821 } else if (input.action == CustomTxtTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) {
822 String s = data.get(input.name);
823 if (s != null) {
824 data.put(input.name, s + " | " + value);
825 } else {
826 data.put(input.name, value);
827 }
828 if (input.name.equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
829 if (timeStampFormat != null) {
830 timeStampFormat += " | " + input.format;
831 } else {
832 timeStampFormat = input.format;
833 }
834 }
835 }
836 } else {
837 if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {
838 if (selectedLine.inputs.get(i).previewText.getText().equals("*no matching line*")) {
839 selectedLine.inputs.get(i).previewText.setText("*no matching group*");
840 }
841 }
842 }
843 }
844 // highlight the matching groups that have no corresponponding input
845 for (int i = line.columns.size(); i < matcher.groupCount(); i++) {
846 if (matcher.group(i+1) != null) {
847 if (line.parentInput == null) {
848 inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
849 COLOR_BLACK, COLOR_MAGENTA));
850 } else {
851 inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
852 COLOR_BLACK, COLOR_LIGHT_MAGENTA));
853 }
854 }
855 }
856 }
857
858 private void openHelpShell(String url) {
859 if (helpBrowser != null && !helpBrowser.isDisposed()) {
860 helpBrowser.getShell().setActive();
861 if (!helpBrowser.getUrl().equals(url)) {
862 helpBrowser.setUrl(url);
863 }
864 return;
865 }
866 final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM);
867 helpShell.setLayout(new FillLayout());
868 helpBrowser = new Browser(helpShell, SWT.NONE);
869 helpBrowser.addTitleListener(new TitleListener() {
870 @Override
871 public void changed(TitleEvent event) {
872 helpShell.setText(event.title);
873 }
874 });
875 helpBrowser.setBounds(0,0,600,400);
876 helpShell.pack();
877 helpShell.open();
878 helpBrowser.setUrl(url);
879 }
880
881 private void openLegend() {
882 final String CG = "Captured group";
883 final String UCG = "Unidentified captured group";
884 final String UT = "Uncaptured text";
885 int line1start = 0;
886 String line1 = "Non-matching line\n";
887 int line2start = line1start + line1.length();
888 String line2 = "Matching root line : "+CG+" "+UCG+" "+UT+" \n";
889 int line3start = line2start + line2.length();
890 String line3 = "Matching other line: "+CG+" "+UCG+" "+UT+" \n";
891 int line4start = line3start + line3.length();
892 String line4 = "Matching other line: "+CG+" "+UCG+" "+UT+" \n";
893 int line5start = line4start + line4.length();
894 String line5 = "Non-matching line\n";
895 int line6start = line5start + line5.length();
896 String line6 = "Matching root line : "+CG+" "+UCG+" "+UT+" \n";
897
898 final Shell legendShell = new Shell(getShell(), SWT.DIALOG_TRIM);
899 legendShell.setLayout(new FillLayout());
900 StyledText legendText = new StyledText(legendShell, SWT.MULTI);
901 legendText.setFont(fixedFont);
902 legendText.setText(line1 + line2 + line3 + line4 + line5 + line6);
903 legendText.setStyleRange(new StyleRange(line2start, line2.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
904 legendText.setStyleRange(new StyleRange(line3start, line3.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
905 legendText.setStyleRange(new StyleRange(line4start, line4.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
906 legendText.setStyleRange(new StyleRange(line6start, line6.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
907 legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
908 legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));
909 legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
910 legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));
911 legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
912 legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));
913 legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
914 legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));
915 legendShell.setText("Preview Legend");
916 legendShell.pack();
917 legendShell.open();
918 }
919
920 private class UpdateListener implements ModifyListener, SelectionListener {
921
922 @Override
923 public void modifyText(ModifyEvent e) {
924 validate();
925 updatePreviews();
926 }
927
928 @Override
929 public void widgetDefaultSelected(SelectionEvent e) {
930 validate();
931 updatePreviews();
932 }
933
934 @Override
935 public void widgetSelected(SelectionEvent e) {
936 validate();
937 updatePreviews();
938 }
939
940 }
941
942 private class Line {
943 private static final String INFINITY_STRING = "\u221E";
944 @SuppressWarnings("unused")
945 String name;
946 InputLine inputLine;
947 Group group;
948 Composite labelComposite;
949 Text regexText;
950 Composite cardinalityContainer;
951 Combo cardinalityCombo;
952 Label cardinalityMinLabel;
953 Text cardinalityMinText;
954 Label cardinalityMaxLabel;
955 Text cardinalityMaxText;
956 Button infiniteButton;
957 ArrayList<InputGroup> inputs = new ArrayList<InputGroup>();
958 Button addGroupButton;
959 Label addGroupLabel;
960
961 public Line(Composite parent, String name, InputLine inputLine) {
962 this.name = name;
963 this.inputLine = inputLine;
964
965 group = new Group(parent, SWT.NONE);
966 group.setText(name);
967 group.setLayout(new GridLayout(2, false));
968 group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
969
970 labelComposite = new Composite(group, SWT.FILL);
971 GridLayout labelLayout = new GridLayout(1, false);
972 labelLayout.marginWidth = 0;
973 labelLayout.marginHeight = 0;
974 labelComposite.setLayout(labelLayout);
975 labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
976
977 Label label = new Label(labelComposite, SWT.NULL);
978 label.setText("Regular expression:");
979
980 Composite regexContainer = new Composite(group, SWT.NONE);
981 GridLayout regexLayout = new GridLayout(2, false);
982 regexLayout.marginHeight = 0;
983 regexLayout.marginWidth = 0;
984 regexContainer.setLayout(regexLayout);
985 regexContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
986
987 regexText = new Text(regexContainer, SWT.BORDER | SWT.SINGLE);
988 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
989 gd.widthHint = 0;
990 regexText.setLayoutData(gd);
991 regexText.setText(inputLine.getRegex());
992 regexText.addModifyListener(updateListener);
993
994 Button regexHelpButton = new Button(regexContainer, SWT.PUSH);
995 regexHelpButton.setImage(helpImage);
996 regexHelpButton.setToolTipText("Regular Expression Help");
997 regexHelpButton.addSelectionListener(new SelectionAdapter() {
998 @Override
999 public void widgetSelected(SelectionEvent e) {
1000 openHelpShell(PATTERN_URL);
1001 }
1002 });
1003
1004 label = new Label(group, SWT.NONE);
1005 label.setText("Cardinality:");
1006 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1007
1008 cardinalityContainer = new Composite(group, SWT.NONE);
1009 GridLayout cardinalityLayout = new GridLayout(6, false);
1010 cardinalityLayout.marginHeight = 0;
1011 cardinalityLayout.marginWidth = 0;
1012 cardinalityContainer.setLayout(cardinalityLayout);
1013 cardinalityContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1014
1015 cardinalityCombo = new Combo(cardinalityContainer, SWT.DROP_DOWN | SWT.READ_ONLY);
1016 cardinalityCombo.setItems(new String[] {
1017 Cardinality.ZERO_OR_MORE.toString(),
1018 Cardinality.ONE_OR_MORE.toString(),
1019 Cardinality.ZERO_OR_ONE.toString(),
1020 Cardinality.ONE.toString(),
1021 "(?,?)"});
1022 cardinalityCombo.addSelectionListener(new SelectionListener(){
1023 @Override
1024 public void widgetDefaultSelected(SelectionEvent e) {}
1025 @Override
1026 public void widgetSelected(SelectionEvent e) {
1027 switch (cardinalityCombo.getSelectionIndex()) {
1028 case 4: //(?,?)
1029 cardinalityMinLabel.setVisible(true);
1030 cardinalityMinText.setVisible(true);
1031 cardinalityMaxLabel.setVisible(true);
1032 cardinalityMaxText.setVisible(true);
1033 infiniteButton.setVisible(true);
1034 break;
1035 default:
1036 cardinalityMinLabel.setVisible(false);
1037 cardinalityMinText.setVisible(false);
1038 cardinalityMaxLabel.setVisible(false);
1039 cardinalityMaxText.setVisible(false);
1040 infiniteButton.setVisible(false);
1041 break;
1042 }
1043 cardinalityContainer.layout();
1044 validate();
1045 updatePreviews();
1046 }});
1047
1048 cardinalityMinLabel = new Label(cardinalityContainer, SWT.NONE);
1049 cardinalityMinLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1050 cardinalityMinLabel.setText("min:");
1051 cardinalityMinLabel.setVisible(false);
1052
1053 cardinalityMinText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);
1054 gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
1055 gd.widthHint = 20;
1056 cardinalityMinText.setLayoutData(gd);
1057 cardinalityMinText.setVisible(false);
1058
1059 cardinalityMaxLabel = new Label(cardinalityContainer, SWT.NONE);
1060 cardinalityMaxLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1061 cardinalityMaxLabel.setText("max:");
1062 cardinalityMaxLabel.setVisible(false);
1063
1064 cardinalityMaxText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);
1065 gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
1066 gd.widthHint = 20;
1067 cardinalityMaxText.setLayoutData(gd);
1068 cardinalityMaxText.setVisible(false);
1069
1070 infiniteButton = new Button(cardinalityContainer, SWT.PUSH);
1071 infiniteButton.setText(INFINITY_STRING);
1072 infiniteButton.setVisible(false);
1073 infiniteButton.addSelectionListener(new SelectionAdapter(){
1074 @Override
1075 public void widgetSelected(SelectionEvent e) {
1076 cardinalityMaxText.setText(INFINITY_STRING);
1077 }});
1078
1079 if (inputLine.cardinality.equals(Cardinality.ZERO_OR_MORE)) {
1080 cardinalityCombo.select(0);
1081 } else if (inputLine.cardinality.equals(Cardinality.ONE_OR_MORE)) {
1082 cardinalityCombo.select(1);
1083 } else if (inputLine.cardinality.equals(Cardinality.ZERO_OR_ONE)) {
1084 cardinalityCombo.select(2);
1085 } else if (inputLine.cardinality.equals(Cardinality.ONE)) {
1086 cardinalityCombo.select(3);
1087 } else {
1088 cardinalityCombo.select(4);
1089 cardinalityMinLabel.setVisible(true);
1090 cardinalityMinText.setVisible(true);
1091 if (inputLine.getMinCount() >= 0) {
1092 cardinalityMinText.setText(Integer.toString(inputLine.getMinCount()));
1093 }
1094 cardinalityMaxLabel.setVisible(true);
1095 cardinalityMaxText.setVisible(true);
1096 if (inputLine.getMaxCount() == Cardinality.INF) {
1097 cardinalityMaxText.setText(INFINITY_STRING);
1098 } else if (inputLine.getMaxCount() >= 0) {
1099 cardinalityMaxText.setText(Integer.toString(inputLine.getMaxCount()));
1100 }
1101 infiniteButton.setVisible(true);
1102 }
1103
1104 VerifyListener digitsListener = new VerifyListener() {
1105 @Override
1106 public void verifyText(VerifyEvent e) {
1107 if (e.text.equals(INFINITY_STRING)) {
1108 e.doit = e.widget == cardinalityMaxText && e.start == 0 && e.end == ((Text) e.widget).getText().length();
1109 } else {
1110 if (((Text) e.widget).getText().equals(INFINITY_STRING)) {
1111 e.doit = e.start == 0 && e.end == ((Text) e.widget).getText().length();
1112 }
1113 for (int i = 0; i < e.text.length(); i++) {
1114 if (!Character.isDigit(e.text.charAt(i))) {
1115 e.doit = false;
1116 break;
1117 }
1118 }
1119 }
1120 }};
1121
1122 cardinalityMinText.addModifyListener(updateListener);
1123 cardinalityMaxText.addModifyListener(updateListener);
1124 cardinalityMinText.addVerifyListener(digitsListener);
1125 cardinalityMaxText.addVerifyListener(digitsListener);
1126
1127 if (inputLine.columns != null) {
1128 for (InputData inputData : inputLine.columns) {
1129 InputGroup inputGroup = new InputGroup(group, this, inputs.size()+1);
1130 if (inputData.name.equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
1131 inputGroup.tagCombo.select(0);
1132 inputGroup.tagText.setText(inputData.format);
1133 inputGroup.tagLabel.setText("format:");
1134 inputGroup.tagLabel.setVisible(true);
1135 inputGroup.tagText.setVisible(true);
1136 inputGroup.tagText.addModifyListener(updateListener);
1137 } else if (inputData.name.equals(CustomTxtTraceDefinition.TAG_MESSAGE)) {
1138 inputGroup.tagCombo.select(1);
1139 } else {
1140 inputGroup.tagCombo.select(2);
1141 inputGroup.tagText.setText(inputData.name);
1142 inputGroup.tagLabel.setText("name:");
1143 inputGroup.tagLabel.setVisible(true);
1144 inputGroup.tagText.setVisible(true);
1145 inputGroup.tagText.addModifyListener(updateListener);
1146 }
1147 inputGroup.actionCombo.select(inputData.action);
1148 inputs.add(inputGroup);
1149 }
1150 }
1151
1152 createAddGroupButton();
1153 }
1154
1155 private void createAddGroupButton() {
1156 addGroupButton = new Button(group, SWT.PUSH);
1157 addGroupButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1158 addGroupButton.setImage(addImage);
1159 addGroupButton.setToolTipText("Add group");
1160 addGroupButton.addSelectionListener(new SelectionAdapter() {
1161 @Override
1162 public void widgetSelected(SelectionEvent e) {
1163 removeAddGroupButton();
1164 inputs.add(new InputGroup(group, Line.this, inputs.size()+1));
1165 createAddGroupButton();
1166 lineContainer.layout();
1167 lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
1168 group.getParent().layout();
1169 validate();
1170 updatePreviews();
1171 }
1172 });
1173
1174 addGroupLabel = new Label(group, SWT.NULL);
1175 addGroupLabel.setText("New group");
1176 }
1177
1178 private void removeAddGroupButton() {
1179 addGroupButton.dispose();
1180 addGroupLabel.dispose();
1181 }
1182
1183 private void removeInput(int inputNumber) {
1184 if (--inputNumber < inputs.size()) {
1185 inputs.remove(inputNumber).dispose();
1186 for (int i = inputNumber; i < inputs.size(); i++) {
1187 inputs.get(i).setInputNumber(i+1);
1188 }
1189 lineContainer.layout();
1190 lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
1191 group.getParent().layout();
1192 }
1193 }
1194
1195 // private void setName(String name) {
1196 // this.name = name;
1197 // group.setText("Line " + name);
1198 // }
1199
1200 private void dispose() {
1201 group.dispose();
1202 }
1203
1204 private void extractInputs() {
1205 inputLine.setRegex(selectedLine.regexText.getText());
1206 switch (cardinalityCombo.getSelectionIndex()) {
1207 case 0:
1208 inputLine.cardinality = Cardinality.ZERO_OR_MORE;
1209 break;
1210 case 1:
1211 inputLine.cardinality = Cardinality.ONE_OR_MORE;
1212 break;
1213 case 2:
1214 inputLine.cardinality = Cardinality.ZERO_OR_ONE;
1215 break;
1216 case 3:
1217 inputLine.cardinality = Cardinality.ONE;
1218 break;
1219 case 4: //(?,?)
1220 int min, max;
1221 try {
1222 min = Integer.parseInt(cardinalityMinText.getText());
1223 } catch (NumberFormatException e) {
1224 min = -1;
1225 }
1226 try {
1227 if (cardinalityMaxText.getText().equals(INFINITY_STRING)) {
1228 max = Cardinality.INF;
1229 } else {
1230 max = Integer.parseInt(cardinalityMaxText.getText());
1231 }
1232 } catch (NumberFormatException e) {
1233 max = -1;
1234 }
1235 inputLine.cardinality = new Cardinality(min, max);
1236 break;
1237 default:
1238 inputLine.cardinality = Cardinality.ZERO_OR_MORE;
1239 break;
1240 }
1241 inputLine.columns = new ArrayList<InputData>(inputs.size());
1242 for (int i = 0; i < inputs.size(); i++) {
1243 InputGroup group = inputs.get(i);
1244 InputData inputData = new InputData();
1245 if (group.tagCombo.getText().equals(CustomTxtTraceDefinition.TAG_OTHER)) {
1246 inputData.name = group.tagText.getText().trim();
1247 } else {
1248 inputData.name = group.tagCombo.getText();
1249 if (group.tagCombo.getText().equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
1250 inputData.format = group.tagText.getText().trim();
1251 }
1252 }
1253 inputData.action = group.actionCombo.getSelectionIndex();
1254 inputLine.columns.add(inputData);
1255 }
1256 }
1257 }
1258
1259 private class InputGroup {
1260 Line line;
1261 int inputNumber;
1262
1263 // children of parent (must be disposed)
1264 Composite labelComposite;
1265 Composite tagComposite;
1266 Label previewLabel;
1267 Text previewText;
1268
1269 // children of labelComposite
1270 Label inputLabel;
1271
1272 // children of tagComposite
1273 Combo tagCombo;
1274 Label tagLabel;
1275 Text tagText;
1276 Combo actionCombo;
1277
1278 public InputGroup(Composite parent, Line line, int inputNumber) {
1279 this.line = line;
1280 this.inputNumber = inputNumber;
1281
1282 labelComposite = new Composite(parent, SWT.FILL);
1283 GridLayout labelLayout = new GridLayout(2, false);
1284 labelLayout.marginWidth = 0;
1285 labelLayout.marginHeight = 0;
1286 labelComposite.setLayout(labelLayout);
1287 labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1288
1289 Button deleteButton = new Button(labelComposite, SWT.PUSH);
1290 deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1291 deleteButton.setImage(deleteImage);
1292 deleteButton.setToolTipText("Remove group");
1293 deleteButton.addSelectionListener(new SelectionAdapter() {
1294 @Override
1295 public void widgetSelected(SelectionEvent e) {
1296 InputGroup.this.line.removeInput(InputGroup.this.inputNumber);
1297 validate();
1298 updatePreviews();
1299 }
1300 });
1301
1302 inputLabel = new Label(labelComposite, SWT.NULL);
1303 inputLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1304 inputLabel.setText("Group " + inputNumber + ":");
1305
1306 tagComposite = new Composite(parent, SWT.FILL);
1307 GridLayout tagLayout = new GridLayout(4, false);
1308 tagLayout.marginWidth = 0;
1309 tagLayout.marginHeight = 0;
1310 tagComposite.setLayout(tagLayout);
1311 tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1312
1313 tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
1314 tagCombo.setItems(new String[] {CustomTxtTraceDefinition.TAG_TIMESTAMP,
1315 CustomTxtTraceDefinition.TAG_MESSAGE,
1316 CustomTxtTraceDefinition.TAG_OTHER});
1317 tagCombo.select(1);
1318 tagCombo.addSelectionListener(new SelectionListener(){
1319 @Override
1320 public void widgetDefaultSelected(SelectionEvent e) {}
1321 @Override
1322 public void widgetSelected(SelectionEvent e) {
1323 tagText.removeModifyListener(updateListener);
1324 switch (tagCombo.getSelectionIndex()) {
1325 case 0: //Time Stamp
1326 tagLabel.setText("format:");
1327 tagLabel.setVisible(true);
1328 tagText.setVisible(true);
1329 tagText.addModifyListener(updateListener);
1330 break;
1331 case 1: //Message
1332 tagLabel.setVisible(false);
1333 tagText.setVisible(false);
1334 break;
1335 case 2: //Other
1336 tagLabel.setText("name:");
1337 tagLabel.setVisible(true);
1338 tagText.setVisible(true);
1339 tagText.addModifyListener(updateListener);
1340 break;
1341 case 3: //Continue
1342 tagLabel.setVisible(false);
1343 tagText.setVisible(false);
1344 break;
1345 }
1346 tagComposite.layout();
1347 validate();
1348 updatePreviews();
1349 }});
1350
1351 tagLabel = new Label(tagComposite, SWT.NULL);
1352 tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1353 tagLabel.setVisible(false);
1354
1355 tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE);
1356 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
1357 gd.widthHint = 0;
1358 tagText.setLayoutData(gd);
1359 tagText.setVisible(false);
1360
1361 actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
1362 actionCombo.setItems(new String[] {"Set", "Append", "Append with |"});
1363 actionCombo.select(0);
1364 actionCombo.addSelectionListener(updateListener);
1365
1366 previewLabel = new Label(parent, SWT.NULL);
1367 previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1368 previewLabel.setText("Preview:");
1369
1370 previewText = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
1371 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
1372 gd.widthHint = 0;
1373 previewText.setLayoutData(gd);
1374 previewText.setText("*no match*");
1375 previewText.setBackground(COLOR_WIDGET_BACKGROUND);
1376 }
1377
1378 private void dispose() {
1379 labelComposite.dispose();
1380 tagComposite.dispose();
1381 previewLabel.dispose();
1382 previewText.dispose();
1383 }
1384
1385 private void setInputNumber(int inputNumber) {
1386 this.inputNumber = inputNumber;
1387 inputLabel.setText("Group " + inputNumber + ":");
1388 labelComposite.layout();
1389 }
1390 }
1391
1392 private void validate() {
1393
1394 definition.definitionName = logtypeText.getText().trim();
1395 definition.timeStampOutputFormat = timestampOutputFormatText.getText().trim();
1396
1397 if (selectedLine != null) {
1398 selectedLine.extractInputs();
1399 treeViewer.refresh();
1400 }
1401
1402 StringBuffer errors = new StringBuffer();
1403
1404 if (definition.definitionName.length() == 0) {
1405 errors.append("Enter a name for the new log type. ");
1406 logtypeText.setBackground(COLOR_LIGHT_RED);
1407 } else {
1408 logtypeText.setBackground(COLOR_TEXT_BACKGROUND);
1409 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
1410 if (definition.definitionName.equals(def.definitionName)) {
1411 if (editDefinitionName == null || ! editDefinitionName.equals(definition.definitionName)) {
1412 errors.append("The log type name already exists. ");
1413 logtypeText.setBackground(COLOR_LIGHT_RED);
1414 break;
1415 }
1416 }
1417 }
1418 }
1419
1420 timestampFound = false;
1421 for (int i = 0; i < definition.inputs.size(); i++) {
1422
1423 InputLine inputLine = definition.inputs.get(i);
1424 String name = Integer.toString(i+1);
1425 errors.append(validateLine(inputLine, name));
1426 }
1427 if (timestampFound) {
1428 if (definition.timeStampOutputFormat.length() == 0) {
1429 errors.append("Enter the output format for the Time Stamp field. ");
1430 timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);
1431 } else {
1432 try {
1433 new SimpleDateFormat(definition.timeStampOutputFormat);
1434 timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);
1435 } catch (IllegalArgumentException e) {
1436 errors.append("Enter a valid output format for the Time Stamp field. ");
1437 timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);
1438 }
1439 }
1440
1441 } else {
1442 timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);
1443 // timestampPreviewText.setBackground(COLOR_WIDGET_BACKGROUND);
1444 // errors.append("Identify a Time Stamp group (Line "+name+"). ");
1445 // timestampPreviewText.setText("*no timestamp group*");
1446 // timestampPreviewText.setBackground(COLOR_LIGHT_RED);
1447 }
1448
1449 if (errors.length() == 0) {
1450 setDescription(defaultDescription);
1451 setPageComplete(true);
1452 } else {
1453 setDescription(errors.toString());
1454 setPageComplete(false);
1455 }
1456 }
1457
1458 public StringBuffer validateLine(InputLine inputLine, String name) {
1459 StringBuffer errors = new StringBuffer();
1460 Line line = null;
1461 if (selectedLine != null && selectedLine.inputLine.equals(inputLine)) line = selectedLine;
1462 try {
1463 Pattern.compile(inputLine.getRegex());
1464 if (line != null) line.regexText.setBackground(COLOR_TEXT_BACKGROUND);
1465 } catch (PatternSyntaxException e) {
1466 errors.append("Enter a valid regular expression (Line "+name+"). ");
1467 if (line != null) line.regexText.setBackground(COLOR_LIGHT_RED);
1468 }
1469 if (inputLine.getMinCount() == -1) {
1470 errors.append("Enter a minimum value for cardinality (Line "+name+"). ");
1471 if (line != null) line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);
1472 } else {
1473 if (line != null) line.cardinalityMinText.setBackground(COLOR_TEXT_BACKGROUND);
1474 }
1475 if (inputLine.getMaxCount() == -1) {
1476 errors.append("Enter a maximum value for cardinality (Line "+name+"). ");
1477 if (line != null) line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);
1478 } else if (inputLine.getMinCount() > inputLine.getMaxCount()) {
1479 errors.append("Enter correct (min <= max) values for cardinality (Line "+name+"). ");
1480 if (line != null) line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);
1481 if (line != null) line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);
1482 } else {
1483 if (line != null) line.cardinalityMaxText.setBackground(COLOR_TEXT_BACKGROUND);
1484 }
1485 for (int i = 0; inputLine.columns != null && i < inputLine.columns.size(); i++) {
1486 InputData inputData = inputLine.columns.get(i);
1487 InputGroup group = null;
1488 if (line != null) group = line.inputs.get(i);
1489 if (inputData.name.equals(CustomTxtTraceDefinition.TAG_TIMESTAMP)) {
1490 timestampFound = true;
1491 if (inputData.format.length() == 0) {
1492 errors.append("Enter the input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). ");
1493 if (group != null) group.tagText.setBackground(COLOR_LIGHT_RED);
1494 } else {
1495 try {
1496 new SimpleDateFormat(inputData.format);
1497 if (group != null) group.tagText.setBackground(COLOR_TEXT_BACKGROUND);
1498 } catch (IllegalArgumentException e) {
1499 errors.append("Enter a valid input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). ");
1500 if (group != null) group.tagText.setBackground(COLOR_LIGHT_RED);
1501 }
1502 }
1503 } else if (inputData.name.length() == 0) {
1504 errors.append("Enter a name for the data group (Line "+name+" Group "+(i+1)+"). ");
1505 if (group != null) group.tagText.setBackground(COLOR_LIGHT_RED);
1506 } else {
1507 if (group != null) group.tagText.setBackground(COLOR_TEXT_BACKGROUND);
1508 }
1509 }
1510 for (int i = 0; inputLine.childrenInputs != null && i < inputLine.childrenInputs.size(); i++) {
1511 errors.append(validateLine(inputLine.childrenInputs.get(i), name+"."+(i+1)));
1512 }
1513 return errors;
1514 }
1515
1516 public CustomTxtTraceDefinition getDefinition() {
1517 return definition;
1518 }
1519
1520 public char[] getInputText() {
1521 return inputText.getText().toCharArray();
1522 }
1523 }
This page took 0.068618 seconds and 5 git commands to generate.