lttng.control: Add support for enabling syscall by name
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.control.ui / src / org / eclipse / tracecompass / internal / lttng2 / control / ui / views / handlers / AssignEventHandler.java
1 /**********************************************************************
2 * Copyright (c) 2012, 2015 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 * Bernd Hufmann - Initial API and implementation
11 * Bernd Hufmann - Updated for support of LTTng Tools 2.1
12 **********************************************************************/
13 package org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import org.eclipse.core.commands.ExecutionEvent;
21 import org.eclipse.core.commands.ExecutionException;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.core.runtime.jobs.Job;
26 import org.eclipse.jdt.annotation.NonNull;
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jface.viewers.ISelection;
29 import org.eclipse.jface.viewers.StructuredSelection;
30 import org.eclipse.jface.window.Window;
31 import org.eclipse.tracecompass.common.core.NonNullUtils;
32 import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceDomainType;
33 import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEventType;
34 import org.eclipse.tracecompass.internal.lttng2.control.ui.Activator;
35 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.ControlView;
36 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.IGetEventInfoDialog;
37 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.TraceControlDialogFactory;
38 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages;
39 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.ITraceControlComponent;
40 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.BaseEventComponent;
41 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.KernelProviderComponent;
42 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TargetNodeComponent;
43 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceChannelComponent;
44 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent;
45 import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.UstProviderComponent;
46 import org.eclipse.ui.IWorkbenchPage;
47
48 /**
49 * <p>
50 * Command handler implementation to assign events to a session and channel and enable/configure them.
51 * This is done on the trace provider level.
52 * </p>
53 *
54 * @author Bernd Hufmann
55 */
56 public class AssignEventHandler extends BaseControlViewHandler {
57
58 // ------------------------------------------------------------------------
59 // Attributes
60 // ------------------------------------------------------------------------
61
62 /**
63 * The command execution parameter.
64 */
65 private Parameter fParam;
66
67 // ------------------------------------------------------------------------
68 // Operations
69 // ------------------------------------------------------------------------
70
71 @Override
72 public Object execute(ExecutionEvent event) throws ExecutionException {
73 // Make a copy for thread safety
74 Parameter tmpParam = null;
75 fLock.lock();
76 try {
77 tmpParam = fParam;
78 if (tmpParam == null) {
79 return null;
80 }
81 tmpParam = new Parameter(tmpParam);
82 } finally {
83 fLock.unlock();
84 }
85 final Parameter param = tmpParam;
86
87 // Open dialog box to retrieve the session and channel where the events should be enabled in.
88 final IGetEventInfoDialog dialog = TraceControlDialogFactory.getInstance().getGetEventInfoDialog();
89 dialog.setDomain(param.getDomain());
90 dialog.setSessions(param.getSessions());
91
92 if (dialog.open() != Window.OK) {
93 return null;
94 }
95
96 Job job = new Job(Messages.TraceControl_EnableEventsJob) {
97 @Override
98 protected IStatus run(IProgressMonitor monitor) {
99
100 Exception error = null;
101 TraceSessionComponent session = dialog.getSession();
102 try {
103 List<String> eventNames = new ArrayList<>();
104 List<BaseEventComponent> events = param.getEvents();
105 // Find the type of the events (all the events in the list are the same type)
106 TraceEventType eventType = !events.isEmpty() ? events.get(0).getEventType() : null;
107 // Create list of event names
108 for (Iterator<BaseEventComponent> iterator = events.iterator(); iterator.hasNext();) {
109 BaseEventComponent baseEvent = iterator.next();
110 eventNames.add(baseEvent.getName());
111 }
112
113 TraceChannelComponent channel = dialog.getChannel();
114 if (TraceEventType.TRACEPOINT.equals(eventType)) {
115 if (channel == null) {
116 // enable events on default channel (which will be created by lttng-tools)
117 session.enableEvents(eventNames, param.getDomain(), dialog.getFilterExpression(), null, monitor);
118 } else {
119 channel.enableEvents(eventNames, dialog.getFilterExpression(), null, monitor);
120 }
121 } else if (TraceEventType.SYSCALL.equals(eventType)) {
122 if (channel == null) {
123 session.enableSyscalls(eventNames, monitor);
124 } else {
125 channel.enableSyscalls(eventNames, monitor);
126 }
127 }
128
129 } catch (ExecutionException e) {
130 error = e;
131 }
132
133 // refresh in all cases
134 if (session != null) {
135 refresh(new CommandParameter(session));
136 }
137
138 if (error != null) {
139 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TraceControl_EnableEventsFailure, error);
140 }
141 return Status.OK_STATUS;
142 }
143 };
144 job.setUser(true);
145 job.schedule();
146
147 return null;
148 }
149
150 @Override
151 public boolean isEnabled() {
152 @NonNull ArrayList<@NonNull BaseEventComponent> events = new ArrayList<>();
153 @NonNull TraceSessionComponent[] sessions = null;
154 TraceDomainType domain = null;
155 TraceEventType eventType = null;
156
157 // Get workbench page for the Control View
158 IWorkbenchPage page = getWorkbenchPage();
159 if (page == null) {
160 return false;
161 }
162
163 // Check if one or more session are selected
164 ISelection selection = page.getSelection(ControlView.ID);
165 if (selection instanceof StructuredSelection) {
166
167 StructuredSelection structered = ((StructuredSelection) selection);
168 for (Iterator<?> iterator = structered.iterator(); iterator.hasNext();) {
169 Object element = iterator.next();
170 if (element instanceof BaseEventComponent) {
171 BaseEventComponent event = (BaseEventComponent) element;
172 ITraceControlComponent provider = event.getParent();
173
174 // check for the domain provider
175 TraceDomainType temp = null;
176 if (provider instanceof KernelProviderComponent) {
177 temp = TraceDomainType.KERNEL;
178 } else if (provider instanceof UstProviderComponent) {
179 temp = TraceDomainType.UST; // Loggers are under the UST domain
180 } else {
181 return false;
182 }
183
184 if (domain == null) {
185 domain = temp;
186 } else {
187 // don't mix events from Kernel and UST provider
188 if (!domain.equals(temp)) {
189 return false;
190 }
191 }
192 // The events have to be the same type
193 if (eventType == null) {
194 eventType = event.getEventType();
195 } else if (!eventType.equals(event.getEventType())) {
196 events.clear();
197 break;
198 }
199
200 // Add BaseEventComponents
201 events.add(event);
202
203 if (sessions == null) {
204 TargetNodeComponent root = (TargetNodeComponent)event.getParent().getParent().getParent();
205 sessions = root.getSessions();
206 }
207 }
208 }
209 }
210
211 boolean isEnabled = ((!events.isEmpty()) && (sessions != null) && (sessions.length > 0));
212
213 // To avoid compiler warnings check for null even if isKernel is always not null when used below
214 if (domain == null) {
215 return false;
216 }
217
218 fLock.lock();
219 try {
220 fParam = null;
221 if(isEnabled) {
222 fParam = new Parameter(NonNullUtils.checkNotNull(sessions), events, domain);
223 }
224 } finally {
225 fLock.unlock();
226 }
227 return isEnabled;
228 }
229
230 /**
231 * Class containing parameter for the command execution.
232 */
233 @NonNullByDefault
234 private static final class Parameter {
235
236 /**
237 * The list of event components the command is to be executed on.
238 */
239 private final List<BaseEventComponent> fEvents;
240
241 /**
242 * The list of available sessions.
243 */
244 private final @NonNull TraceSessionComponent[] fSessions;
245
246 /**
247 * The domain type ({@link TraceDomainType})
248 */
249 private final TraceDomainType fDomain;
250
251 /**
252 * Constructor
253 *
254 * @param sessions - a array of trace sessions
255 * @param events - a lists of events to enable
256 * @param domain - domain type ({@link TraceDomainType})
257 */
258 public Parameter(@NonNull TraceSessionComponent[] sessions, List<BaseEventComponent> events, TraceDomainType domain) {
259 fSessions = NonNullUtils.checkNotNull(Arrays.copyOf(sessions, sessions.length));
260 fEvents = new ArrayList<>();
261 fEvents.addAll(events);
262 fDomain = domain;
263 }
264
265 /**
266 * Copy constructor
267 * @param other - a parameter to copy
268 */
269 public Parameter(Parameter other) {
270 this(other.fSessions, other.fEvents, other.fDomain);
271 }
272
273 public TraceSessionComponent[] getSessions() {
274 return fSessions;
275 }
276
277 public List<BaseEventComponent> getEvents() {
278 return fEvents;
279 }
280
281 public TraceDomainType getDomain() {
282 return fDomain;
283 }
284 }
285 }
This page took 0.03858 seconds and 5 git commands to generate.