lttng.control: Fix: Allowing loglevel when enabling all loggers
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.control.ui / src / org / eclipse / tracecompass / internal / lttng2 / control / ui / views / dialogs / EnableLoggersComposite.java
1 /**********************************************************************
2 * Copyright (c) 2016 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Bruno Roy - Initial API and implementation
11 **********************************************************************/
12 package org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs;
13
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
19 import java.util.stream.Collectors;
20
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;
54
55 /**
56 * A composite for collecting information about loggers to be enabled.
57 *
58 * @author Bruno Roy
59 */
60 public class EnableLoggersComposite extends Composite implements IBaseEnableUstEvents {
61
62 // ------------------------------------------------------------------------
63 // Constants
64 // ------------------------------------------------------------------------
65
66 private enum GroupEnum { LOGGERS }
67
68 // ------------------------------------------------------------------------
69 // Attributes
70 // ------------------------------------------------------------------------
71
72 /**
73 * The referenced trace provider group containing the loggers providers
74 * component which contains a list of available tracepoints.
75 */
76 private final TraceProviderGroup fProviderGroup;
77 /**
78 * A button to enable/disable the loggers group
79 */
80 private Button fLoggersActivateButton;
81 /**
82 * A tree viewer for displaying and selection of available loggers.
83 */
84 private CheckboxTreeViewer fLoggersViewer;
85 /**
86 * A Text field for the specific logger name.
87 */
88 private Text fSpecificLoggerText;
89 /**
90 * The flag indicating that loggers are selected.
91 */
92 private boolean fIsLoggers;
93 /**
94 * The list of loggers to be enabled.
95 */
96 private List<String> fLoggers;
97 /**
98 * A button to enable/disable the log level group
99 */
100 private Button fLogLevelActivateButton;
101 /**
102 * A Combo box for selecting the log level.
103 */
104 private CCombo fLogLevelCombo;
105 /**
106 * A button for selecting the log level (range 0 to level).
107 */
108 private Button fLogLevelButton;
109 /**
110 * A button for selecting the specified log level only.
111 */
112 private Button fLogLevelOnlyButton;
113 /**
114 * The flag indicating that all log level are selected.
115 */
116 private boolean fIsLogLevel;
117 /**
118 * The flag indicating that all loggers (across providers) are selected.
119 */
120 private boolean fIsAllLoggers;
121 /**
122 * The type of the log level (loglevel or loglevel-only)
123 */
124 private LogLevelType fLogLevelType;
125 /**
126 * The selected log level.
127 */
128 private ITraceLogLevel fLogLevel;
129 /**
130 * The domain of the loggers.
131 */
132 private final TraceDomainType fDomain;
133
134 // ------------------------------------------------------------------------
135 // Constructors
136 // ------------------------------------------------------------------------
137 /**
138 * Constructor
139 *
140 * @param parent
141 * a parent composite
142 * @param style
143 * a composite style
144 * @param providerGroup
145 * the trace provider group
146 * @param domain
147 * the domain of the loggers
148 */
149 public EnableLoggersComposite(Composite parent, int style, TraceProviderGroup providerGroup, TraceDomainType domain) {
150 super(parent, style);
151 fProviderGroup = providerGroup;
152 fDomain = domain;
153 }
154
155 // ------------------------------------------------------------------------
156 // Accessors
157 // ------------------------------------------------------------------------
158
159 @Override
160 public ITraceLogLevel getLogLevel() {
161 return fLogLevel;
162 }
163
164 @Override
165 public LogLevelType getLogLevelType() {
166 return fLogLevelType;
167 }
168
169 @Override
170 public boolean isAllTracePoints() {
171 return fIsAllLoggers;
172 }
173
174 @Override
175 public List<String> getEventNames() {
176 return new ArrayList<>(fLoggers);
177 }
178
179 @Override
180 public boolean isLogLevel() {
181 return fIsLogLevel;
182 }
183
184 // ------------------------------------------------------------------------
185 // Operations
186 // ------------------------------------------------------------------------
187
188 /**
189 * Create the contents of this event composite
190 */
191 public void createContent() {
192
193 // Logger group
194 createLoggersGroup();
195
196 // Log Level Group
197 createLogLevelGroup();
198
199 // Set default enablements
200 setEnablements(GroupEnum.LOGGERS);
201 }
202
203 /**
204 * Validates the loggers composite input data.
205 *
206 * @return true if configured data is valid and can be retrieved.
207 */
208 public boolean isValid() {
209
210 fIsLoggers = fLoggersActivateButton.getSelection();
211 fIsLogLevel = fLogLevelActivateButton.getSelection();
212
213 // Initialize loggers fields
214 fLoggers = new ArrayList<>();
215 if (fIsLoggers) {
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) {
222 checkedNbLoggers++;
223 if (!set.contains(component.getName())) {
224 set.add(component.getName());
225 fLoggers.add(component.getName());
226 }
227 }
228 }
229
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++;
239 }
240 }
241
242 }
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);
246
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());
256 }
257 }
258
259 // initialize log level event name string
260 fLogLevelType = LogLevelType.LOGLEVEL_NONE;
261 if (fIsLogLevel) {
262 if (fLogLevelButton.getSelection()) {
263 fLogLevelType = LogLevelType.LOGLEVEL;
264 } else if (fLogLevelOnlyButton.getSelection()) {
265 fLogLevelType = LogLevelType.LOGLEVEL_ONLY;
266 }
267
268 ITraceLogLevel[] levels = getLogLevelNames();
269 int id = fLogLevelCombo.getSelectionIndex();
270
271 if (id < 0) {
272 MessageDialog.openError(getShell(),
273 Messages.TraceControl_EnableLoggersDialogTitle,
274 Messages.TraceControl_InvalidLogLevel);
275
276 return false;
277 }
278
279 if (fLoggers.isEmpty() && !fIsAllLoggers) {
280 MessageDialog.openError(getShell(),
281 Messages.TraceControl_EnableLoggersDialogTitle,
282 Messages.TraceControl_InvalidLogger);
283
284 return false;
285 }
286 if (levels != null) {
287 fLogLevel = levels[id];
288 }
289 }
290
291 // validation successful -> call super.okPressed()
292 return true;
293 }
294
295 // ------------------------------------------------------------------------
296 // Helper methods
297 // ------------------------------------------------------------------------
298
299 private ITraceLogLevel[] getLogLevelNames() {
300 switch (fDomain) {
301 case JUL:
302 return TraceJulLogLevel.values();
303 case LOG4J:
304 return TraceLog4jLogLevel.values();
305 case PYTHON:
306 return TracePythonLogLevel.values();
307 //$CASES-OMITTED$
308 default:
309 return null;
310 }
311 }
312
313 /**
314 * Creates loggers group.
315 */
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);
324
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);
331
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() {
337 @Override
338 public void widgetSelected(SelectionEvent e) {
339 setEnablements(GroupEnum.LOGGERS);
340 }
341 });
342
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) {
350 @Override
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());
355
356 fLoggersViewer.setLabelProvider(new LoggersLabelProvider());
357 fLoggersViewer.addCheckStateListener(new LoggersCheckStateListener());
358
359 fLoggersViewer.setInput(fProviderGroup.getParent());
360 fLoggersViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
361 return fLoggersViewer;
362 }
363 };
364
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));
370
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);
376
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);
382 }
383
384 /**
385 * Creates log level group.
386 */
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);
394
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);
400
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() {
407 @Override
408 public void widgetSelected(SelectionEvent e) {
409 fLogLevelCombo.setEnabled(fLogLevelActivateButton.getSelection());
410 fLogLevelButton.setEnabled(fLogLevelActivateButton.getSelection());
411 fLogLevelOnlyButton.setEnabled(fLogLevelActivateButton.getSelection());
412 }
413 });
414
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));
419
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);
426
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);
432
433 fLogLevelCombo = new CCombo(logLevelGroup, SWT.READ_ONLY);
434 ITraceLogLevel[] levels = getLogLevelNames();
435 if (levels != null) {
436 String[] levelNames = new String[levels.length - 1];
437 int k = 0;
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();
443 }
444 }
445 fLogLevelCombo.setItems(levelNames);
446 }
447
448 fLogLevelCombo.setToolTipText(Messages.TraceControl_EnableEventsLogLevelTooltip);
449 data = new GridData(GridData.FILL_HORIZONTAL);
450 data.horizontalSpan = 4;
451 fLogLevelCombo.setLayoutData(data);
452
453 // By default the combo box and the buttons are not enabled
454 fLogLevelCombo.setEnabled(false);
455 fLogLevelButton.setEnabled(false);
456 fLogLevelOnlyButton.setEnabled(false);
457
458 }
459
460 /**
461 * Enable/selects widgets depending on the group specified.
462 *
463 * @param group
464 * group to enable.
465 */
466 private void setEnablements(GroupEnum group) {
467
468 // Enable/disable trace point items
469 fLoggersActivateButton.setSelection(group == GroupEnum.LOGGERS);
470 fLoggersViewer.getTree().setEnabled(group == GroupEnum.LOGGERS);
471 }
472
473 /**
474 * Content provider for the loggers tree.
475 */
476 public final class LoggersContentProvider extends TraceControlContentProvider {
477 @Override
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()]);
482 }
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()]);
488 }
489 if (parentElement instanceof UstProviderComponent) {
490 List<ITraceControlComponent> loggers = ((UstProviderComponent) parentElement).getLoggerComponents(fDomain);
491 return loggers.toArray(new ITraceControlComponent[loggers.size()]);
492 }
493 return new Object[0];
494 }
495 }
496
497 /**
498 * Content label for the loggers tree.
499 */
500 public static final class LoggersLabelProvider extends TraceControlLabelProvider {
501 @Override
502 public Image getImage(Object element) {
503 return null;
504 }
505
506 @Override
507 public String getText(Object element) {
508 if ((element != null) && (element instanceof TraceProviderGroup)) {
509 return Messages.TraceControl_EnableEventsTreeAllLabel;
510 }
511
512 if ((element != null) && (element instanceof UstProviderComponent)) {
513 return Messages.TraceControl_EnableEventsTreeAllLabel + " - " + ((UstProviderComponent)element).getName(); //$NON-NLS-1$
514 }
515 return super.getText(element);
516 }
517 }
518
519 /**
520 * Check state listener for the loggers tree.
521 */
522 public final class LoggersCheckStateListener implements ICheckStateListener {
523 @Override
524 public void checkStateChanged(CheckStateChangedEvent event) {
525 if (event.getChecked()) {
526 if (event.getElement() instanceof TraceProviderGroup) {
527 fLoggersViewer.setSubtreeChecked(event.getElement(), true);
528 }
529 if (event.getElement() instanceof UstProviderComponent) {
530 fLoggersViewer.setSubtreeChecked(event.getElement(), true);
531 }
532 } else {
533 if (event.getElement() instanceof TraceProviderGroup) {
534 fLoggersViewer.setSubtreeChecked(event.getElement(), true);
535 }
536 if (event.getElement() instanceof UstProviderComponent) {
537 ITraceControlComponent component = (ITraceControlComponent) event.getElement();
538 fLoggersViewer.setSubtreeChecked(event.getElement(), false);
539 fLoggersViewer.setChecked(component.getParent(), false);
540 } else {
541 ITraceControlComponent component = (ITraceControlComponent) event.getElement();
542 fLoggersViewer.setChecked(component.getParent(), false);
543 fLoggersViewer.setChecked(component.getParent().getParent(), false);
544 }
545 }
546 }
547 }
548 }
This page took 0.046191 seconds and 5 git commands to generate.