1 /*******************************************************************************
2 * Copyright (c) 2010, 2014 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards;
15 import java.io.BufferedReader;
16 import java.io.ByteArrayInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.InputStreamReader;
21 import java.text.ParseException;
22 import java.util.ArrayList;
23 import java.util.List;
25 import javax.xml.parsers.DocumentBuilder;
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.parsers.ParserConfigurationException;
29 import org.eclipse.core.resources.IFile;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.core.runtime.FileLocator;
32 import org.eclipse.core.runtime.IPath;
33 import org.eclipse.core.runtime.Path;
34 import org.eclipse.core.runtime.Platform;
35 import org.eclipse.jface.viewers.AbstractTreeViewer;
36 import org.eclipse.jface.viewers.ColumnLabelProvider;
37 import org.eclipse.jface.viewers.ISelection;
38 import org.eclipse.jface.viewers.ISelectionChangedListener;
39 import org.eclipse.jface.viewers.IStructuredSelection;
40 import org.eclipse.jface.viewers.ITreeContentProvider;
41 import org.eclipse.jface.viewers.SelectionChangedEvent;
42 import org.eclipse.jface.viewers.StructuredSelection;
43 import org.eclipse.jface.viewers.TreeViewer;
44 import org.eclipse.jface.viewers.Viewer;
45 import org.eclipse.jface.wizard.WizardPage;
46 import org.eclipse.osgi.util.NLS;
47 import org.eclipse.swt.SWT;
48 import org.eclipse.swt.browser.Browser;
49 import org.eclipse.swt.browser.TitleEvent;
50 import org.eclipse.swt.browser.TitleListener;
51 import org.eclipse.swt.custom.SashForm;
52 import org.eclipse.swt.custom.ScrolledComposite;
53 import org.eclipse.swt.custom.StyleRange;
54 import org.eclipse.swt.custom.StyledText;
55 import org.eclipse.swt.events.ModifyEvent;
56 import org.eclipse.swt.events.ModifyListener;
57 import org.eclipse.swt.events.SelectionAdapter;
58 import org.eclipse.swt.events.SelectionEvent;
59 import org.eclipse.swt.events.SelectionListener;
60 import org.eclipse.swt.graphics.Color;
61 import org.eclipse.swt.graphics.Font;
62 import org.eclipse.swt.graphics.FontData;
63 import org.eclipse.swt.graphics.Image;
64 import org.eclipse.swt.graphics.Point;
65 import org.eclipse.swt.graphics.Rectangle;
66 import org.eclipse.swt.layout.FillLayout;
67 import org.eclipse.swt.layout.GridData;
68 import org.eclipse.swt.layout.GridLayout;
69 import org.eclipse.swt.widgets.Button;
70 import org.eclipse.swt.widgets.Combo;
71 import org.eclipse.swt.widgets.Composite;
72 import org.eclipse.swt.widgets.Display;
73 import org.eclipse.swt.widgets.Group;
74 import org.eclipse.swt.widgets.Label;
75 import org.eclipse.swt.widgets.Shell;
76 import org.eclipse.swt.widgets.Text;
77 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
78 import org.eclipse.tracecompass.internal.tmf.ui.Messages;
79 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition;
80 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlInputElement;
81 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
82 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
83 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlInputAttribute;
84 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
85 import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
86 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
87 import org.osgi.framework.Bundle;
88 import org.w3c.dom.Document;
89 import org.w3c.dom.Element;
90 import org.w3c.dom.NamedNodeMap;
91 import org.w3c.dom.Node;
92 import org.w3c.dom.NodeList;
93 import org.xml.sax.EntityResolver;
94 import org.xml.sax.ErrorHandler;
95 import org.xml.sax.InputSource;
96 import org.xml.sax.SAXException;
97 import org.xml.sax.SAXParseException;
99 import com.google.common.base.Joiner;
102 * Input wizard page for custom XML trace parsers.
104 * @author Patrick Tasse
106 public class CustomXmlParserInputWizardPage extends WizardPage {
108 private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$
109 private static final String TIMESTAMP_FORMAT_BUNDLE = "org.eclipse.tracecompass.doc.user"; //$NON-NLS-1$
110 private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$
111 private static final Image ELEMENT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/element_icon.gif"); //$NON-NLS-1$
112 private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$
113 private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$
114 private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$
115 private static final Image ADD_MANY_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addmany_button.gif"); //$NON-NLS-1$
116 private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$
117 private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$
118 private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$
119 private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$
120 private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192);
121 private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE);
122 private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
124 private final ISelection selection;
125 private CustomXmlTraceDefinition definition;
126 private String editCategoryName;
127 private String editDefinitionName;
128 private String defaultDescription;
129 private ElementNode selectedElement;
130 private Composite container;
131 private Text categoryText;
132 private Text logtypeText;
133 private Text timeStampOutputFormatText;
134 private Text timeStampPreviewText;
135 private Button removeButton;
136 private Button addChildButton;
137 private Button addNextButton;
138 private Button moveUpButton;
139 private Button moveDownButton;
140 private ScrolledComposite elementScrolledComposite;
141 private TreeViewer treeViewer;
142 private Composite elementContainer;
143 private Text errorText;
144 private StyledText inputText;
145 private Font fixedFont;
146 private UpdateListener updateListener;
147 private Browser helpBrowser;
148 private Element documentElement;
150 // variables used recursively through element traversal
151 private String timeStampValue;
152 private String timeStampFormat;
153 private boolean timeStampFound;
154 private int logEntriesCount;
155 private boolean logEntryFound;
165 protected CustomXmlParserInputWizardPage(ISelection selection, CustomXmlTraceDefinition definition) {
166 super("CustomXmlParserWizardPage"); //$NON-NLS-1$
167 if (definition == null) {
168 setTitle(Messages.CustomXmlParserInputWizardPage_titleNew);
169 defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionNew;
171 setTitle(Messages.CustomXmlParserInputWizardPage_titleEdit);
172 defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionEdit;
174 setDescription(defaultDescription);
175 this.selection = selection;
176 this.definition = definition;
177 if (definition != null) {
178 this.editCategoryName = definition.categoryName;
179 this.editDefinitionName = definition.definitionName;
184 public void createControl(Composite parent) {
185 container = new Composite(parent, SWT.NULL);
186 container.setLayout(new GridLayout());
188 updateListener = new UpdateListener();
190 Composite headerComposite = new Composite(container, SWT.FILL);
191 GridLayout headerLayout = new GridLayout(5, false);
192 headerLayout.marginHeight = 0;
193 headerLayout.marginWidth = 0;
194 headerComposite.setLayout(headerLayout);
195 headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
197 Label categoryLabel = new Label(headerComposite, SWT.NULL);
198 categoryLabel.setText(Messages.CustomXmlParserInputWizardPage_category);
200 categoryText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
201 categoryText.setLayoutData(new GridData(120, SWT.DEFAULT));
203 Label timeStampFormatLabel = new Label(headerComposite, SWT.NULL);
204 timeStampFormatLabel.setText(Messages.CustomXmlParserInputWizardPage_timestampFormat);
206 timeStampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
207 timeStampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
208 timeStampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT);
210 Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH);
211 timeStampFormatHelpButton.setImage(HELP_IMAGE);
212 timeStampFormatHelpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_timestampFormatHelp);
213 timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() {
215 public void widgetSelected(SelectionEvent e) {
216 Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE);
217 IPath path = new Path(TIMESTAMP_FORMAT_PATH);
218 URL fileURL = FileLocator.find(plugin, path, null);
220 URL pageURL = FileLocator.toFileURL(fileURL);
221 openHelpShell(pageURL.toString());
222 } catch (IOException e1) {
227 Label logtypeLabel = new Label(headerComposite, SWT.NULL);
228 logtypeLabel.setText(Messages.CustomXmlParserInputWizardPage_logType);
230 logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
231 logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT));
232 logtypeText.setFocus();
234 Label timeStampPreviewLabel = new Label(headerComposite, SWT.NULL);
235 timeStampPreviewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview);
237 timeStampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
238 timeStampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
239 timeStampPreviewText.setText("*no time stamp element or attribute*"); //$NON-NLS-1$
243 SashForm vSash = new SashForm(container, SWT.VERTICAL);
244 vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
245 vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
247 SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL);
248 hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
250 ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL);
251 treeScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
252 Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE);
253 treeContainer.setLayout(new FillLayout());
254 treeScrolledComposite.setContent(treeContainer);
255 treeScrolledComposite.setExpandHorizontal(true);
256 treeScrolledComposite.setExpandVertical(true);
258 treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER);
259 treeViewer.setContentProvider(new InputElementTreeNodeContentProvider());
260 treeViewer.setLabelProvider(new InputElementTreeLabelProvider());
261 treeViewer.addSelectionChangedListener(new InputElementTreeSelectionChangedListener());
262 treeContainer.layout();
264 treeScrolledComposite
265 .setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
267 elementScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL);
268 elementScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
269 elementContainer = new Composite(elementScrolledComposite, SWT.NONE);
270 GridLayout gl = new GridLayout();
273 elementContainer.setLayout(gl);
274 elementScrolledComposite.setContent(elementContainer);
275 elementScrolledComposite.setExpandHorizontal(true);
276 elementScrolledComposite.setExpandVertical(true);
278 if (definition == null) {
279 definition = new CustomXmlTraceDefinition();
281 loadDefinition(definition);
282 treeViewer.expandAll();
283 elementContainer.layout();
285 categoryText.addModifyListener(updateListener);
286 logtypeText.addModifyListener(updateListener);
287 timeStampOutputFormatText.addModifyListener(updateListener);
289 elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x,
290 elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1);
292 hSash.setWeights(new int[] { 1, 2 });
294 if (definition.rootInputElement == null) {
295 removeButton.setEnabled(false);
296 addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement);
297 addNextButton.setEnabled(false);
298 moveUpButton.setEnabled(false);
299 moveDownButton.setEnabled(false);
300 } else { // root is selected
301 addNextButton.setEnabled(false);
304 Composite sashBottom = new Composite(vSash, SWT.NONE);
305 GridLayout sashBottomLayout = new GridLayout(2, false);
306 sashBottomLayout.marginHeight = 0;
307 sashBottomLayout.marginWidth = 0;
308 sashBottom.setLayout(sashBottomLayout);
310 Label previewLabel = new Label(sashBottom, SWT.NULL);
311 previewLabel.setText(Messages.CustomXmlParserInputWizardPage_previewInput);
313 errorText = new Text(sashBottom, SWT.SINGLE | SWT.READ_ONLY);
314 errorText.setBackground(COLOR_WIDGET_BACKGROUND);
315 errorText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
316 errorText.setVisible(false);
318 inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
319 if (fixedFont == null) {
320 if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$
321 fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$
323 fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$
326 inputText.setFont(fixedFont);
327 GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
328 gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y;
330 inputText.setLayoutData(gd);
331 inputText.setText(getSelectionText());
332 inputText.addModifyListener(new ModifyListener() {
334 public void modifyText(ModifyEvent e) {
335 parseXmlInput(inputText.getText());
338 inputText.addModifyListener(updateListener);
340 vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y });
342 setControl(container);
345 private void createButtonBar() {
346 Composite buttonBar = new Composite(container, SWT.NONE);
347 GridLayout buttonBarLayout = new GridLayout(6, false);
348 buttonBarLayout.marginHeight = 0;
349 buttonBarLayout.marginWidth = 0;
350 buttonBar.setLayout(buttonBarLayout);
352 removeButton = new Button(buttonBar, SWT.PUSH);
353 removeButton.setImage(DELETE_IMAGE);
354 removeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeElement);
355 removeButton.addSelectionListener(new SelectionAdapter() {
357 public void widgetSelected(SelectionEvent e) {
358 if (treeViewer.getSelection().isEmpty() || selectedElement == null) {
362 CustomXmlInputElement inputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
363 if (inputElement == definition.rootInputElement) {
364 definition.rootInputElement = null;
366 inputElement.getParentElement().getChildElements().remove(inputElement);
368 treeViewer.refresh();
371 removeButton.setEnabled(false);
372 if (definition.rootInputElement == null) {
373 addChildButton.setEnabled(true);
374 addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentEleemnt);
376 addChildButton.setEnabled(false);
378 addNextButton.setEnabled(false);
379 moveUpButton.setEnabled(false);
380 moveDownButton.setEnabled(false);
384 addChildButton = new Button(buttonBar, SWT.PUSH);
385 addChildButton.setImage(ADD_CHILD_IMAGE);
386 addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement);
387 addChildButton.addSelectionListener(new SelectionAdapter() {
389 public void widgetSelected(SelectionEvent e) {
390 CustomXmlInputElement inputElement = new CustomXmlInputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$
391 if (definition.rootInputElement == null) {
392 definition.rootInputElement = inputElement;
393 inputElement.setElementName(getChildNameSuggestion(null));
394 } else if (treeViewer.getSelection().isEmpty()) {
397 CustomXmlInputElement parentInputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
398 parentInputElement.addChild(inputElement);
399 inputElement.setElementName(getChildNameSuggestion(parentInputElement));
401 treeViewer.refresh();
402 treeViewer.setSelection(new StructuredSelection(inputElement), true);
406 addNextButton = new Button(buttonBar, SWT.PUSH);
407 addNextButton.setImage(ADD_NEXT_IMAGE);
408 addNextButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addNextElement);
409 addNextButton.addSelectionListener(new SelectionAdapter() {
411 public void widgetSelected(SelectionEvent e) {
412 CustomXmlInputElement inputElement = new CustomXmlInputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$
413 if (definition.rootInputElement == null) {
414 definition.rootInputElement = inputElement;
415 inputElement.setElementName(getChildNameSuggestion(null));
416 } else if (treeViewer.getSelection().isEmpty()) {
419 CustomXmlInputElement previousInputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
420 if (previousInputElement == definition.rootInputElement) {
423 previousInputElement.addNext(inputElement);
424 inputElement.setElementName(getChildNameSuggestion(inputElement.getParentElement()));
426 treeViewer.refresh();
427 treeViewer.setSelection(new StructuredSelection(inputElement), true);
431 Button feelingLuckyButton = new Button(buttonBar, SWT.PUSH);
432 feelingLuckyButton.setImage(ADD_MANY_IMAGE);
433 feelingLuckyButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_feelingLucky);
434 feelingLuckyButton.addSelectionListener(new SelectionAdapter() {
436 public void widgetSelected(SelectionEvent e) {
437 CustomXmlInputElement inputElement = null;
438 if (definition.rootInputElement == null) {
439 if (getChildNameSuggestion(null).length() != 0) {
440 inputElement = new CustomXmlInputElement(getChildNameSuggestion(null), false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$
441 definition.rootInputElement = inputElement;
442 feelingLucky(inputElement);
446 } else if (treeViewer.getSelection().isEmpty()) {
449 inputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
450 feelingLucky(inputElement);
452 treeViewer.refresh();
453 treeViewer.setSelection(new StructuredSelection(inputElement), true);
454 treeViewer.expandToLevel(inputElement, AbstractTreeViewer.ALL_LEVELS);
458 moveUpButton = new Button(buttonBar, SWT.PUSH);
459 moveUpButton.setImage(MOVE_UP_IMAGE);
460 moveUpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveUp);
461 moveUpButton.addSelectionListener(new SelectionAdapter() {
463 public void widgetSelected(SelectionEvent e) {
464 if (treeViewer.getSelection().isEmpty()) {
467 CustomXmlInputElement inputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
468 if (inputElement == definition.rootInputElement) {
471 inputElement.moveUp();
472 treeViewer.refresh();
478 moveDownButton = new Button(buttonBar, SWT.PUSH);
479 moveDownButton.setImage(MOVE_DOWN_IMAGE);
480 moveDownButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveDown);
481 moveDownButton.addSelectionListener(new SelectionAdapter() {
483 public void widgetSelected(SelectionEvent e) {
484 if (treeViewer.getSelection().isEmpty()) {
487 CustomXmlInputElement inputElement = (CustomXmlInputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
488 if (inputElement == definition.rootInputElement) {
491 inputElement.moveDown();
492 treeViewer.refresh();
499 private void feelingLucky(CustomXmlInputElement inputElement) {
501 String attributeName = getAttributeNameSuggestion(inputElement);
502 if (attributeName.length() == 0) {
505 CustomXmlInputAttribute attribute = new CustomXmlInputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$
506 inputElement.addAttribute(attribute);
509 String childName = getChildNameSuggestion(inputElement);
510 if (childName.length() == 0) {
513 CustomXmlInputElement childElement = new CustomXmlInputElement(childName, false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$
514 inputElement.addChild(childElement);
515 feelingLucky(childElement);
519 private static class InputElementTreeNodeContentProvider implements ITreeContentProvider {
522 public Object[] getElements(Object inputElement) {
523 CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) inputElement;
524 if (def.rootInputElement != null) {
525 return new Object[] { def.rootInputElement };
527 return new Object[0];
531 public Object[] getChildren(Object parentElement) {
532 CustomXmlInputElement inputElement = (CustomXmlInputElement) parentElement;
533 if (inputElement.getChildElements() == null) {
534 return new CustomXmlInputElement[0];
536 return inputElement.getChildElements().toArray();
540 public boolean hasChildren(Object element) {
541 CustomXmlInputElement inputElement = (CustomXmlInputElement) element;
542 return (inputElement.getChildElements() != null && inputElement.getChildElements().size() > 0);
546 public void dispose() {
550 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
554 public Object getParent(Object element) {
555 CustomXmlInputElement inputElement = (CustomXmlInputElement) element;
556 return inputElement.getParentElement();
560 private static class InputElementTreeLabelProvider extends ColumnLabelProvider {
563 public Image getImage(Object element) {
564 return ELEMENT_IMAGE;
568 public String getText(Object element) {
569 CustomXmlInputElement inputElement = (CustomXmlInputElement) element;
570 return (inputElement.getElementName().trim().length() == 0) ? "?" : inputElement.getElementName(); //$NON-NLS-1$
574 private class InputElementTreeSelectionChangedListener implements ISelectionChangedListener {
576 public void selectionChanged(SelectionChangedEvent event) {
577 if (selectedElement != null) {
578 selectedElement.dispose();
580 if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) {
581 IStructuredSelection sel = (IStructuredSelection) event.getSelection();
582 CustomXmlInputElement inputElement = (CustomXmlInputElement) sel.getFirstElement();
583 selectedElement = new ElementNode(elementContainer, inputElement);
584 elementContainer.layout();
585 elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x,
586 elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1);
590 removeButton.setEnabled(true);
591 addChildButton.setEnabled(true);
592 addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement);
593 if (definition.rootInputElement == inputElement) {
594 addNextButton.setEnabled(false);
596 addNextButton.setEnabled(true);
598 moveUpButton.setEnabled(true);
599 moveDownButton.setEnabled(true);
601 removeButton.setEnabled(false);
602 if (definition.rootInputElement == null) {
603 addChildButton.setEnabled(true);
604 addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement);
606 addChildButton.setEnabled(false);
608 addNextButton.setEnabled(false);
609 moveUpButton.setEnabled(false);
610 moveDownButton.setEnabled(false);
616 public void dispose() {
617 if (fixedFont != null) {
624 private void loadDefinition(CustomXmlTraceDefinition def) {
625 categoryText.setText(def.categoryName);
626 logtypeText.setText(def.definitionName);
627 timeStampOutputFormatText.setText(def.timeStampOutputFormat);
628 treeViewer.setInput(def);
630 if (def.rootInputElement != null) {
631 treeViewer.setSelection(new StructuredSelection(def.rootInputElement));
635 private String getName(CustomXmlInputElement inputElement) {
636 String name = (inputElement.getElementName().trim().length() == 0) ? "?" : inputElement.getElementName().trim(); //$NON-NLS-1$
637 if (inputElement.getParentElement() == null) {
640 return getName(inputElement.getParentElement()) + " : " + name; //$NON-NLS-1$
643 private String getName(CustomXmlInputAttribute inputAttribute, CustomXmlInputElement inputElement) {
644 String name = (inputAttribute.getAttributeName().trim().length() == 0) ? "?" : inputAttribute.getAttributeName().trim(); //$NON-NLS-1$
645 return getName(inputElement) + " : " + name; //$NON-NLS-1$
649 public void setVisible(boolean visible) {
654 super.setVisible(visible);
658 * Get the global list of input names.
660 * @return The list of input names
662 public List<String> getInputNames() {
663 return getInputNames(definition.rootInputElement);
667 * Get the list of input names for a given element.
669 * @param inputElement
671 * @return The input names for this element
673 public List<String> getInputNames(CustomXmlInputElement inputElement) {
674 List<String> inputs = new ArrayList<>();
675 if (inputElement.getInputName() != null && !inputElement.getInputName().equals(CustomXmlTraceDefinition.TAG_IGNORE)) {
676 String inputName = inputElement.getInputName();
677 if (!inputs.contains(inputName)) {
678 inputs.add(inputName);
681 if (inputElement.getAttributes() != null) {
682 for (CustomXmlInputAttribute attribute : inputElement.getAttributes()) {
683 String inputName = attribute.getInputName();
684 if (!inputs.contains(inputName)) {
685 inputs.add(inputName);
689 if (inputElement.getChildElements() != null) {
690 for (CustomXmlInputElement childInputElement : inputElement.getChildElements()) {
691 for (String inputName : getInputNames(childInputElement)) {
692 if (!inputs.contains(inputName)) {
693 inputs.add(inputName);
701 private void removeElement() {
702 selectedElement.dispose();
703 selectedElement = null;
704 elementContainer.layout();
705 elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x,
706 elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1);
710 private String getSelectionText() {
711 InputStream inputStream = null;
712 if (this.selection instanceof IStructuredSelection) {
713 Object sel = ((IStructuredSelection) this.selection).getFirstElement();
714 if (sel instanceof IFile) {
715 IFile file = (IFile) sel;
717 inputStream = file.getContents();
718 } catch (CoreException e) {
719 return ""; //$NON-NLS-1$
723 if (inputStream != null) {
724 try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) {
725 StringBuilder sb = new StringBuilder();
727 while ((line = reader.readLine()) != null) {
731 parseXmlInput(sb.toString());
732 return sb.toString();
733 } catch (IOException e) {
734 return ""; //$NON-NLS-1$
737 return ""; //$NON-NLS-1$
740 private void parseXmlInput(final String string) {
742 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
743 DocumentBuilder db = dbf.newDocumentBuilder();
745 // The following allows xml parsing without access to the dtd
746 EntityResolver resolver = new EntityResolver() {
748 public InputSource resolveEntity(String publicId, String systemId) {
749 String empty = ""; //$NON-NLS-1$
750 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
751 return new InputSource(bais);
754 db.setEntityResolver(resolver);
756 // The following catches xml parsing exceptions
757 db.setErrorHandler(new ErrorHandler() {
759 public void error(SAXParseException saxparseexception) throws SAXException {
763 public void warning(SAXParseException saxparseexception) throws SAXException {
767 public void fatalError(SAXParseException saxparseexception) throws SAXException {
768 if (string.trim().length() != 0) {
769 errorText.setText(saxparseexception.getMessage());
770 errorText.setBackground(COLOR_LIGHT_RED);
771 errorText.setVisible(true);
773 throw saxparseexception;
777 errorText.setVisible(false);
779 doc = db.parse(new ByteArrayInputStream(string.getBytes()));
780 documentElement = doc.getDocumentElement();
781 } catch (ParserConfigurationException e) {
782 Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$
783 documentElement = null;
784 } catch (SAXException e) {
785 documentElement = null;
786 } catch (IOException e) {
787 Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$
788 documentElement = null;
792 private void initValues() {
793 timeStampValue = null;
794 timeStampFormat = null;
796 logEntryFound = false;
799 private void updatePreviews() {
800 if (inputText == null) {
801 // early update during construction
804 inputText.setStyleRanges(new StyleRange[] {});
805 if (selectedElement == null) {
811 selectedElement.updatePreview();
813 if (timeStampValue != null && timeStampFormat != null) {
815 TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timeStampFormat);
816 long timestamp = timestampFormat.parseValue(timeStampValue);
817 timestampFormat = new TmfTimestampFormat(timeStampOutputFormatText.getText().trim());
818 timeStampPreviewText.setText(timestampFormat.format(timestamp));
819 } catch (ParseException e) {
820 timeStampPreviewText.setText("*parse exception* [" + timeStampValue + "] <> [" + timeStampFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
821 } catch (IllegalArgumentException e) {
822 timeStampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$
825 timeStampPreviewText.setText("*no matching time stamp*"); //$NON-NLS-1$
829 private void openHelpShell(String url) {
830 if (helpBrowser != null && !helpBrowser.isDisposed()) {
831 helpBrowser.getShell().setActive();
832 if (!helpBrowser.getUrl().equals(url)) {
833 helpBrowser.setUrl(url);
837 final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM);
838 helpShell.setLayout(new FillLayout());
839 helpBrowser = new Browser(helpShell, SWT.NONE);
840 helpBrowser.addTitleListener(new TitleListener() {
842 public void changed(TitleEvent event) {
843 helpShell.setText(event.title);
846 Rectangle r = container.getBounds();
847 Point p = container.toDisplay(r.x, r.y);
848 Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400);
849 helpShell.setBounds(trim);
851 helpBrowser.setUrl(url);
854 private class UpdateListener implements ModifyListener, SelectionListener {
857 public void modifyText(ModifyEvent e) {
863 public void widgetDefaultSelected(SelectionEvent e) {
869 public void widgetSelected(SelectionEvent e) {
876 private class ElementNode {
877 private final CustomXmlInputElement inputElement;
878 private final Group group;
879 private List<Attribute> attributes = new ArrayList<>();
880 private List<ElementNode> childElements = new ArrayList<>();
881 private Text elementNameText;
882 private Composite tagComposite;
883 private Combo tagCombo;
884 private Label tagLabel;
885 private Text tagText;
886 private Combo actionCombo;
887 private Label previewLabel;
888 private Text previewText;
889 private Button logEntryButton;
890 private Label fillerLabel;
891 private Composite addAttributeComposite;
892 private Button addAttributeButton;
893 private Label addAttributeLabel;
895 public ElementNode(Composite parent, CustomXmlInputElement inputElement) {
896 this.inputElement = inputElement;
898 group = new Group(parent, SWT.NONE);
899 GridLayout gl = new GridLayout(2, false);
902 group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
903 group.setText(getName(inputElement));
905 Label label = new Label(group, SWT.NULL);
906 label.setText(Messages.CustomXmlParserInputWizardPage_elementName);
907 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
909 elementNameText = new Text(group, SWT.BORDER | SWT.SINGLE);
910 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
912 elementNameText.setLayoutData(gd);
913 elementNameText.addModifyListener(new ModifyListener() {
915 public void modifyText(ModifyEvent e) {
916 ElementNode.this.inputElement.setElementName(elementNameText.getText().trim());
917 group.setText(getName(ElementNode.this.inputElement));
920 elementNameText.setText(inputElement.getElementName());
921 elementNameText.addModifyListener(updateListener);
923 if (inputElement.getParentElement() != null) {
924 previewLabel = new Label(group, SWT.NULL);
925 previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
926 previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview);
928 previewText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
929 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
931 previewText.setLayoutData(gd);
932 previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement);
933 previewText.setBackground(COLOR_WIDGET_BACKGROUND);
935 logEntryButton = new Button(group, SWT.CHECK);
936 logEntryButton.setText(Messages.CustomXmlParserInputWizardPage_logEntry);
937 logEntryButton.setSelection(inputElement.isLogEntry());
938 logEntryButton.addSelectionListener(new SelectionListener() {
940 public void widgetDefaultSelected(SelectionEvent e) {
944 public void widgetSelected(SelectionEvent e) {
945 CustomXmlInputElement parentElem = ElementNode.this.inputElement.getParentElement();
946 while (parentElem != null) {
947 parentElem.setLogEntry(false);
948 parentElem = parentElem.getParentElement();
952 logEntryButton.addSelectionListener(updateListener);
954 tagComposite = new Composite(group, SWT.FILL);
955 GridLayout tagLayout = new GridLayout(4, false);
956 tagLayout.marginWidth = 0;
957 tagLayout.marginHeight = 0;
958 tagComposite.setLayout(tagLayout);
959 tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
961 tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
962 tagCombo.setItems(new String[] { CustomXmlTraceDefinition.TAG_IGNORE, CustomTraceDefinition.TAG_TIMESTAMP,
963 CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.TAG_OTHER });
964 tagCombo.setVisibleItemCount(tagCombo.getItemCount());
965 tagCombo.addSelectionListener(new SelectionListener() {
967 public void widgetDefaultSelected(SelectionEvent e) {
971 public void widgetSelected(SelectionEvent e) {
972 tagText.removeModifyListener(updateListener);
973 switch (tagCombo.getSelectionIndex()) {
975 tagLabel.setVisible(false);
976 tagText.setVisible(false);
977 actionCombo.setVisible(false);
979 case 1: // Time Stamp
980 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format);
981 tagLabel.setVisible(true);
982 tagText.setVisible(true);
983 tagText.addModifyListener(updateListener);
984 actionCombo.setVisible(true);
987 tagLabel.setVisible(false);
988 tagText.setVisible(false);
989 actionCombo.setVisible(true);
992 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName);
993 tagLabel.setVisible(true);
994 if (tagText.getText().trim().length() == 0) {
995 tagText.setText(elementNameText.getText().trim());
997 tagText.setVisible(true);
998 tagText.addModifyListener(updateListener);
999 actionCombo.setVisible(true);
1004 tagComposite.layout();
1010 tagLabel = new Label(tagComposite, SWT.NULL);
1011 tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1013 tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE);
1014 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
1016 tagText.setLayoutData(gd);
1018 actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
1019 actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append,
1020 Messages.CustomXmlParserInputWizardPage_appendWith });
1021 actionCombo.select(inputElement.getInputAction());
1022 actionCombo.addSelectionListener(updateListener);
1024 if (inputElement.getInputName().equals(CustomXmlTraceDefinition.TAG_IGNORE)) {
1026 tagLabel.setVisible(false);
1027 tagText.setVisible(false);
1028 actionCombo.setVisible(false);
1029 } else if (inputElement.getInputName().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1031 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format);
1032 tagText.setText(inputElement.getInputFormat());
1033 tagText.addModifyListener(updateListener);
1034 } else if (inputElement.getInputName().equals(CustomTraceDefinition.TAG_MESSAGE)) {
1036 tagLabel.setVisible(false);
1037 tagText.setVisible(false);
1040 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName);
1041 tagText.setText(inputElement.getInputName());
1042 tagText.addModifyListener(updateListener);
1046 if (inputElement.getAttributes() != null) {
1047 for (CustomXmlInputAttribute inputAttribute : inputElement.getAttributes()) {
1048 Attribute attribute = new Attribute(group, this, inputAttribute, attributes.size() + 1);
1049 attributes.add(attribute);
1056 private void updatePreview() {
1057 Element element = getPreviewElement(inputElement);
1058 if (inputElement.getParentElement() != null) { // no preview text for
1060 previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement);
1061 if (element != null) {
1062 previewText.setText(CustomXmlTrace.parseElement(element, new StringBuffer()).toString());
1063 if (logEntryButton.getSelection()) {
1064 if (!logEntryFound) {
1065 logEntryFound = true;
1068 logEntryButton.setSelection(false); // remove nested
1072 if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) {
1073 String value = previewText.getText().trim();
1074 if (value.length() != 0) {
1075 if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) {
1076 timeStampValue = value;
1077 timeStampFormat = tagText.getText().trim();
1078 } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) {
1079 if (timeStampValue != null) {
1080 timeStampValue += value;
1081 timeStampFormat += tagText.getText().trim();
1083 timeStampValue = value;
1084 timeStampFormat = tagText.getText().trim();
1086 } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) {
1087 if (timeStampValue != null) {
1088 timeStampValue += " | " + value; //$NON-NLS-1$
1089 timeStampFormat += " | " + tagText.getText().trim(); //$NON-NLS-1$
1091 timeStampValue = value;
1092 timeStampFormat = tagText.getText().trim();
1099 for (Attribute attribute : attributes) {
1100 if (element != null) {
1101 String value = element.getAttribute(attribute.attributeNameText.getText().trim());
1102 if (value.length() != 0) {
1103 attribute.previewText.setText(value);
1104 if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) {
1105 if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) {
1106 timeStampValue = value;
1107 timeStampFormat = attribute.tagText.getText().trim();
1108 } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) {
1109 if (timeStampValue != null) {
1110 timeStampValue += value;
1111 timeStampFormat += attribute.tagText.getText().trim();
1113 timeStampValue = value;
1114 timeStampFormat = attribute.tagText.getText().trim();
1116 } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) {
1117 if (timeStampValue != null) {
1118 timeStampValue += " | " + value; //$NON-NLS-1$
1119 timeStampFormat += " | " + attribute.tagText.getText().trim(); //$NON-NLS-1$
1121 timeStampValue = value;
1122 timeStampFormat = attribute.tagText.getText().trim();
1127 attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingAttribute);
1130 attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement);
1133 for (ElementNode child : childElements) {
1134 child.updatePreview();
1136 if (logEntryButton != null && logEntryButton.getSelection()) {
1137 logEntryFound = false;
1141 private void createAddButton() {
1142 fillerLabel = new Label(group, SWT.NONE);
1144 addAttributeComposite = new Composite(group, SWT.NONE);
1145 addAttributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1146 GridLayout addAttributeLayout = new GridLayout(2, false);
1147 addAttributeLayout.marginHeight = 0;
1148 addAttributeLayout.marginWidth = 0;
1149 addAttributeComposite.setLayout(addAttributeLayout);
1151 addAttributeButton = new Button(addAttributeComposite, SWT.PUSH);
1152 addAttributeButton.setImage(ADD_IMAGE);
1153 addAttributeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addAttribute);
1154 addAttributeButton.addSelectionListener(new SelectionAdapter() {
1156 public void widgetSelected(SelectionEvent e) {
1158 String attributeName = getAttributeNameSuggestion(inputElement);
1159 CustomXmlInputAttribute inputAttribute = new CustomXmlInputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$
1160 attributes.add(new Attribute(group, ElementNode.this, inputAttribute, attributes.size() + 1));
1162 elementContainer.layout();
1163 elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x,
1164 elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1);
1165 group.getParent().layout();
1171 addAttributeLabel = new Label(addAttributeComposite, SWT.NULL);
1172 addAttributeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1173 addAttributeLabel.setText(Messages.CustomXmlParserInputWizardPage_newAttibute);
1176 private void removeAddButton() {
1177 fillerLabel.dispose();
1178 addAttributeComposite.dispose();
1181 private void removeAttribute(int attributeNumber) {
1182 int nb = attributeNumber;
1183 if (--nb < attributes.size()) {
1184 attributes.remove(nb).dispose();
1185 for (int i = nb; i < attributes.size(); i++) {
1186 attributes.get(i).setAttributeNumber(i + 1);
1188 elementContainer.layout();
1189 elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x,
1190 elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1);
1191 group.getParent().layout();
1195 private void dispose() {
1199 private void extractInputs() {
1200 inputElement.setElementName(elementNameText.getText().trim());
1201 if (inputElement.getParentElement() != null) {
1202 inputElement.setLogEntry(logEntryButton.getSelection());
1203 if (tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) {
1204 inputElement.setInputName(tagText.getText().trim());
1206 inputElement.setInputName(tagCombo.getText());
1207 if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1208 inputElement.setInputFormat(tagText.getText().trim());
1211 inputElement.setInputAction(actionCombo.getSelectionIndex());
1213 inputElement.setAttributes(new ArrayList<CustomXmlInputAttribute>(attributes.size()));
1214 for (int i = 0; i < attributes.size(); i++) {
1215 String inputName = null;
1216 String inputFormat = null;
1217 Attribute attribute = attributes.get(i);
1218 String attributeName = attribute.attributeNameText.getText().trim();
1219 if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) {
1220 inputName = attribute.tagText.getText().trim();
1222 inputName = attribute.tagCombo.getText();
1223 if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1224 inputFormat = attribute.tagText.getText().trim();
1227 int inputAction = attribute.actionCombo.getSelectionIndex();
1228 inputElement.addAttribute(new CustomXmlInputAttribute(attributeName, inputName, inputAction, inputFormat));
1233 private class Attribute {
1234 private ElementNode element;
1235 private int attributeNumber;
1237 // children of parent (must be disposed)
1238 private Composite labelComposite;
1239 private Composite attributeComposite;
1240 private Label filler;
1241 private Composite tagComposite;
1243 // children of labelComposite
1244 private Label attributeLabel;
1246 // children of attributeComposite
1247 private Text attributeNameText;
1248 private Text previewText;
1250 // children of tagComposite
1251 private Combo tagCombo;
1252 private Label tagLabel;
1253 private Text tagText;
1254 private Combo actionCombo;
1256 public Attribute(Composite parent, ElementNode element, CustomXmlInputAttribute inputAttribute, int attributeNumber) {
1257 this.element = element;
1258 this.attributeNumber = attributeNumber;
1260 labelComposite = new Composite(parent, SWT.FILL);
1261 GridLayout labelLayout = new GridLayout(2, false);
1262 labelLayout.marginWidth = 0;
1263 labelLayout.marginHeight = 0;
1264 labelComposite.setLayout(labelLayout);
1265 labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1267 Button deleteButton = new Button(labelComposite, SWT.PUSH);
1268 deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1269 deleteButton.setImage(DELETE_IMAGE);
1270 deleteButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeAttribute);
1271 deleteButton.addSelectionListener(new SelectionAdapter() {
1273 public void widgetSelected(SelectionEvent e) {
1274 Attribute.this.element.removeAttribute(Attribute.this.attributeNumber);
1280 attributeLabel = new Label(labelComposite, SWT.NULL);
1281 attributeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1282 attributeLabel.setText(Messages.CustomXmlParserInputWizardPage_attibute);
1284 attributeComposite = new Composite(parent, SWT.FILL);
1285 GridLayout attributeLayout = new GridLayout(4, false);
1286 attributeLayout.marginWidth = 0;
1287 attributeLayout.marginHeight = 0;
1288 attributeComposite.setLayout(attributeLayout);
1289 attributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1291 Label nameLabel = new Label(attributeComposite, SWT.NONE);
1292 nameLabel.setText(Messages.CustomXmlParserInputWizardPage_name);
1294 attributeNameText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE);
1295 attributeNameText.setLayoutData(new GridData(120, SWT.DEFAULT));
1296 attributeNameText.setText(inputAttribute.getAttributeName());
1297 attributeNameText.addModifyListener(updateListener);
1299 Label previewLabel = new Label(attributeComposite, SWT.NONE);
1300 previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview);
1302 previewText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
1303 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
1305 previewText.setLayoutData(gd);
1306 previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatch);
1307 previewText.setBackground(COLOR_WIDGET_BACKGROUND);
1309 filler = new Label(parent, SWT.NULL);
1311 tagComposite = new Composite(parent, SWT.FILL);
1312 GridLayout tagLayout = new GridLayout(4, false);
1313 tagLayout.marginWidth = 0;
1314 tagLayout.marginHeight = 0;
1315 tagComposite.setLayout(tagLayout);
1316 tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
1318 tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
1319 tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, CustomTraceDefinition.TAG_MESSAGE,
1320 CustomTraceDefinition.TAG_OTHER });
1321 tagCombo.select(2); // Other
1322 tagCombo.addSelectionListener(new SelectionListener() {
1324 public void widgetDefaultSelected(SelectionEvent e) {
1328 public void widgetSelected(SelectionEvent e) {
1329 tagText.removeModifyListener(updateListener);
1330 switch (tagCombo.getSelectionIndex()) {
1331 case 0: // Time Stamp
1332 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format);
1333 tagLabel.setVisible(true);
1334 tagText.setVisible(true);
1335 tagText.addModifyListener(updateListener);
1338 tagLabel.setVisible(false);
1339 tagText.setVisible(false);
1342 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName);
1343 tagLabel.setVisible(true);
1344 if (tagText.getText().trim().length() == 0) {
1345 tagText.setText(attributeNameText.getText().trim());
1347 tagText.setVisible(true);
1348 tagText.addModifyListener(updateListener);
1353 tagComposite.layout();
1359 tagLabel = new Label(tagComposite, SWT.NULL);
1360 tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
1362 tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE);
1363 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
1365 tagText.setLayoutData(gd);
1366 tagText.setText(attributeNameText.getText());
1368 actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
1369 actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append,
1370 Messages.CustomXmlParserInputWizardPage_appendWith });
1371 actionCombo.select(inputAttribute.getInputAction());
1372 actionCombo.addSelectionListener(updateListener);
1374 if (inputAttribute.getInputName().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1376 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format);
1377 tagText.setText(inputAttribute.getInputFormat());
1378 tagText.addModifyListener(updateListener);
1379 } else if (inputAttribute.getInputName().equals(CustomTraceDefinition.TAG_MESSAGE)) {
1381 tagLabel.setVisible(false);
1382 tagText.setVisible(false);
1385 tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName);
1386 tagText.setText(inputAttribute.getInputName());
1387 tagText.addModifyListener(updateListener);
1391 private void dispose() {
1392 labelComposite.dispose();
1393 attributeComposite.dispose();
1395 tagComposite.dispose();
1398 private void setAttributeNumber(int attributeNumber) {
1399 this.attributeNumber = attributeNumber;
1400 labelComposite.layout();
1404 private Element getPreviewElement(CustomXmlInputElement inputElement) {
1405 CustomXmlInputElement currentElement = inputElement;
1406 Element element = documentElement;
1407 if (element != null) {
1408 if (!documentElement.getNodeName().equals(definition.rootInputElement.getElementName())) {
1411 ArrayList<String> elementNames = new ArrayList<>();
1412 while (currentElement != null) {
1413 elementNames.add(currentElement.getElementName());
1414 currentElement = currentElement.getParentElement();
1416 for (int i = elementNames.size() - 1; --i >= 0;) {
1417 NodeList childList = element.getChildNodes();
1419 for (int j = 0; j < childList.getLength(); j++) {
1420 Node child = childList.item(j);
1421 if (child instanceof Element && child.getNodeName().equals(elementNames.get(i))) {
1422 element = (Element) child;
1426 if (element == null) {
1430 if (element != null) {
1437 private String getChildNameSuggestion(CustomXmlInputElement inputElement) {
1438 if (inputElement == null) {
1439 if (documentElement != null) {
1440 return documentElement.getNodeName();
1443 Element element = getPreviewElement(inputElement);
1444 if (element != null) {
1445 NodeList childNodes = element.getChildNodes();
1446 for (int i = 0; i < childNodes.getLength(); i++) {
1447 Node node = childNodes.item(i);
1448 if (node instanceof Element) {
1449 boolean unused = true;
1450 if (inputElement.getChildElements() != null) {
1451 for (CustomXmlInputElement child : inputElement.getChildElements()) {
1452 if (child.getElementName().equals(node.getNodeName())) {
1459 return node.getNodeName();
1465 return ""; //$NON-NLS-1$
1468 private String getAttributeNameSuggestion(CustomXmlInputElement inputElement) {
1469 Element element = getPreviewElement(inputElement);
1470 if (element != null) {
1471 NamedNodeMap attributeMap = element.getAttributes();
1472 for (int i = 0; i < attributeMap.getLength(); i++) {
1473 Node node = attributeMap.item(i);
1474 boolean unused = true;
1475 if (inputElement.getAttributes() != null) {
1476 for (CustomXmlInputAttribute attribute : inputElement.getAttributes()) {
1477 if (attribute.getAttributeName().equals(node.getNodeName())) {
1484 return node.getNodeName();
1488 return ""; //$NON-NLS-1$
1491 private void validate() {
1492 definition.categoryName = categoryText.getText().trim();
1493 definition.definitionName = logtypeText.getText().trim();
1494 definition.timeStampOutputFormat = timeStampOutputFormatText.getText().trim();
1496 if (selectedElement != null) {
1497 selectedElement.extractInputs();
1498 treeViewer.refresh();
1501 List<String> errors = new ArrayList<>();
1503 if (definition.categoryName.length() == 0) {
1504 errors.add(Messages.CustomXmlParserInputWizardPage_emptyCategoryError);
1505 categoryText.setBackground(COLOR_LIGHT_RED);
1506 } else if (definition.definitionName.length() == 0) {
1507 errors.add(Messages.CustomXmlParserInputWizardPage_emptyLogTypeError);
1508 logtypeText.setBackground(COLOR_LIGHT_RED);
1510 categoryText.setBackground(COLOR_TEXT_BACKGROUND);
1511 logtypeText.setBackground(COLOR_TEXT_BACKGROUND);
1512 if (definition.categoryName.indexOf(':') != -1) {
1513 errors.add(Messages.CustomXmlParserInputWizardPage_invalidCategoryError);
1514 categoryText.setBackground(COLOR_LIGHT_RED);
1516 if (definition.definitionName.indexOf(':') != -1) {
1517 errors.add(Messages.CustomXmlParserInputWizardPage_invalidLogTypeError);
1518 logtypeText.setBackground(COLOR_LIGHT_RED);
1520 for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) {
1521 if (definition.categoryName.equals(helper.getCategoryName()) &&
1522 definition.definitionName.equals(helper.getName()) &&
1523 (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName)) &&
1524 (editCategoryName == null || !editCategoryName.equals(definition.categoryName))) {
1525 errors.add(Messages.CustomXmlParserInputWizardPage_duplicatelogTypeError);
1526 logtypeText.setBackground(COLOR_LIGHT_RED);
1532 if (definition.rootInputElement == null) {
1533 errors.add(Messages.CustomXmlParserInputWizardPage_noDocumentError);
1536 if (definition.rootInputElement != null) {
1537 logEntryFound = false;
1538 timeStampFound = false;
1540 errors.addAll(validateElement(definition.rootInputElement));
1542 if ((definition.rootInputElement.getAttributes() != null && definition.rootInputElement.getAttributes().size() != 0)
1543 || (definition.rootInputElement.getChildElements() != null && definition.rootInputElement.getChildElements().size() != 0)
1544 || errors.size() == 0) {
1545 if (!logEntryFound) {
1546 errors.add(Messages.CustomXmlParserInputWizardPage_missingLogEntryError);
1549 if (timeStampFound) {
1550 if (timeStampOutputFormatText.getText().trim().length() == 0) {
1551 errors.add(Messages.CustomXmlParserInputWizardPage_missingTimestampFmtError);
1552 timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED);
1555 new TmfTimestampFormat(timeStampOutputFormatText.getText().trim());
1556 timeStampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);
1557 } catch (IllegalArgumentException e) {
1558 errors.add(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError);
1559 timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED);
1563 timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute);
1567 timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute);
1570 if (errors.size() == 0) {
1571 setDescription(defaultDescription);
1572 setPageComplete(true);
1574 setDescription(Joiner.on(' ').join(errors));
1575 setPageComplete(false);
1580 * Clean up the specified XML element.
1582 * @param inputElement
1583 * The element to clean up
1584 * @return The validated element
1586 public List<String> validateElement(CustomXmlInputElement inputElement) {
1587 List<String> errors = new ArrayList<>();
1588 ElementNode elementNode = null;
1589 if (selectedElement != null && selectedElement.inputElement.equals(inputElement)) {
1590 elementNode = selectedElement;
1592 if (inputElement == definition.rootInputElement) {
1593 if (inputElement.getElementName().length() == 0) {
1594 errors.add(Messages.CustomXmlParserInputWizardPage_missingDocumentElementError);
1595 if (elementNode != null) {
1596 elementNode.elementNameText.setBackground(COLOR_LIGHT_RED);
1599 if (elementNode != null) {
1600 elementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND);
1604 if (inputElement != definition.rootInputElement) {
1605 if (inputElement.isLogEntry()) {
1606 logEntryFound = true;
1608 if (inputElement.getInputName().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1609 timeStampFound = true;
1610 if (inputElement.getInputFormat().length() == 0) {
1611 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingTimestampFmtError, getName(inputElement)));
1612 if (elementNode != null) {
1613 elementNode.tagText.setBackground(COLOR_LIGHT_RED);
1617 new TmfTimestampFormat(inputElement.getInputFormat());
1618 if (elementNode != null) {
1619 elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND);
1621 } catch (IllegalArgumentException e) {
1622 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError, getName(inputElement)));
1623 if (elementNode != null) {
1624 elementNode.tagText.setBackground(COLOR_LIGHT_RED);
1628 } else if (inputElement.getInputName().length() == 0) {
1629 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingInputNameError, getName(inputElement)));
1630 if (elementNode != null) {
1631 elementNode.tagText.setBackground(COLOR_LIGHT_RED);
1634 if (elementNode != null) {
1635 elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND);
1639 if (inputElement.getAttributes() != null) {
1640 if (elementNode != null) {
1641 for (Attribute attribute : elementNode.attributes) {
1642 attribute.attributeNameText.setBackground(COLOR_TEXT_BACKGROUND);
1645 for (int i = 0; i < inputElement.getAttributes().size(); i++) {
1646 CustomXmlInputAttribute attribute = inputElement.getAttributes().get(i);
1647 boolean duplicate = false;
1648 for (int j = i + 1; j < inputElement.getAttributes().size(); j++) {
1649 CustomXmlInputAttribute otherAttribute = inputElement.getAttributes().get(j);
1650 if (otherAttribute.getAttributeName().equals(attribute.getAttributeName())) {
1652 if (elementNode != null) {
1653 elementNode.attributes.get(j).attributeNameText.setBackground(COLOR_LIGHT_RED);
1657 if (attribute.getAttributeName().length() == 0) {
1658 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingNameError, getName(inputElement)));
1659 if (elementNode != null) {
1660 elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED);
1662 } else if (duplicate) {
1663 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeDuplicateNameError, getName(attribute, inputElement)));
1664 if (elementNode != null) {
1665 elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED);
1668 if (attribute.getInputName().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
1669 timeStampFound = true;
1670 if (attribute.getInputFormat().length() == 0) {
1671 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError, getName(attribute, inputElement)));
1672 if (elementNode != null) {
1673 elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED);
1677 new TmfTimestampFormat(attribute.getInputFormat());
1678 if (elementNode != null) {
1679 elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND);
1681 } catch (IllegalArgumentException e) {
1682 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError, getName(attribute, inputElement)));
1683 if (elementNode != null) {
1684 elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED);
1688 } else if (attribute.getInputName().length() == 0) {
1689 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingInputNameError, getName(attribute, inputElement)));
1690 if (elementNode != null) {
1691 elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED);
1694 if (elementNode != null) {
1695 elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND);
1700 if (inputElement.getChildElements() != null) {
1701 for (CustomXmlInputElement child : inputElement.getChildElements()) {
1702 ElementNode childElementNode = null;
1703 if (selectedElement != null && selectedElement.inputElement.equals(child)) {
1704 childElementNode = selectedElement;
1706 if (childElementNode != null) {
1707 childElementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND);
1710 for (int i = 0; i < inputElement.getChildElements().size(); i++) {
1711 CustomXmlInputElement child = inputElement.getChildElements().get(i);
1712 ElementNode childElementNode = null;
1713 if (selectedElement != null && selectedElement.inputElement.equals(child)) {
1714 childElementNode = selectedElement;
1716 if (child.getElementName().length() == 0) {
1717 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingNameError, getName(child)));
1718 if (childElementNode != null) {
1719 childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED);
1722 boolean duplicate = false;
1723 for (int j = i + 1; j < inputElement.getChildElements().size(); j++) {
1724 CustomXmlInputElement otherChild = inputElement.getChildElements().get(j);
1725 if (otherChild.getElementName().equals(child.getElementName())) {
1727 ElementNode otherChildElementNode = null;
1728 if (selectedElement != null && selectedElement.inputElement.equals(otherChild)) {
1729 otherChildElementNode = selectedElement;
1731 if (otherChildElementNode != null) {
1732 otherChildElementNode.elementNameText.setBackground(COLOR_LIGHT_RED);
1737 errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementDuplicateNameError, getName(child)));
1738 if (childElementNode != null) {
1739 childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED);
1744 errors.addAll(validateElement(child));
1751 * Get the trace definition.
1753 * @return The trace definition
1755 public CustomXmlTraceDefinition getDefinition() {
1760 * Get the raw text input.
1762 * @return The raw text input.
1764 public char[] getInputText() {
1765 return inputText.getText().toCharArray();