1 /*******************************************************************************
2 * Copyright (c) 2010, 2016 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 static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
18 import java
.io
.FileWriter
;
19 import java
.io
.IOException
;
20 import java
.util
.AbstractMap
.SimpleEntry
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Iterator
;
23 import java
.util
.List
;
24 import java
.util
.Map
.Entry
;
26 import org
.eclipse
.jface
.wizard
.WizardPage
;
27 import org
.eclipse
.swt
.SWT
;
28 import org
.eclipse
.swt
.custom
.SashForm
;
29 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
30 import org
.eclipse
.swt
.events
.SelectionAdapter
;
31 import org
.eclipse
.swt
.events
.SelectionEvent
;
32 import org
.eclipse
.swt
.graphics
.Image
;
33 import org
.eclipse
.swt
.layout
.GridData
;
34 import org
.eclipse
.swt
.layout
.GridLayout
;
35 import org
.eclipse
.swt
.widgets
.Button
;
36 import org
.eclipse
.swt
.widgets
.Composite
;
37 import org
.eclipse
.swt
.widgets
.Text
;
38 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.parsers
.custom
.CustomEventAspects
;
39 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
40 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTraceDefinition
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTraceDefinition
.OutputColumn
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTraceDefinition
.Tag
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTrace
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTraceDefinition
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.indexer
.ITmfTraceIndexer
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.indexer
.checkpoint
.TmfCheckpointIndexer
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.events
.TmfEventsTable
;
53 * Output wizard page for custom XML trace parsers.
55 * @author Patrick Tasse
57 public class CustomXmlParserOutputWizardPage
extends WizardPage
{
59 private static final Image UP_IMAGE
= Activator
.getDefault().getImageFromPath("/icons/elcl16/up_button.gif"); //$NON-NLS-1$
60 private static final Image DOWN_IMAGE
= Activator
.getDefault().getImageFromPath("/icons/elcl16/down_button.gif"); //$NON-NLS-1$
61 private final CustomXmlParserWizard wizard
;
62 private CustomXmlTraceDefinition definition
;
63 private List
<Output
> outputs
= new ArrayList
<>();
64 private Composite container
;
65 private SashForm sash
;
66 private ScrolledComposite outputsScrolledComposite
;
67 private Composite outputsContainer
;
68 private Composite tableContainer
;
69 private TmfEventsTable previewTable
;
76 * The wizard to which this page belongs
78 protected CustomXmlParserOutputWizardPage(final CustomXmlParserWizard wizard
) {
79 super("CustomParserOutputWizardPage"); //$NON-NLS-1$
80 setTitle(wizard
.inputPage
.getTitle());
81 setDescription(Messages
.CustomXmlParserOutputWizardPage_description
);
83 setPageComplete(false);
87 public void createControl(final Composite parent
) {
88 container
= new Composite(parent
, SWT
.NULL
);
89 container
.setLayout(new GridLayout());
91 sash
= new SashForm(container
, SWT
.VERTICAL
);
92 sash
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
93 sash
.setBackground(sash
.getDisplay().getSystemColor(SWT
.COLOR_GRAY
));
95 outputsScrolledComposite
= new ScrolledComposite(sash
, SWT
.V_SCROLL
);
96 outputsScrolledComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
97 outputsContainer
= new Composite(outputsScrolledComposite
, SWT
.NONE
);
98 final GridLayout outputsLayout
= new GridLayout(4, false);
99 outputsLayout
.marginHeight
= 10;
100 outputsLayout
.marginWidth
= 0;
101 outputsContainer
.setLayout(outputsLayout
);
102 outputsScrolledComposite
.setContent(outputsContainer
);
103 outputsScrolledComposite
.setExpandHorizontal(true);
104 outputsScrolledComposite
.setExpandVertical(true);
106 outputsContainer
.layout();
108 outputsScrolledComposite
.setMinSize(outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).x
, outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
-5);
110 tableContainer
= new Composite(sash
, SWT
.NONE
);
111 final GridLayout tableLayout
= new GridLayout();
112 tableLayout
.marginHeight
= 0;
113 tableLayout
.marginWidth
= 0;
114 tableContainer
.setLayout(tableLayout
);
115 previewTable
= new TmfEventsTable(tableContainer
, 0, CustomEventAspects
.generateAspects(new CustomXmlTraceDefinition()));
116 previewTable
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
118 if (wizard
.definition
!= null) {
119 loadDefinition(wizard
.definition
);
121 setControl(container
);
126 public void dispose() {
127 previewTable
.dispose();
131 private void loadDefinition(final CustomTraceDefinition def
) {
132 for (final OutputColumn outputColumn
: def
.outputs
) {
133 final Output output
= new Output(outputsContainer
, outputColumn
.tag
, outputColumn
.name
);
139 public void setVisible(final boolean visible
) {
141 this.definition
= wizard
.inputPage
.getDefinition();
142 final List
<Entry
<Tag
, String
>> inputs
= wizard
.inputPage
.getInputs();
144 // substitute extra field name/value with extra fields tag
145 Iterator
<Entry
<Tag
, String
>> iterator
= inputs
.iterator();
146 boolean addExtraFields
= false;
147 while (iterator
.hasNext()) {
148 Entry
<Tag
, String
> entry
= iterator
.next();
149 if (entry
.getKey().equals(Tag
.EXTRA_FIELD_NAME
) ||
150 entry
.getKey().equals(Tag
.EXTRA_FIELD_VALUE
)) {
152 addExtraFields
= true;
155 if (addExtraFields
) {
156 inputs
.add(new SimpleEntry
<>(Tag
.EXTRA_FIELDS
, Tag
.EXTRA_FIELDS
.toString()));
159 // dispose outputs that have been removed in the input page
160 final Iterator
<Output
> iter
= outputs
.iterator();
161 while (iter
.hasNext()) {
162 final Output output
= iter
.next();
163 boolean found
= false;
164 for (final Entry
<Tag
, String
> input
: inputs
) {
165 if (output
.tag
.equals(input
.getKey()) &&
166 output
.name
.equals(input
.getValue())) {
177 // create outputs that have been added in the input page
178 for (final Entry
<Tag
, String
> input
: inputs
) {
179 boolean found
= false;
180 for (final Output output
: outputs
) {
181 if (output
.tag
.equals(input
.getKey()) &&
182 output
.name
.equals(input
.getValue())) {
188 outputs
.add(new Output(outputsContainer
, input
.getKey(), input
.getValue()));
192 outputsContainer
.layout();
193 outputsScrolledComposite
.setMinSize(outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).x
, outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
-5);
194 updatePreviewTable();
195 if (sash
.getSize().y
> outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
+ previewTable
.getTable().getItemHeight()) {
196 sash
.setWeights(new int[] {outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
, sash
.getSize().y
- outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
});
198 sash
.setWeights(new int[] {outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
, previewTable
.getTable().getItemHeight()});
200 setPageComplete(true);
202 setPageComplete(false);
204 super.setVisible(visible
);
207 private void moveBefore(final Output moved
) {
208 final int i
= outputs
.indexOf(moved
);
210 final Output previous
= outputs
.get(i
-1);
211 moved
.enabledButton
.moveAbove(previous
.enabledButton
);
212 moved
.nameLabel
.moveBelow(moved
.enabledButton
);
213 moved
.upButton
.moveBelow(moved
.nameLabel
);
214 moved
.downButton
.moveBelow(moved
.upButton
);
215 outputs
.add(i
-1, outputs
.remove(i
));
216 outputsContainer
.layout();
217 outputsScrolledComposite
.setMinSize(outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).x
, outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
-5);
219 updatePreviewTable();
223 private void moveAfter(final Output moved
) {
224 final int i
= outputs
.indexOf(moved
);
225 if (i
+1 < outputs
.size()) {
226 final Output next
= outputs
.get(i
+1);
227 moved
.enabledButton
.moveBelow(next
.downButton
);
228 moved
.nameLabel
.moveBelow(moved
.enabledButton
);
229 moved
.upButton
.moveBelow(moved
.nameLabel
);
230 moved
.downButton
.moveBelow(moved
.upButton
);
231 outputs
.add(i
+1, outputs
.remove(i
));
232 outputsContainer
.layout();
233 outputsScrolledComposite
.setMinSize(outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).x
, outputsContainer
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
).y
-5);
235 updatePreviewTable();
239 private void updatePreviewTable() {
240 final int CACHE_SIZE
= 50;
241 definition
.outputs
= extractOutputs();
242 tmpFile
= Activator
.getDefault().getStateLocation().addTrailingSeparator().append("customwizard.tmp").toFile(); //$NON-NLS-1$
244 try (final FileWriter writer
= new FileWriter(tmpFile
);) {
245 writer
.write(wizard
.inputPage
.getInputText());
246 } catch (final IOException e
) {
247 Activator
.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile
.getAbsolutePath(), e
); //$NON-NLS-1$
251 final CustomXmlTrace trace
= new CustomXmlTrace(null, definition
, tmpFile
.getAbsolutePath(), CACHE_SIZE
) {
253 protected ITmfTraceIndexer
createIndexer(int interval
) {
254 return new TmfCheckpointIndexer(this, interval
);
257 trace
.getIndexer().buildIndex(0, TmfTimeRange
.ETERNITY
, false);
258 previewTable
.dispose();
259 previewTable
= new TmfEventsTable(tableContainer
, CACHE_SIZE
, CustomEventAspects
.generateAspects(definition
));
260 previewTable
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
261 previewTable
.setTrace(trace
, true);
262 } catch (final TmfTraceException e
) {
263 Activator
.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile
.getAbsolutePath(), e
); //$NON-NLS-1$
266 tableContainer
.layout();
271 * Extract the output columns from the page's current contents.
273 * @return The list of output columns
275 public List
<OutputColumn
> extractOutputs() {
276 final List
<OutputColumn
> outputColumns
= new ArrayList
<>();
277 for (Output output
: outputs
) {
278 if (output
.enabledButton
.getSelection()) {
279 final OutputColumn column
= new OutputColumn(checkNotNull(output
.tag
), checkNotNull(output
.name
));
280 outputColumns
.add(column
);
283 return outputColumns
;
286 private class Output
{
289 Button enabledButton
;
294 public Output(final Composite parent
, final Tag tag
, final String name
) {
298 enabledButton
= new Button(parent
, SWT
.CHECK
);
299 enabledButton
.setToolTipText(Messages
.CustomXmlParserOutputWizardPage_visible
);
300 enabledButton
.setSelection(true);
301 enabledButton
.addSelectionListener(new SelectionAdapter() {
303 public void widgetSelected(final SelectionEvent e
) {
304 updatePreviewTable();
307 // if (messageOutput != null) {
308 // enabledButton.moveAbove(messageOutput.enabledButton);
311 nameLabel
= new Text(parent
, SWT
.BORDER
| SWT
.READ_ONLY
| SWT
.SINGLE
);
312 nameLabel
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
313 nameLabel
.setText(name
);
314 nameLabel
.moveBelow(enabledButton
);
316 upButton
= new Button(parent
, SWT
.PUSH
);
317 upButton
.setImage(UP_IMAGE
);
318 upButton
.setToolTipText(Messages
.CustomXmlParserOutputWizardPage_moveBefore
);
319 upButton
.addSelectionListener(new SelectionAdapter() {
321 public void widgetSelected(final SelectionEvent e
) {
322 moveBefore(Output
.this);
325 upButton
.moveBelow(nameLabel
);
327 downButton
= new Button(parent
, SWT
.PUSH
);
328 downButton
.setImage(DOWN_IMAGE
);
329 downButton
.setToolTipText(Messages
.CustomXmlParserOutputWizardPage_moveAfter
);
330 downButton
.addSelectionListener(new SelectionAdapter() {
332 public void widgetSelected(final SelectionEvent e
) {
333 moveAfter(Output
.this);
336 downButton
.moveBelow(upButton
);
339 private void dispose() {
340 enabledButton
.dispose();
343 downButton
.dispose();
348 * Get the trace definition.
350 * @return The trace definition
352 public CustomXmlTraceDefinition
getDefinition() {