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