Commit | Line | Data |
---|---|---|
6503ae0f | 1 | /********************************************************************** |
60ae41e1 | 2 | * Copyright (c) 2012, 2014 Ericsson |
cfdb727a | 3 | * |
6503ae0f BH |
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 | |
cfdb727a AM |
8 | * |
9 | * Contributors: | |
6503ae0f BH |
10 | * Bernd Hufmann - Initial API and implementation |
11 | **********************************************************************/ | |
9bc60be7 | 12 | package org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers; |
6503ae0f BH |
13 | |
14 | import java.util.ArrayList; | |
15 | import java.util.Iterator; | |
16 | import java.util.List; | |
17 | ||
6503ae0f BH |
18 | import org.eclipse.core.commands.ExecutionEvent; |
19 | import org.eclipse.core.commands.ExecutionException; | |
20 | import org.eclipse.core.runtime.IProgressMonitor; | |
21 | import org.eclipse.core.runtime.IStatus; | |
22 | import org.eclipse.core.runtime.Status; | |
23 | import org.eclipse.core.runtime.jobs.Job; | |
24 | import org.eclipse.jface.viewers.ISelection; | |
25 | import org.eclipse.jface.viewers.StructuredSelection; | |
9bc60be7 | 26 | import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEnablement; |
207ff523 | 27 | import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEventType; |
9bc60be7 AM |
28 | import org.eclipse.tracecompass.internal.lttng2.control.ui.Activator; |
29 | import org.eclipse.tracecompass.internal.lttng2.control.ui.views.ControlView; | |
30 | import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; | |
31 | import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceChannelComponent; | |
32 | import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceEventComponent; | |
33 | import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent; | |
6503ae0f | 34 | import org.eclipse.ui.IWorkbenchPage; |
6503ae0f BH |
35 | import org.eclipse.ui.IWorkbenchWindow; |
36 | import org.eclipse.ui.PlatformUI; | |
37 | ||
38 | /** | |
6503ae0f BH |
39 | * <p> |
40 | * Base Command handler implementation to enable or disabling a trace channel. | |
41 | * </p> | |
cfdb727a | 42 | * |
dbd4432d | 43 | * @author Bernd Hufmann |
6503ae0f | 44 | */ |
77735e82 | 45 | public abstract class ChangeEventStateHandler extends BaseControlViewHandler { |
6503ae0f BH |
46 | |
47 | // ------------------------------------------------------------------------ | |
48 | // Attributes | |
49 | // ------------------------------------------------------------------------ | |
50 | /** | |
c56972bb | 51 | * The command execution parameter. |
6503ae0f | 52 | */ |
c56972bb | 53 | protected Parameter fParam; |
cfdb727a | 54 | |
6503ae0f BH |
55 | // ------------------------------------------------------------------------ |
56 | // Accessors | |
57 | // ------------------------------------------------------------------------ | |
58 | /** | |
59 | * @return the new state to set | |
60 | */ | |
77735e82 | 61 | protected abstract TraceEnablement getNewState(); |
6503ae0f BH |
62 | |
63 | // ------------------------------------------------------------------------ | |
64 | // Operations | |
65 | // ------------------------------------------------------------------------ | |
66 | /** | |
67 | * Change the state | |
68 | * @param channel - channel of events to be enabled | |
cfdb727a | 69 | * @param eventNames - list event names |
207ff523 | 70 | * @param eventType - the event type ({@link TraceEventType}) |
6503ae0f | 71 | * @param monitor - a progress monitor |
6f4e8ec0 | 72 | * @throws ExecutionException If the command fails |
6503ae0f | 73 | */ |
207ff523 | 74 | protected abstract void changeState(TraceChannelComponent channel, List<String> eventNames, TraceEventType eventType, IProgressMonitor monitor) throws ExecutionException; |
6503ae0f | 75 | |
6503ae0f BH |
76 | @Override |
77 | public Object execute(ExecutionEvent event) throws ExecutionException { | |
78 | ||
79 | IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); | |
80 | ||
81 | if (window == null) { | |
82 | return false; | |
83 | } | |
84 | ||
c56972bb BH |
85 | fLock.lock(); |
86 | try { | |
cfdb727a | 87 | |
c56972bb BH |
88 | final Parameter param = new Parameter(fParam); |
89 | ||
90 | Job job = new Job(Messages.TraceControl_ChangeChannelStateJob) { | |
91 | @Override | |
92 | protected IStatus run(IProgressMonitor monitor) { | |
f455db37 | 93 | Exception error = null; |
c56972bb BH |
94 | |
95 | TraceSessionComponent session = null; | |
96 | ||
97 | try { | |
98 | boolean isAll = false; | |
99 | if (param.getChannel() != null) { | |
100 | session = param.getChannel().getSession(); | |
e0838ca1 | 101 | List<String> eventNames = new ArrayList<>(); |
c56972bb | 102 | List<TraceEventComponent> events = param.getEvents(); |
207ff523 BR |
103 | // Find the type of the events (all the events in the list are the same type) |
104 | TraceEventType eventType = !events.isEmpty() ? events.get(0).getEventType() : null; | |
cfdb727a | 105 | |
c56972bb BH |
106 | for (Iterator<TraceEventComponent> iterator = events.iterator(); iterator.hasNext();) { |
107 | // Enable/disable all selected channels which are disabled | |
ea21cd65 | 108 | TraceEventComponent traceEvent = iterator.next(); |
c56972bb BH |
109 | |
110 | // Workaround for wildcard handling in lttng-tools | |
ea21cd65 | 111 | if ("*".equals(traceEvent.getName())) { //$NON-NLS-1$ |
c56972bb | 112 | isAll = true; |
cfdb727a | 113 | } else { |
ea21cd65 | 114 | eventNames.add(traceEvent.getName()); |
c56972bb BH |
115 | } |
116 | } | |
117 | if (isAll) { | |
207ff523 | 118 | changeState(param.getChannel(), null, eventType, monitor); |
3e91c9c0 | 119 | } |
3e91c9c0 | 120 | |
c56972bb | 121 | if (!eventNames.isEmpty()) { |
207ff523 | 122 | changeState(param.getChannel(), eventNames, eventType, monitor); |
c56972bb | 123 | } |
6503ae0f | 124 | |
c56972bb BH |
125 | for (Iterator<TraceEventComponent> iterator = events.iterator(); iterator.hasNext();) { |
126 | // Enable all selected channels which are disabled | |
cfdb727a | 127 | TraceEventComponent ev = iterator.next(); |
c56972bb BH |
128 | ev.setState(getNewState()); |
129 | } | |
6503ae0f | 130 | } |
c56972bb | 131 | } catch (ExecutionException e) { |
f455db37 | 132 | error = e; |
6503ae0f | 133 | } |
6503ae0f | 134 | |
c56972bb | 135 | if (session != null) { |
cfdb727a | 136 | // In all cases notify listeners |
c56972bb BH |
137 | session.fireComponentChanged(session); |
138 | } | |
6503ae0f | 139 | |
f455db37 | 140 | if (error != null) { |
cfdb727a | 141 | return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TraceControl_ChangeEventStateFailure, error); |
c56972bb | 142 | } |
6503ae0f | 143 | |
c56972bb BH |
144 | return Status.OK_STATUS; |
145 | } | |
146 | }; | |
147 | job.setUser(true); | |
148 | job.schedule(); | |
149 | } finally { | |
150 | fLock.unlock(); | |
151 | } | |
6503ae0f BH |
152 | return null; |
153 | } | |
154 | ||
6503ae0f BH |
155 | @Override |
156 | public boolean isEnabled() { | |
498704b3 BH |
157 | // Get workbench page for the Control View |
158 | IWorkbenchPage page = getWorkbenchPage(); | |
6503ae0f BH |
159 | if (page == null) { |
160 | return false; | |
161 | } | |
162 | ||
6503ae0f BH |
163 | // Check if one or more session are selected |
164 | ISelection selection = page.getSelection(ControlView.ID); | |
cfdb727a | 165 | |
c56972bb | 166 | TraceChannelComponent channel = null; |
e0838ca1 | 167 | List<TraceEventComponent> events = new ArrayList<>(); |
c56972bb | 168 | |
6503ae0f BH |
169 | if (selection instanceof StructuredSelection) { |
170 | StructuredSelection structered = ((StructuredSelection) selection); | |
171 | String sessionName = null; | |
172 | String channelName = null; | |
207ff523 | 173 | TraceEventType eventType = null; |
cfdb727a | 174 | |
6503ae0f | 175 | for (Iterator<?> iterator = structered.iterator(); iterator.hasNext();) { |
cfdb727a AM |
176 | Object element = iterator.next(); |
177 | ||
6503ae0f | 178 | if (element instanceof TraceEventComponent) { |
cfdb727a | 179 | |
3e91c9c0 | 180 | TraceEventComponent event = (TraceEventComponent) element; |
6503ae0f | 181 | if (sessionName == null) { |
3e91c9c0 | 182 | sessionName = String.valueOf(event.getSessionName()); |
6503ae0f | 183 | } |
cfdb727a | 184 | |
c56972bb BH |
185 | if (channel == null) { |
186 | channel = (TraceChannelComponent)event.getParent(); | |
6503ae0f BH |
187 | } |
188 | ||
189 | if (channelName == null) { | |
3e91c9c0 | 190 | channelName = event.getChannelName(); |
6503ae0f | 191 | } |
3e91c9c0 | 192 | |
6503ae0f | 193 | // Enable command only for events of same session, same channel and domain |
3e91c9c0 BH |
194 | if ((!sessionName.equals(event.getSessionName())) || |
195 | (!channelName.equals(event.getChannelName())) || | |
1bc37054 | 196 | (!channel.getDomain().equals(event.getDomain()))) { |
c56972bb | 197 | events.clear(); |
6503ae0f BH |
198 | break; |
199 | } | |
200 | ||
207ff523 BR |
201 | // The events have to be the same type |
202 | if (eventType == null) { | |
203 | eventType = event.getEventType(); | |
204 | } else if (!eventType.equals(event.getEventType())) { | |
205 | events.clear(); | |
206 | break; | |
207 | } | |
208 | ||
3e91c9c0 | 209 | if ((event.getState() != getNewState())) { |
c56972bb | 210 | events.add(event); |
6503ae0f BH |
211 | } |
212 | } | |
213 | } | |
214 | } | |
c56972bb BH |
215 | boolean isEnabled = !events.isEmpty(); |
216 | ||
217 | fLock.lock(); | |
218 | try { | |
219 | fParam = null; | |
220 | if (isEnabled) { | |
221 | fParam = new Parameter(channel, events); | |
222 | } | |
223 | } finally { | |
224 | fLock.unlock(); | |
225 | } | |
226 | return isEnabled; | |
6503ae0f BH |
227 | } |
228 | ||
229 | /** | |
cfdb727a | 230 | * Class containing parameter for the command execution. |
6503ae0f | 231 | */ |
77735e82 | 232 | protected static class Parameter { |
c56972bb BH |
233 | /** |
234 | * Channel component reference. | |
235 | */ | |
77735e82 | 236 | private final TraceChannelComponent fChannel; |
c56972bb | 237 | /** |
cfdb727a | 238 | * The list of kernel channel components the command is to be executed on. |
c56972bb | 239 | */ |
e0838ca1 | 240 | private final List<TraceEventComponent> fEvents = new ArrayList<>(); |
cfdb727a | 241 | |
5293eb3f BH |
242 | /** |
243 | * Constructor | |
244 | * @param channel - a channel component | |
245 | * @param events - a list of event components | |
246 | */ | |
c56972bb BH |
247 | public Parameter(TraceChannelComponent channel, List<TraceEventComponent> events) { |
248 | fChannel = channel; | |
249 | fEvents.addAll(events); | |
250 | } | |
cfdb727a | 251 | |
c56972bb BH |
252 | /** |
253 | * Copy constructor | |
254 | * @param other - a parameter to copy | |
255 | */ | |
256 | public Parameter(Parameter other) { | |
257 | this(other.fChannel, other.fEvents); | |
258 | } | |
cfdb727a | 259 | |
c56972bb BH |
260 | /** |
261 | * @return the trace channel component. | |
262 | */ | |
263 | public TraceChannelComponent getChannel() { | |
264 | return fChannel; | |
265 | } | |
cfdb727a | 266 | |
c56972bb BH |
267 | /** |
268 | * @return a list of trace event components. | |
269 | */ | |
270 | public List<TraceEventComponent> getEvents() { | |
271 | return fEvents; | |
272 | } | |
6503ae0f BH |
273 | } |
274 | } |