1 /**********************************************************************
2 * Copyright (c) 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 * Bruno Roy - Initial API and implementation
11 **********************************************************************/
12 package org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.dialogs
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Arrays
;
16 import java
.util
.HashSet
;
17 import java
.util
.List
;
19 import java
.util
.stream
.Collectors
;
21 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
22 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
23 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
24 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
25 import org
.eclipse
.jface
.viewers
.TreeViewer
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.custom
.CCombo
;
28 import org
.eclipse
.swt
.events
.SelectionAdapter
;
29 import org
.eclipse
.swt
.events
.SelectionEvent
;
30 import org
.eclipse
.swt
.graphics
.Image
;
31 import org
.eclipse
.swt
.layout
.GridData
;
32 import org
.eclipse
.swt
.layout
.GridLayout
;
33 import org
.eclipse
.swt
.widgets
.Button
;
34 import org
.eclipse
.swt
.widgets
.Composite
;
35 import org
.eclipse
.swt
.widgets
.Group
;
36 import org
.eclipse
.swt
.widgets
.Label
;
37 import org
.eclipse
.swt
.widgets
.Text
;
38 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.ITraceLogLevel
;
39 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.LogLevelType
;
40 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.TraceDomainType
;
41 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.TraceJulLogLevel
;
42 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.TraceLog4jLogLevel
;
43 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.core
.model
.TracePythonLogLevel
;
44 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.messages
.Messages
;
45 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.ITraceControlComponent
;
46 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.BaseLoggerComponent
;
47 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.TargetNodeComponent
;
48 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.TraceControlContentProvider
;
49 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.TraceControlLabelProvider
;
50 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.TraceProviderGroup
;
51 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.model
.impl
.UstProviderComponent
;
52 import org
.eclipse
.ui
.dialogs
.FilteredTree
;
53 import org
.eclipse
.ui
.dialogs
.PatternFilter
;
56 * A composite for collecting information about loggers to be enabled.
60 public class EnableLoggersComposite
extends Composite
implements IBaseEnableUstEvents
{
62 // ------------------------------------------------------------------------
64 // ------------------------------------------------------------------------
66 private enum GroupEnum
{ LOGGERS
}
68 // ------------------------------------------------------------------------
70 // ------------------------------------------------------------------------
73 * The referenced trace provider group containing the loggers providers
74 * component which contains a list of available tracepoints.
76 private final TraceProviderGroup fProviderGroup
;
78 * A button to enable/disable the loggers group
80 private Button fLoggersActivateButton
;
82 * A tree viewer for displaying and selection of available loggers.
84 private CheckboxTreeViewer fLoggersViewer
;
86 * A Text field for the specific logger name.
88 private Text fSpecificLoggerText
;
90 * The flag indicating that loggers are selected.
92 private boolean fIsLoggers
;
94 * The list of loggers to be enabled.
96 private List
<String
> fLoggers
;
98 * A button to enable/disable the log level group
100 private Button fLogLevelActivateButton
;
102 * A Combo box for selecting the log level.
104 private CCombo fLogLevelCombo
;
106 * A button for selecting the log level (range 0 to level).
108 private Button fLogLevelButton
;
110 * A button for selecting the specified log level only.
112 private Button fLogLevelOnlyButton
;
114 * The flag indicating that all log level are selected.
116 private boolean fIsLogLevel
;
118 * The flag indicating that all loggers (across providers) are selected.
120 private boolean fIsAllLoggers
;
122 * The type of the log level (loglevel or loglevel-only)
124 private LogLevelType fLogLevelType
;
126 * The selected log level.
128 private ITraceLogLevel fLogLevel
;
130 * The domain of the loggers.
132 private final TraceDomainType fDomain
;
134 // ------------------------------------------------------------------------
136 // ------------------------------------------------------------------------
144 * @param providerGroup
145 * the trace provider group
147 * the domain of the loggers
149 public EnableLoggersComposite(Composite parent
, int style
, TraceProviderGroup providerGroup
, TraceDomainType domain
) {
150 super(parent
, style
);
151 fProviderGroup
= providerGroup
;
155 // ------------------------------------------------------------------------
157 // ------------------------------------------------------------------------
160 public ITraceLogLevel
getLogLevel() {
165 public LogLevelType
getLogLevelType() {
166 return fLogLevelType
;
170 public boolean isAllTracePoints() {
171 return fIsAllLoggers
;
175 public List
<String
> getEventNames() {
176 return new ArrayList
<>(fLoggers
);
180 public boolean isLogLevel() {
184 // ------------------------------------------------------------------------
186 // ------------------------------------------------------------------------
189 * Create the contents of this event composite
191 public void createContent() {
194 createLoggersGroup();
197 createLogLevelGroup();
199 // Set default enablements
200 setEnablements(GroupEnum
.LOGGERS
);
204 * Validates the loggers composite input data.
206 * @return true if configured data is valid and can be retrieved.
208 public boolean isValid() {
210 fIsLoggers
= fLoggersActivateButton
.getSelection();
211 fIsLogLevel
= fLogLevelActivateButton
.getSelection();
213 // Initialize loggers fields
214 fLoggers
= new ArrayList
<>();
216 Set
<String
> set
= new HashSet
<>();
217 Object
[] checkedElements
= fLoggersViewer
.getCheckedElements();
218 int checkedNbLoggers
= 0;
219 for (int i
= 0; i
< checkedElements
.length
; i
++) {
220 ITraceControlComponent component
= (ITraceControlComponent
) checkedElements
[i
];
221 if (component
instanceof BaseLoggerComponent
) {
223 if (!set
.contains(component
.getName())) {
224 set
.add(component
.getName());
225 fLoggers
.add(component
.getName());
230 // verify if all events are selected
231 int nbAvailableLoggers
= 0;
232 List
<ITraceControlComponent
> comps
= fProviderGroup
.getChildren(UstProviderComponent
.class);
233 for (ITraceControlComponent comp
: comps
) {
234 // We want the children of each UST provider
235 ITraceControlComponent
[] events
= comp
.getChildren();
236 for (ITraceControlComponent event
: events
) {
237 if (event
instanceof BaseLoggerComponent
&& fDomain
.equals(((BaseLoggerComponent
)event
).getDomain())) {
238 nbAvailableLoggers
++;
243 // Either all available loggers are selected or no loggers are available but All checkbox is selected
244 fIsAllLoggers
= ((checkedNbLoggers
> 0) && (nbAvailableLoggers
== checkedNbLoggers
)) ||
245 ((nbAvailableLoggers
== 0) && fLoggersViewer
.getCheckedElements().length
== 1);
247 String tmpSpecificLogger
= fSpecificLoggerText
.getText();
248 if (!fIsAllLoggers
&& !tmpSpecificLogger
.trim().isEmpty()) {
249 // Format the text to a List<String>
250 // Removing all non visible characters
251 tmpSpecificLogger
= tmpSpecificLogger
.replaceAll("\\s", ""); //$NON-NLS-1$ //$NON-NLS-2$
252 // Splitting the different events that are separated by commas
253 List
<String
> specificLoggerList
= Arrays
.asList(tmpSpecificLogger
.split(",")); //$NON-NLS-1$
254 fLoggers
.addAll(specificLoggerList
);
255 fLoggers
= fLoggers
.stream().distinct().collect(Collectors
.toList());
259 // initialize log level event name string
260 fLogLevelType
= LogLevelType
.LOGLEVEL_NONE
;
262 if (fLogLevelButton
.getSelection()) {
263 fLogLevelType
= LogLevelType
.LOGLEVEL
;
264 } else if (fLogLevelOnlyButton
.getSelection()) {
265 fLogLevelType
= LogLevelType
.LOGLEVEL_ONLY
;
268 ITraceLogLevel
[] levels
= getLogLevelNames();
269 int id
= fLogLevelCombo
.getSelectionIndex();
272 MessageDialog
.openError(getShell(),
273 Messages
.TraceControl_EnableLoggersDialogTitle
,
274 Messages
.TraceControl_InvalidLogLevel
);
279 if (fLoggers
.isEmpty() && !fIsAllLoggers
) {
280 MessageDialog
.openError(getShell(),
281 Messages
.TraceControl_EnableLoggersDialogTitle
,
282 Messages
.TraceControl_InvalidLogger
);
286 if (levels
!= null) {
287 fLogLevel
= levels
[id
];
291 // validation successful -> call super.okPressed()
295 // ------------------------------------------------------------------------
297 // ------------------------------------------------------------------------
299 private ITraceLogLevel
[] getLogLevelNames() {
302 return TraceJulLogLevel
.values();
304 return TraceLog4jLogLevel
.values();
306 return TracePythonLogLevel
.values();
314 * Creates loggers group.
316 private void createLoggersGroup() {
317 // Create the loggers group
318 Group loggersMainGroup
= new Group(this, SWT
.SHADOW_NONE
);
319 loggersMainGroup
.setText(Messages
.TraceControl_EnableEventsLoggerGroupName
);
320 GridLayout layout
= new GridLayout(2, false);
321 loggersMainGroup
.setLayout(layout
);
322 GridData data
= new GridData(GridData
.FILL_BOTH
);
323 loggersMainGroup
.setLayoutData(data
);
325 // Create the Select button
326 Composite buttonComposite
= new Composite(loggersMainGroup
, SWT
.NONE
);
327 layout
= new GridLayout(1, true);
328 buttonComposite
.setLayout(layout
);
329 data
= new GridData(SWT
.BEGINNING
, SWT
.CENTER
, false, true);
330 buttonComposite
.setLayoutData(data
);
332 fLoggersActivateButton
= new Button(buttonComposite
, SWT
.RADIO
);
333 fLoggersActivateButton
.setText(Messages
.TraceControl_EnableGroupSelectionName
);
334 data
= new GridData(GridData
.FILL_HORIZONTAL
);
335 fLoggersActivateButton
.setLayoutData(data
);
336 fLoggersActivateButton
.addSelectionListener(new SelectionAdapter() {
338 public void widgetSelected(SelectionEvent e
) {
339 setEnablements(GroupEnum
.LOGGERS
);
343 // Create the group for the tree
344 Group loggersGroup
= new Group(loggersMainGroup
, SWT
.SHADOW_NONE
);
345 layout
= new GridLayout(1, true);
346 loggersGroup
.setLayout(layout
);
347 data
= new GridData(GridData
.FILL_BOTH
);
348 loggersGroup
.setLayoutData(data
);
349 new FilteredTree(loggersGroup
, SWT
.MULTI
| SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.BORDER
, new PatternFilter(), true) {
351 protected TreeViewer
doCreateTreeViewer(Composite aparent
, int style
) {
352 fLoggersViewer
= new CheckboxTreeViewer(aparent
, SWT
.MULTI
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
353 fLoggersViewer
.getTree().setToolTipText(Messages
.TraceControl_EnableEventsLoggerTreeTooltip
);
354 fLoggersViewer
.setContentProvider(new LoggersContentProvider());
356 fLoggersViewer
.setLabelProvider(new LoggersLabelProvider());
357 fLoggersViewer
.addCheckStateListener(new LoggersCheckStateListener());
359 fLoggersViewer
.setInput(fProviderGroup
.getParent());
360 fLoggersViewer
.getTree().setLayoutData(new GridData(GridData
.FILL_BOTH
));
361 return fLoggersViewer
;
365 Group specificLoggerGroup
= new Group(loggersGroup
, SWT
.SHADOW_NONE
);
366 specificLoggerGroup
.setText(Messages
.TraceControl_EnableEventsSpecificLoggerGroupName
);
367 layout
= new GridLayout(4, true);
368 specificLoggerGroup
.setLayout(layout
);
369 specificLoggerGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
371 Label specificLoggerLabel
= new Label(specificLoggerGroup
, SWT
.LEFT
);
372 specificLoggerLabel
.setText(Messages
.TraceControl_EnableEventsNameLabel
);
373 data
= new GridData(GridData
.FILL_HORIZONTAL
);
374 data
.horizontalSpan
= 1;
375 specificLoggerLabel
.setLayoutData(data
);
377 fSpecificLoggerText
= new Text(specificLoggerGroup
, SWT
.LEFT
);
378 fSpecificLoggerText
.setToolTipText(Messages
.TraceControl_EnableEventsSpecificLoggerTooltip
);
379 data
= new GridData(GridData
.FILL_HORIZONTAL
);
380 data
.horizontalSpan
= 3;
381 fSpecificLoggerText
.setLayoutData(data
);
385 * Creates log level group.
387 private void createLogLevelGroup() {
388 Group logLevelMainGroup
= new Group(this, SWT
.SHADOW_NONE
);
389 logLevelMainGroup
.setText(Messages
.TraceControl_EnableEventsLogLevelGroupName
);
390 GridLayout layout
= new GridLayout(2, false);
391 logLevelMainGroup
.setLayout(layout
);
392 GridData data
= new GridData(GridData
.FILL_HORIZONTAL
);
393 logLevelMainGroup
.setLayoutData(data
);
395 Composite buttonComposite
= new Composite(logLevelMainGroup
, SWT
.NONE
);
396 layout
= new GridLayout(1, false);
397 buttonComposite
.setLayout(layout
);
398 data
= new GridData(SWT
.BEGINNING
, SWT
.CENTER
, false, true);
399 buttonComposite
.setLayoutData(data
);
401 fLogLevelActivateButton
= new Button(buttonComposite
, SWT
.CHECK
);
402 fLogLevelActivateButton
.setText(Messages
.TraceControl_EnableGroupSelectionName
);
403 fLogLevelActivateButton
.setSelection(false);
404 data
= new GridData(GridData
.FILL_HORIZONTAL
);
405 fLogLevelActivateButton
.setLayoutData(data
);
406 fLogLevelActivateButton
.addSelectionListener(new SelectionAdapter() {
408 public void widgetSelected(SelectionEvent e
) {
409 fLogLevelCombo
.setEnabled(fLogLevelActivateButton
.getSelection());
410 fLogLevelButton
.setEnabled(fLogLevelActivateButton
.getSelection());
411 fLogLevelOnlyButton
.setEnabled(fLogLevelActivateButton
.getSelection());
415 Group logLevelGroup
= new Group(logLevelMainGroup
, SWT
.SHADOW_NONE
);
416 layout
= new GridLayout(2, true);
417 logLevelGroup
.setLayout(layout
);
418 logLevelGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
420 fLogLevelButton
= new Button(logLevelGroup
, SWT
.RADIO
);
421 fLogLevelButton
.setText(Messages
.TraceControl_EnableEventsLogLevelTypeName
);
422 fLogLevelButton
.setToolTipText(Messages
.TraceControl_EnableEventsLogLevelTypeTooltip
);
423 data
= new GridData(GridData
.FILL_BOTH
);
424 fLogLevelButton
.setLayoutData(data
);
425 fLogLevelButton
.setSelection(true);
427 fLogLevelOnlyButton
= new Button(logLevelGroup
, SWT
.RADIO
);
428 fLogLevelOnlyButton
.setText(Messages
.TraceControl_EnableEventsLogLevelOnlyTypeName
);
429 fLogLevelOnlyButton
.setToolTipText(Messages
.TraceControl_EnableEventsLogLevelOnlyTypeTooltip
);
430 data
= new GridData(GridData
.FILL_BOTH
);
431 fLogLevelButton
.setLayoutData(data
);
433 fLogLevelCombo
= new CCombo(logLevelGroup
, SWT
.READ_ONLY
);
434 ITraceLogLevel
[] levels
= getLogLevelNames();
435 if (levels
!= null) {
436 String
[] levelNames
= new String
[levels
.length
- 1];
438 for (int i
= 0; i
< levels
.length
; i
++) {
439 if (levels
[i
] != TraceJulLogLevel
.LEVEL_UNKNOWN
&&
440 levels
[i
] != TraceLog4jLogLevel
.LEVEL_UNKNOWN
&&
441 levels
[i
] != TracePythonLogLevel
.LEVEL_UNKNOWN
) {
442 levelNames
[k
++] = levels
[i
].getInName();
445 fLogLevelCombo
.setItems(levelNames
);
448 fLogLevelCombo
.setToolTipText(Messages
.TraceControl_EnableEventsLogLevelTooltip
);
449 data
= new GridData(GridData
.FILL_HORIZONTAL
);
450 data
.horizontalSpan
= 4;
451 fLogLevelCombo
.setLayoutData(data
);
453 // By default the combo box and the buttons are not enabled
454 fLogLevelCombo
.setEnabled(false);
455 fLogLevelButton
.setEnabled(false);
456 fLogLevelOnlyButton
.setEnabled(false);
461 * Enable/selects widgets depending on the group specified.
466 private void setEnablements(GroupEnum group
) {
468 // Enable/disable trace point items
469 fLoggersActivateButton
.setSelection(group
== GroupEnum
.LOGGERS
);
470 fLoggersViewer
.getTree().setEnabled(group
== GroupEnum
.LOGGERS
);
474 * Content provider for the loggers tree.
476 public final class LoggersContentProvider
extends TraceControlContentProvider
{
478 public Object
[] getChildren(Object parentElement
) {
479 if (parentElement
instanceof TargetNodeComponent
) {
480 List
<ITraceControlComponent
> children
= ((ITraceControlComponent
) parentElement
).getChildren(TraceProviderGroup
.class);
481 return children
.toArray(new ITraceControlComponent
[children
.size()]);
483 if (parentElement
instanceof TraceProviderGroup
) {
484 List
<ITraceControlComponent
> ustProviderChildren
= ((ITraceControlComponent
) parentElement
).getChildren(UstProviderComponent
.class)
485 .stream().filter(comp
-> ((UstProviderComponent
) comp
).getLoggerComponents(fDomain
).size() > 0)
486 .collect(Collectors
.toList());
487 return ustProviderChildren
.toArray(new ITraceControlComponent
[ustProviderChildren
.size()]);
489 if (parentElement
instanceof UstProviderComponent
) {
490 List
<ITraceControlComponent
> loggers
= ((UstProviderComponent
) parentElement
).getLoggerComponents(fDomain
);
491 return loggers
.toArray(new ITraceControlComponent
[loggers
.size()]);
493 return new Object
[0];
498 * Content label for the loggers tree.
500 public static final class LoggersLabelProvider
extends TraceControlLabelProvider
{
502 public Image
getImage(Object element
) {
507 public String
getText(Object element
) {
508 if ((element
!= null) && (element
instanceof TraceProviderGroup
)) {
509 return Messages
.TraceControl_EnableEventsTreeAllLabel
;
512 if ((element
!= null) && (element
instanceof UstProviderComponent
)) {
513 return Messages
.TraceControl_EnableEventsTreeAllLabel
+ " - " + ((UstProviderComponent
)element
).getName(); //$NON-NLS-1$
515 return super.getText(element
);
520 * Check state listener for the loggers tree.
522 public final class LoggersCheckStateListener
implements ICheckStateListener
{
524 public void checkStateChanged(CheckStateChangedEvent event
) {
525 if (event
.getChecked()) {
526 if (event
.getElement() instanceof TraceProviderGroup
) {
527 fLoggersViewer
.setSubtreeChecked(event
.getElement(), true);
529 if (event
.getElement() instanceof UstProviderComponent
) {
530 fLoggersViewer
.setSubtreeChecked(event
.getElement(), true);
533 if (event
.getElement() instanceof TraceProviderGroup
) {
534 fLoggersViewer
.setSubtreeChecked(event
.getElement(), true);
536 if (event
.getElement() instanceof UstProviderComponent
) {
537 ITraceControlComponent component
= (ITraceControlComponent
) event
.getElement();
538 fLoggersViewer
.setSubtreeChecked(event
.getElement(), false);
539 fLoggersViewer
.setChecked(component
.getParent(), false);
541 ITraceControlComponent component
= (ITraceControlComponent
) event
.getElement();
542 fLoggersViewer
.setChecked(component
.getParent(), false);
543 fLoggersViewer
.setChecked(component
.getParent().getParent(), false);