/******************************************************************************* * Copyright (c) 2010, 2014 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Patrick Tasse - Initial API and implementation *******************************************************************************/ package fr.inria.linuxtools.internal.tmf.ui.parsers.wizards; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.text.ParseException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.TitleEvent; import org.eclipse.swt.browser.TitleListener; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.osgi.framework.Bundle; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import fr.inria.linuxtools.internal.tmf.ui.Activator; import fr.inria.linuxtools.internal.tmf.ui.Messages; import fr.inria.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; import fr.inria.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; import fr.inria.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; import fr.inria.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputAttribute; import fr.inria.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; import fr.inria.linuxtools.tmf.core.timestamp.TmfTimestampFormat; /** * Input wizard page for custom XML trace parsers. * * @author Patrick Tasse */ public class CustomXmlParserInputWizardPage extends WizardPage { private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ private static final String TIMESTAMP_FORMAT_BUNDLE = "fr.inria.linuxtools.lttng.help"; //$NON-NLS-1$ private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$ private static final Image ELEMENT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/element_icon.gif"); //$NON-NLS-1$ private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$ private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$ private static final Image ADD_MANY_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addmany_button.gif"); //$NON-NLS-1$ private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$ private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192); private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); private final ISelection selection; private CustomXmlTraceDefinition definition; private String editDefinitionName; private String defaultDescription; private ElementNode selectedElement; private Composite container; private Text logtypeText; private Text timeStampOutputFormatText; private Text timeStampPreviewText; private Button removeButton; private Button addChildButton; private Button addNextButton; private Button moveUpButton; private Button moveDownButton; private ScrolledComposite elementScrolledComposite; private TreeViewer treeViewer; private Composite elementContainer; private Text errorText; private StyledText inputText; private Font fixedFont; private UpdateListener updateListener; private Browser helpBrowser; private Element documentElement; // variables used recursively through element traversal private String timeStampValue; private String timeStampFormat; private boolean timeStampFound; private int logEntriesCount; private boolean logEntryFound; /** * Constructor * * @param selection * Selection object * @param definition * Trace definition */ protected CustomXmlParserInputWizardPage(ISelection selection, CustomXmlTraceDefinition definition) { super("CustomXmlParserWizardPage"); //$NON-NLS-1$ if (definition == null) { setTitle(Messages.CustomXmlParserInputWizardPage_titleNew); defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionNew; } else { setTitle(Messages.CustomXmlParserInputWizardPage_titleEdit); defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionEdit; } setDescription(defaultDescription); this.selection = selection; this.definition = definition; if (definition != null) { this.editDefinitionName = definition.definitionName; } } @Override public void createControl(Composite parent) { container = new Composite(parent, SWT.NULL); container.setLayout(new GridLayout()); updateListener = new UpdateListener(); Composite headerComposite = new Composite(container, SWT.FILL); GridLayout headerLayout = new GridLayout(5, false); headerLayout.marginHeight = 0; headerLayout.marginWidth = 0; headerComposite.setLayout(headerLayout); headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); Label logtypeLabel = new Label(headerComposite, SWT.NULL); logtypeLabel.setText(Messages.CustomXmlParserInputWizardPage_logType); logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT)); Label timeStampFormatLabel = new Label(headerComposite, SWT.NULL); timeStampFormatLabel.setText(Messages.CustomXmlParserInputWizardPage_timestampFormat); timeStampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); timeStampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); timeStampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT); Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH); timeStampFormatHelpButton.setImage(HELP_IMAGE); timeStampFormatHelpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_timestampFormatHelp); timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE); IPath path = new Path(TIMESTAMP_FORMAT_PATH); URL fileURL = FileLocator.find(plugin, path, null); try { URL pageURL = FileLocator.toFileURL(fileURL); openHelpShell(pageURL.toString()); } catch (IOException e1) { } } }); Label timeStampPreviewLabel = new Label(headerComposite, SWT.NULL); timeStampPreviewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1)); timeStampPreviewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); timeStampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); timeStampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); timeStampPreviewText.setText("*no time stamp element or attribute*"); //$NON-NLS-1$ createButtonBar(); SashForm vSash = new SashForm(container, SWT.VERTICAL); vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL); hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL); treeScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE); treeContainer.setLayout(new FillLayout()); treeScrolledComposite.setContent(treeContainer); treeScrolledComposite.setExpandHorizontal(true); treeScrolledComposite.setExpandVertical(true); treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER); treeViewer.setContentProvider(new InputElementTreeNodeContentProvider()); treeViewer.setLabelProvider(new InputElementTreeLabelProvider()); treeViewer.addSelectionChangedListener(new InputElementTreeSelectionChangedListener()); treeContainer.layout(); treeScrolledComposite .setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); elementScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL); elementScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); elementContainer = new Composite(elementScrolledComposite, SWT.NONE); GridLayout gl = new GridLayout(); gl.marginHeight = 1; gl.marginWidth = 0; elementContainer.setLayout(gl); elementScrolledComposite.setContent(elementContainer); elementScrolledComposite.setExpandHorizontal(true); elementScrolledComposite.setExpandVertical(true); if (definition == null) { definition = new CustomXmlTraceDefinition(); } loadDefinition(definition); treeViewer.expandAll(); elementContainer.layout(); logtypeText.addModifyListener(updateListener); timeStampOutputFormatText.addModifyListener(updateListener); elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); hSash.setWeights(new int[] { 1, 2 }); if (definition.rootInputElement == null) { removeButton.setEnabled(false); addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); addNextButton.setEnabled(false); moveUpButton.setEnabled(false); moveDownButton.setEnabled(false); } else { // root is selected addNextButton.setEnabled(false); } Composite sashBottom = new Composite(vSash, SWT.NONE); GridLayout sashBottomLayout = new GridLayout(2, false); sashBottomLayout.marginHeight = 0; sashBottomLayout.marginWidth = 0; sashBottom.setLayout(sashBottomLayout); Label previewLabel = new Label(sashBottom, SWT.NULL); previewLabel.setText(Messages.CustomXmlParserInputWizardPage_previewInput); errorText = new Text(sashBottom, SWT.SINGLE | SWT.READ_ONLY); errorText.setBackground(COLOR_WIDGET_BACKGROUND); errorText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); errorText.setVisible(false); inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); if (fixedFont == null) { if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ } else { fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ } } inputText.setFont(fixedFont); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y; gd.widthHint = 800; inputText.setLayoutData(gd); inputText.setText(getSelectionText()); inputText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { parseXmlInput(inputText.getText()); } }); inputText.addModifyListener(updateListener); vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y }); setControl(container); } private void createButtonBar() { Composite buttonBar = new Composite(container, SWT.NONE); GridLayout buttonBarLayout = new GridLayout(6, false); buttonBarLayout.marginHeight = 0; buttonBarLayout.marginWidth = 0; buttonBar.setLayout(buttonBarLayout); removeButton = new Button(buttonBar, SWT.PUSH); removeButton.setImage(DELETE_IMAGE); removeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeElement); removeButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (treeViewer.getSelection().isEmpty() || selectedElement == null) { return; } removeElement(); InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); if (inputElement == definition.rootInputElement) { definition.rootInputElement = null; } else { inputElement.parentElement.childElements.remove(inputElement); } treeViewer.refresh(); validate(); updatePreviews(); removeButton.setEnabled(false); if (definition.rootInputElement == null) { addChildButton.setEnabled(true); addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentEleemnt); } else { addChildButton.setEnabled(false); } addNextButton.setEnabled(false); moveUpButton.setEnabled(false); moveDownButton.setEnabled(false); } }); addChildButton = new Button(buttonBar, SWT.PUSH); addChildButton.setImage(ADD_CHILD_IMAGE); addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); addChildButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ if (definition.rootInputElement == null) { definition.rootInputElement = inputElement; inputElement.elementName = getChildNameSuggestion(null); } else if (treeViewer.getSelection().isEmpty()) { return; } else { InputElement parentInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); parentInputElement.addChild(inputElement); inputElement.elementName = getChildNameSuggestion(parentInputElement); } treeViewer.refresh(); treeViewer.setSelection(new StructuredSelection(inputElement), true); } }); addNextButton = new Button(buttonBar, SWT.PUSH); addNextButton.setImage(ADD_NEXT_IMAGE); addNextButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addNextElement); addNextButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ if (definition.rootInputElement == null) { definition.rootInputElement = inputElement; inputElement.elementName = getChildNameSuggestion(null); } else if (treeViewer.getSelection().isEmpty()) { return; } else { InputElement previousInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); if (previousInputElement == definition.rootInputElement) { return; } previousInputElement.addNext(inputElement); inputElement.elementName = getChildNameSuggestion(inputElement.parentElement); } treeViewer.refresh(); treeViewer.setSelection(new StructuredSelection(inputElement), true); } }); Button feelingLuckyButton = new Button(buttonBar, SWT.PUSH); feelingLuckyButton.setImage(ADD_MANY_IMAGE); feelingLuckyButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_feelingLucky); feelingLuckyButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InputElement inputElement = null; if (definition.rootInputElement == null) { if (getChildNameSuggestion(null).length() != 0) { inputElement = new InputElement(getChildNameSuggestion(null), false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ definition.rootInputElement = inputElement; feelingLucky(inputElement); } else { return; } } else if (treeViewer.getSelection().isEmpty()) { return; } else { inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); feelingLucky(inputElement); } treeViewer.refresh(); treeViewer.setSelection(new StructuredSelection(inputElement), true); treeViewer.expandToLevel(inputElement, AbstractTreeViewer.ALL_LEVELS); } }); moveUpButton = new Button(buttonBar, SWT.PUSH); moveUpButton.setImage(MOVE_UP_IMAGE); moveUpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveUp); moveUpButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (treeViewer.getSelection().isEmpty()) { return; } InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); if (inputElement == definition.rootInputElement) { return; } inputElement.moveUp(); treeViewer.refresh(); validate(); updatePreviews(); } }); moveDownButton = new Button(buttonBar, SWT.PUSH); moveDownButton.setImage(MOVE_DOWN_IMAGE); moveDownButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveDown); moveDownButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (treeViewer.getSelection().isEmpty()) { return; } InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); if (inputElement == definition.rootInputElement) { return; } inputElement.moveDown(); treeViewer.refresh(); validate(); updatePreviews(); } }); } private void feelingLucky(InputElement inputElement) { while (true) { String attributeName = getAttributeNameSuggestion(inputElement); if (attributeName.length() == 0) { break; } InputAttribute attribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ inputElement.addAttribute(attribute); } while (true) { String childName = getChildNameSuggestion(inputElement); if (childName.length() == 0) { break; } InputElement childElement = new InputElement(childName, false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ inputElement.addChild(childElement); feelingLucky(childElement); } } private static class InputElementTreeNodeContentProvider implements ITreeContentProvider { @Override public Object[] getElements(Object inputElement) { CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) inputElement; if (def.rootInputElement != null) { return new Object[] { def.rootInputElement }; } return new Object[0]; } @Override public Object[] getChildren(Object parentElement) { InputElement inputElement = (InputElement) parentElement; if (inputElement.childElements == null) { return new InputElement[0]; } return inputElement.childElements.toArray(); } @Override public boolean hasChildren(Object element) { InputElement inputElement = (InputElement) element; return (inputElement.childElements != null && inputElement.childElements.size() > 0); } @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public Object getParent(Object element) { InputElement inputElement = (InputElement) element; return inputElement.parentElement; } } private static class InputElementTreeLabelProvider extends ColumnLabelProvider { @Override public Image getImage(Object element) { return ELEMENT_IMAGE; } @Override public String getText(Object element) { InputElement inputElement = (InputElement) element; return (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName; //$NON-NLS-1$ } } private class InputElementTreeSelectionChangedListener implements ISelectionChangedListener { @Override public void selectionChanged(SelectionChangedEvent event) { if (selectedElement != null) { selectedElement.dispose(); } if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { IStructuredSelection sel = (IStructuredSelection) event.getSelection(); InputElement inputElement = (InputElement) sel.getFirstElement(); selectedElement = new ElementNode(elementContainer, inputElement); elementContainer.layout(); elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); container.layout(); validate(); updatePreviews(); removeButton.setEnabled(true); addChildButton.setEnabled(true); addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); if (definition.rootInputElement == inputElement) { addNextButton.setEnabled(false); } else { addNextButton.setEnabled(true); } moveUpButton.setEnabled(true); moveDownButton.setEnabled(true); } else { removeButton.setEnabled(false); if (definition.rootInputElement == null) { addChildButton.setEnabled(true); addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); } else { addChildButton.setEnabled(false); } addNextButton.setEnabled(false); moveUpButton.setEnabled(false); moveDownButton.setEnabled(false); } } } @Override public void dispose() { if (fixedFont != null) { fixedFont.dispose(); fixedFont = null; } super.dispose(); } private void loadDefinition(CustomXmlTraceDefinition def) { logtypeText.setText(def.definitionName); timeStampOutputFormatText.setText(def.timeStampOutputFormat); treeViewer.setInput(def); if (def.rootInputElement != null) { treeViewer.setSelection(new StructuredSelection(def.rootInputElement)); } } private String getName(InputElement inputElement) { String name = (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName.trim(); //$NON-NLS-1$ if (inputElement.parentElement == null) { return name; } return getName(inputElement.parentElement) + " : " + name; //$NON-NLS-1$ } private String getName(InputAttribute inputAttribute, InputElement inputElement) { String name = (inputAttribute.attributeName.trim().length() == 0) ? "?" : inputAttribute.attributeName.trim(); //$NON-NLS-1$ return getName(inputElement) + " : " + name; //$NON-NLS-1$ } @Override public void setVisible(boolean visible) { if (visible) { validate(); updatePreviews(); } super.setVisible(visible); } /** * Get the global list of input names. * * @return The list of input names */ public List<String> getInputNames() { return getInputNames(definition.rootInputElement); } /** * Get the list of input names for a given element. * * @param inputElement * The element * @return The input names for this element */ public List<String> getInputNames(InputElement inputElement) { List<String> inputs = new ArrayList<>(); if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { String inputName = inputElement.inputName; if (!inputs.contains(inputName)) { inputs.add(inputName); } } if (inputElement.attributes != null) { for (InputAttribute attribute : inputElement.attributes) { String inputName = attribute.inputName; if (!inputs.contains(inputName)) { inputs.add(inputName); } } } if (inputElement.childElements != null) { for (InputElement childInputElement : inputElement.childElements) { for (String inputName : getInputNames(childInputElement)) { if (!inputs.contains(inputName)) { inputs.add(inputName); } } } } return inputs; } private void removeElement() { selectedElement.dispose(); selectedElement = null; elementContainer.layout(); elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); container.layout(); } private String getSelectionText() { InputStream inputStream = null; if (this.selection instanceof IStructuredSelection) { Object sel = ((IStructuredSelection) this.selection).getFirstElement(); if (sel instanceof IFile) { IFile file = (IFile) sel; try { inputStream = file.getContents(); } catch (CoreException e) { return ""; //$NON-NLS-1$ } } } if (inputStream != null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); //$NON-NLS-1$ } parseXmlInput(sb.toString()); return sb.toString(); } catch (IOException e) { return ""; //$NON-NLS-1$ } } return ""; //$NON-NLS-1$ } private void parseXmlInput(final String string) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); // The following allows xml parsing without access to the dtd EntityResolver resolver = new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) { String empty = ""; //$NON-NLS-1$ ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); return new InputSource(bais); } }; db.setEntityResolver(resolver); // The following catches xml parsing exceptions db.setErrorHandler(new ErrorHandler() { @Override public void error(SAXParseException saxparseexception) throws SAXException { } @Override public void warning(SAXParseException saxparseexception) throws SAXException { } @Override public void fatalError(SAXParseException saxparseexception) throws SAXException { if (string.trim().length() != 0) { errorText.setText(saxparseexception.getMessage()); errorText.setBackground(COLOR_LIGHT_RED); errorText.setVisible(true); } throw saxparseexception; } }); errorText.setVisible(false); Document doc = null; doc = db.parse(new ByteArrayInputStream(string.getBytes())); documentElement = doc.getDocumentElement(); } catch (ParserConfigurationException e) { Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ documentElement = null; } catch (SAXException e) { documentElement = null; } catch (IOException e) { Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ documentElement = null; } } private void initValues() { timeStampValue = null; timeStampFormat = null; logEntriesCount = 0; logEntryFound = false; } private void updatePreviews() { if (inputText == null) { // early update during construction return; } inputText.setStyleRanges(new StyleRange[] {}); if (selectedElement == null) { return; } initValues(); selectedElement.updatePreview(); if (timeStampValue != null && timeStampFormat != null) { try { TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timeStampFormat); long timestamp = timestampFormat.parseValue(timeStampValue); timestampFormat = new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); timeStampPreviewText.setText(timestampFormat.format(timestamp)); } catch (ParseException e) { timeStampPreviewText.setText("*parse exception* [" + timeStampValue + "] <> [" + timeStampFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (IllegalArgumentException e) { timeStampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$ } } else { timeStampPreviewText.setText("*no matching time stamp*"); //$NON-NLS-1$ } } private void openHelpShell(String url) { if (helpBrowser != null && !helpBrowser.isDisposed()) { helpBrowser.getShell().setActive(); if (!helpBrowser.getUrl().equals(url)) { helpBrowser.setUrl(url); } return; } final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM); helpShell.setLayout(new FillLayout()); helpBrowser = new Browser(helpShell, SWT.NONE); helpBrowser.addTitleListener(new TitleListener() { @Override public void changed(TitleEvent event) { helpShell.setText(event.title); } }); Rectangle r = container.getBounds(); Point p = container.toDisplay(r.x, r.y); Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400); helpShell.setBounds(trim); helpShell.open(); helpBrowser.setUrl(url); } private class UpdateListener implements ModifyListener, SelectionListener { @Override public void modifyText(ModifyEvent e) { validate(); updatePreviews(); } @Override public void widgetDefaultSelected(SelectionEvent e) { validate(); updatePreviews(); } @Override public void widgetSelected(SelectionEvent e) { validate(); updatePreviews(); } } private class ElementNode { private final InputElement inputElement; private final Group group; private List<Attribute> attributes = new ArrayList<>(); private List<ElementNode> childElements = new ArrayList<>(); private Text elementNameText; private Composite tagComposite; private Combo tagCombo; private Label tagLabel; private Text tagText; private Combo actionCombo; private Label previewLabel; private Text previewText; private Button logEntryButton; private Label fillerLabel; private Composite addAttributeComposite; private Button addAttributeButton; private Label addAttributeLabel; public ElementNode(Composite parent, InputElement inputElement) { this.inputElement = inputElement; group = new Group(parent, SWT.NONE); GridLayout gl = new GridLayout(2, false); gl.marginHeight = 0; group.setLayout(gl); group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); group.setText(getName(inputElement)); Label label = new Label(group, SWT.NULL); label.setText(Messages.CustomXmlParserInputWizardPage_elementName); label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); elementNameText = new Text(group, SWT.BORDER | SWT.SINGLE); GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint = 0; elementNameText.setLayoutData(gd); elementNameText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { ElementNode.this.inputElement.elementName = elementNameText.getText().trim(); group.setText(getName(ElementNode.this.inputElement)); } }); elementNameText.setText(inputElement.elementName); elementNameText.addModifyListener(updateListener); if (inputElement.parentElement != null) { previewLabel = new Label(group, SWT.NULL); previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); previewText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); gd = new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint = 0; previewText.setLayoutData(gd); previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); previewText.setBackground(COLOR_WIDGET_BACKGROUND); logEntryButton = new Button(group, SWT.CHECK); logEntryButton.setText(Messages.CustomXmlParserInputWizardPage_logEntry); logEntryButton.setSelection(inputElement.logEntry); logEntryButton.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { } @Override public void widgetSelected(SelectionEvent e) { InputElement parentElem = ElementNode.this.inputElement.parentElement; while (parentElem != null) { parentElem.logEntry = false; parentElem = parentElem.parentElement; } } }); logEntryButton.addSelectionListener(updateListener); tagComposite = new Composite(group, SWT.FILL); GridLayout tagLayout = new GridLayout(4, false); tagLayout.marginWidth = 0; tagLayout.marginHeight = 0; tagComposite.setLayout(tagLayout); tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); tagCombo.setItems(new String[] { CustomXmlTraceDefinition.TAG_IGNORE, CustomTraceDefinition.TAG_TIMESTAMP, CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.TAG_OTHER }); tagCombo.setVisibleItemCount(tagCombo.getItemCount()); tagCombo.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { } @Override public void widgetSelected(SelectionEvent e) { tagText.removeModifyListener(updateListener); switch (tagCombo.getSelectionIndex()) { case 0: // Ignore tagLabel.setVisible(false); tagText.setVisible(false); actionCombo.setVisible(false); break; case 1: // Time Stamp tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); tagLabel.setVisible(true); tagText.setVisible(true); tagText.addModifyListener(updateListener); actionCombo.setVisible(true); break; case 2: // Message tagLabel.setVisible(false); tagText.setVisible(false); actionCombo.setVisible(true); break; case 3: // Other tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); tagLabel.setVisible(true); if (tagText.getText().trim().length() == 0) { tagText.setText(elementNameText.getText().trim()); } tagText.setVisible(true); tagText.addModifyListener(updateListener); actionCombo.setVisible(true); break; default: break; } tagComposite.layout(); validate(); updatePreviews(); } }); tagLabel = new Label(tagComposite, SWT.NULL); tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); gd = new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint = 0; tagText.setLayoutData(gd); actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, Messages.CustomXmlParserInputWizardPage_appendWith }); actionCombo.select(inputElement.inputAction); actionCombo.addSelectionListener(updateListener); if (inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { tagCombo.select(0); tagLabel.setVisible(false); tagText.setVisible(false); actionCombo.setVisible(false); } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { tagCombo.select(1); tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); tagText.setText(inputElement.inputFormat); tagText.addModifyListener(updateListener); } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { tagCombo.select(2); tagLabel.setVisible(false); tagText.setVisible(false); } else { tagCombo.select(3); tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); tagText.setText(inputElement.inputName); tagText.addModifyListener(updateListener); } } if (inputElement.attributes != null) { for (InputAttribute inputAttribute : inputElement.attributes) { Attribute attribute = new Attribute(group, this, inputAttribute, attributes.size() + 1); attributes.add(attribute); } } createAddButton(); } private void updatePreview() { Element element = getPreviewElement(inputElement); if (inputElement.parentElement != null) { // no preview text for // document element previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); if (element != null) { previewText.setText(CustomXmlTrace.parseElement(element, new StringBuffer()).toString()); if (logEntryButton.getSelection()) { if (!logEntryFound) { logEntryFound = true; logEntriesCount++; } else { logEntryButton.setSelection(false); // remove nested // log entry } } if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { String value = previewText.getText().trim(); if (value.length() != 0) { if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { timeStampValue = value; timeStampFormat = tagText.getText().trim(); } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { if (timeStampValue != null) { timeStampValue += value; timeStampFormat += tagText.getText().trim(); } else { timeStampValue = value; timeStampFormat = tagText.getText().trim(); } } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { if (timeStampValue != null) { timeStampValue += " | " + value; //$NON-NLS-1$ timeStampFormat += " | " + tagText.getText().trim(); //$NON-NLS-1$ } else { timeStampValue = value; timeStampFormat = tagText.getText().trim(); } } } } } } for (Attribute attribute : attributes) { if (element != null) { String value = element.getAttribute(attribute.attributeNameText.getText().trim()); if (value.length() != 0) { attribute.previewText.setText(value); if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { timeStampValue = value; timeStampFormat = attribute.tagText.getText().trim(); } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { if (timeStampValue != null) { timeStampValue += value; timeStampFormat += attribute.tagText.getText().trim(); } else { timeStampValue = value; timeStampFormat = attribute.tagText.getText().trim(); } } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { if (timeStampValue != null) { timeStampValue += " | " + value; //$NON-NLS-1$ timeStampFormat += " | " + attribute.tagText.getText().trim(); //$NON-NLS-1$ } else { timeStampValue = value; timeStampFormat = attribute.tagText.getText().trim(); } } } } else { attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingAttribute); } } else { attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); } } for (ElementNode child : childElements) { child.updatePreview(); } if (logEntryButton != null && logEntryButton.getSelection()) { logEntryFound = false; } } private void createAddButton() { fillerLabel = new Label(group, SWT.NONE); addAttributeComposite = new Composite(group, SWT.NONE); addAttributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); GridLayout addAttributeLayout = new GridLayout(2, false); addAttributeLayout.marginHeight = 0; addAttributeLayout.marginWidth = 0; addAttributeComposite.setLayout(addAttributeLayout); addAttributeButton = new Button(addAttributeComposite, SWT.PUSH); addAttributeButton.setImage(ADD_IMAGE); addAttributeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addAttribute); addAttributeButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { removeAddButton(); String attributeName = getAttributeNameSuggestion(inputElement); InputAttribute inputAttribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ attributes.add(new Attribute(group, ElementNode.this, inputAttribute, attributes.size() + 1)); createAddButton(); elementContainer.layout(); elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); group.getParent().layout(); validate(); updatePreviews(); } }); addAttributeLabel = new Label(addAttributeComposite, SWT.NULL); addAttributeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); addAttributeLabel.setText(Messages.CustomXmlParserInputWizardPage_newAttibute); } private void removeAddButton() { fillerLabel.dispose(); addAttributeComposite.dispose(); } private void removeAttribute(int attributeNumber) { int nb = attributeNumber; if (--nb < attributes.size()) { attributes.remove(nb).dispose(); for (int i = nb; i < attributes.size(); i++) { attributes.get(i).setAttributeNumber(i + 1); } elementContainer.layout(); elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); group.getParent().layout(); } } private void dispose() { group.dispose(); } private void extractInputs() { inputElement.elementName = elementNameText.getText().trim(); if (inputElement.parentElement != null) { inputElement.logEntry = logEntryButton.getSelection(); if (tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { inputElement.inputName = tagText.getText().trim(); } else { inputElement.inputName = tagCombo.getText(); if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { inputElement.inputFormat = tagText.getText().trim(); } } inputElement.inputAction = actionCombo.getSelectionIndex(); } inputElement.attributes = new ArrayList<>(attributes.size()); for (int i = 0; i < attributes.size(); i++) { Attribute attribute = attributes.get(i); InputAttribute inputAttribute = new InputAttribute(); inputAttribute.attributeName = attribute.attributeNameText.getText().trim(); if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { inputAttribute.inputName = attribute.tagText.getText().trim(); } else { inputAttribute.inputName = attribute.tagCombo.getText(); if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { inputAttribute.inputFormat = attribute.tagText.getText().trim(); } } inputAttribute.inputAction = attribute.actionCombo.getSelectionIndex(); inputElement.addAttribute(inputAttribute); } } } private class Attribute { private ElementNode element; private int attributeNumber; // children of parent (must be disposed) private Composite labelComposite; private Composite attributeComposite; private Label filler; private Composite tagComposite; // children of labelComposite private Label attributeLabel; // children of attributeComposite private Text attributeNameText; private Text previewText; // children of tagComposite private Combo tagCombo; private Label tagLabel; private Text tagText; private Combo actionCombo; public Attribute(Composite parent, ElementNode element, InputAttribute inputAttribute, int attributeNumber) { this.element = element; this.attributeNumber = attributeNumber; labelComposite = new Composite(parent, SWT.FILL); GridLayout labelLayout = new GridLayout(2, false); labelLayout.marginWidth = 0; labelLayout.marginHeight = 0; labelComposite.setLayout(labelLayout); labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); Button deleteButton = new Button(labelComposite, SWT.PUSH); deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); deleteButton.setImage(DELETE_IMAGE); deleteButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeAttribute); deleteButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Attribute.this.element.removeAttribute(Attribute.this.attributeNumber); validate(); updatePreviews(); } }); attributeLabel = new Label(labelComposite, SWT.NULL); attributeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); attributeLabel.setText(Messages.CustomXmlParserInputWizardPage_attibute); attributeComposite = new Composite(parent, SWT.FILL); GridLayout attributeLayout = new GridLayout(4, false); attributeLayout.marginWidth = 0; attributeLayout.marginHeight = 0; attributeComposite.setLayout(attributeLayout); attributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); Label nameLabel = new Label(attributeComposite, SWT.NONE); nameLabel.setText(Messages.CustomXmlParserInputWizardPage_name); attributeNameText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE); attributeNameText.setLayoutData(new GridData(120, SWT.DEFAULT)); attributeNameText.setText(inputAttribute.attributeName); attributeNameText.addModifyListener(updateListener); Label previewLabel = new Label(attributeComposite, SWT.NONE); previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); previewText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint = 0; previewText.setLayoutData(gd); previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatch); previewText.setBackground(COLOR_WIDGET_BACKGROUND); filler = new Label(parent, SWT.NULL); tagComposite = new Composite(parent, SWT.FILL); GridLayout tagLayout = new GridLayout(4, false); tagLayout.marginWidth = 0; tagLayout.marginHeight = 0; tagComposite.setLayout(tagLayout); tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.TAG_OTHER }); tagCombo.select(2); // Other tagCombo.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { } @Override public void widgetSelected(SelectionEvent e) { tagText.removeModifyListener(updateListener); switch (tagCombo.getSelectionIndex()) { case 0: // Time Stamp tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); tagLabel.setVisible(true); tagText.setVisible(true); tagText.addModifyListener(updateListener); break; case 1: // Message tagLabel.setVisible(false); tagText.setVisible(false); break; case 2: // Other tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); tagLabel.setVisible(true); if (tagText.getText().trim().length() == 0) { tagText.setText(attributeNameText.getText().trim()); } tagText.setVisible(true); tagText.addModifyListener(updateListener); break; default: break; } tagComposite.layout(); validate(); updatePreviews(); } }); tagLabel = new Label(tagComposite, SWT.NULL); tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); gd = new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint = 0; tagText.setLayoutData(gd); tagText.setText(attributeNameText.getText()); actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, Messages.CustomXmlParserInputWizardPage_appendWith }); actionCombo.select(inputAttribute.inputAction); actionCombo.addSelectionListener(updateListener); if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { tagCombo.select(0); tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); tagText.setText(inputAttribute.inputFormat); tagText.addModifyListener(updateListener); } else if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { tagCombo.select(1); tagLabel.setVisible(false); tagText.setVisible(false); } else { tagCombo.select(2); tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); tagText.setText(inputAttribute.inputName); tagText.addModifyListener(updateListener); } } private void dispose() { labelComposite.dispose(); attributeComposite.dispose(); filler.dispose(); tagComposite.dispose(); } private void setAttributeNumber(int attributeNumber) { this.attributeNumber = attributeNumber; labelComposite.layout(); } } private Element getPreviewElement(InputElement inputElement) { InputElement currentElement = inputElement; Element element = documentElement; if (element != null) { if (!documentElement.getNodeName().equals(definition.rootInputElement.elementName)) { return null; } ArrayList<String> elementNames = new ArrayList<>(); while (currentElement != null) { elementNames.add(currentElement.elementName); currentElement = currentElement.parentElement; } for (int i = elementNames.size() - 1; --i >= 0;) { NodeList childList = element.getChildNodes(); element = null; for (int j = 0; j < childList.getLength(); j++) { Node child = childList.item(j); if (child instanceof Element && child.getNodeName().equals(elementNames.get(i))) { element = (Element) child; break; } } if (element == null) { break; } } if (element != null) { return element; } } return null; } private String getChildNameSuggestion(InputElement inputElement) { if (inputElement == null) { if (documentElement != null) { return documentElement.getNodeName(); } } else { Element element = getPreviewElement(inputElement); if (element != null) { NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { boolean unused = true; if (inputElement.childElements != null) { for (InputElement child : inputElement.childElements) { if (child.elementName.equals(node.getNodeName())) { unused = false; break; } } } if (unused) { return node.getNodeName(); } } } } } return ""; //$NON-NLS-1$ } private String getAttributeNameSuggestion(InputElement inputElement) { Element element = getPreviewElement(inputElement); if (element != null) { NamedNodeMap attributeMap = element.getAttributes(); for (int i = 0; i < attributeMap.getLength(); i++) { Node node = attributeMap.item(i); boolean unused = true; if (inputElement.attributes != null) { for (InputAttribute attribute : inputElement.attributes) { if (attribute.attributeName.equals(node.getNodeName())) { unused = false; break; } } } if (unused) { return node.getNodeName(); } } } return ""; //$NON-NLS-1$ } private void validate() { definition.definitionName = logtypeText.getText().trim(); definition.timeStampOutputFormat = timeStampOutputFormatText.getText().trim(); if (selectedElement != null) { selectedElement.extractInputs(); treeViewer.refresh(); } StringBuffer errors = new StringBuffer(); if (definition.definitionName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_emptyLogTypeError); logtypeText.setBackground(COLOR_LIGHT_RED); } else { logtypeText.setBackground(COLOR_TEXT_BACKGROUND); for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { if (definition.definitionName.equals(def.definitionName) && (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName))) { errors.append(Messages.CustomXmlParserInputWizardPage_duplicatelogTypeError); logtypeText.setBackground(COLOR_LIGHT_RED); break; } } } if (definition.rootInputElement == null) { errors.append(Messages.CustomXmlParserInputWizardPage_noDocumentError); } if (definition.rootInputElement != null) { logEntryFound = false; timeStampFound = false; errors.append(validateElement(definition.rootInputElement)); if ((definition.rootInputElement.attributes != null && definition.rootInputElement.attributes.size() != 0) || (definition.rootInputElement.childElements != null && definition.rootInputElement.childElements.size() != 0) || errors.length() == 0) { if (!logEntryFound) { errors.append(Messages.CustomXmlParserInputWizardPage_missingLogEntryError); } if (timeStampFound) { if (timeStampOutputFormatText.getText().trim().length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingTimestampFmtError); timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); } else { try { new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); timeStampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); } catch (IllegalArgumentException e) { errors.append(Messages.CustomXmlParserInputWizardPage_invalidTimestampFmtError); timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); } } } else { timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_notimestamporAttributeError); } } } else { timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_notimestamporAttributeError); } if (errors.length() == 0) { setDescription(defaultDescription); setPageComplete(true); } else { setDescription(errors.toString()); setPageComplete(false); } } /** * Clean up the specified XML element. * * @param inputElement * The element to clean up * @return The validated element */ public StringBuffer validateElement(InputElement inputElement) { StringBuffer errors = new StringBuffer(); ElementNode elementNode = null; if (selectedElement != null && selectedElement.inputElement.equals(inputElement)) { elementNode = selectedElement; } if (inputElement == definition.rootInputElement) { if (inputElement.elementName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingDocumentElementError); if (elementNode != null) { elementNode.elementNameText.setBackground(COLOR_LIGHT_RED); } } else { if (elementNode != null) { elementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); } } } if (inputElement != definition.rootInputElement) { if (inputElement.logEntry) { logEntryFound = true; } if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { timeStampFound = true; if (inputElement.inputFormat.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_timestampFormatPrompt + " (" + Messages.CustomXmlParserInputWizardPage_timestampElementPrompt + " " + getName(inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.tagText.setBackground(COLOR_LIGHT_RED); } } else { try { new TmfTimestampFormat(inputElement.inputFormat); if (elementNode != null) { elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); } } catch (IllegalArgumentException e) { errors.append(Messages.CustomXmlParserInputWizardPage_invalidTimestampFmtError + " (" + Messages.CustomXmlParserInputWizardPage_timestampElementPrompt + " " + getName(inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.tagText.setBackground(COLOR_LIGHT_RED); } } } } else if (inputElement.inputName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingInputElementNameError); if (elementNode != null) { elementNode.tagText.setBackground(COLOR_LIGHT_RED); } } else { if (elementNode != null) { elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); } } } if (inputElement.attributes != null) { if (elementNode != null) { for (Attribute attribute : elementNode.attributes) { attribute.attributeNameText.setBackground(COLOR_TEXT_BACKGROUND); } } for (int i = 0; i < inputElement.attributes.size(); i++) { InputAttribute attribute = inputElement.attributes.get(i); boolean duplicate = false; for (int j = i + 1; j < inputElement.attributes.size(); j++) { InputAttribute otherAttribute = inputElement.attributes.get(j); if (otherAttribute.attributeName.equals(attribute.attributeName)) { duplicate = true; if (elementNode != null) { elementNode.attributes.get(j).attributeNameText.setBackground(COLOR_LIGHT_RED); } } } if (attribute.attributeName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingAttribute + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(inputElement) + ": ?). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); } } else if (duplicate) { errors.append(Messages.CustomXmlParserInputWizardPage_duplicateAttributeError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(attribute, inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); } } if (attribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { timeStampFound = true; if (attribute.inputFormat.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingTimestampInFmtError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(attribute, inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); } } else { try { new TmfTimestampFormat(attribute.inputFormat); if (elementNode != null) { elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); } } catch (IllegalArgumentException e) { errors.append(Messages.CustomXmlParserInputWizardPage_invalidTimestampInFmtError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(attribute, inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); } } } } else if (attribute.inputName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingDataGroupNameError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(attribute, inputElement) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (elementNode != null) { elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); } } else { if (elementNode != null) { elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); } } } } if (inputElement.childElements != null) { for (InputElement child : inputElement.childElements) { ElementNode childElementNode = null; if (selectedElement != null && selectedElement.inputElement.equals(child)) { childElementNode = selectedElement; } if (childElementNode != null) { childElementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); } } for (int i = 0; i < inputElement.childElements.size(); i++) { InputElement child = inputElement.childElements.get(i); ElementNode childElementNode = null; if (selectedElement != null && selectedElement.inputElement.equals(child)) { childElementNode = selectedElement; } if (child.elementName.length() == 0) { errors.append(Messages.CustomXmlParserInputWizardPage_missingElementNameError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(child) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (childElementNode != null) { childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); } } else { boolean duplicate = false; for (int j = i + 1; j < inputElement.childElements.size(); j++) { InputElement otherChild = inputElement.childElements.get(j); if (otherChild.elementName.equals(child.elementName)) { duplicate = true; ElementNode otherChildElementNode = null; if (selectedElement != null && selectedElement.inputElement.equals(otherChild)) { otherChildElementNode = selectedElement; } if (otherChildElementNode != null) { otherChildElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); } } } if (duplicate) { errors.append(Messages.CustomXmlParserInputWizardPage_duplicateElementNameError + " (" + Messages.CustomXmlParserInputWizardPage_attributePrompt + " " + getName(child) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (childElementNode != null) { childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); } } } errors.append(validateElement(child)); } } return errors; } /** * Get the trace definition. * * @return The trace definition */ public CustomXmlTraceDefinition getDefinition() { return definition; } /** * Get the raw text input. * * @return The raw text input. */ public char[] getInputText() { return inputText.getText().toCharArray(); } }