~ubuntu-branches/ubuntu/vivid/eclipse-linuxtools/vivid-proposed

« back to all changes in this revision

Viewing changes to lttng/org.eclipse.linuxtools.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/service/LTTngControlService.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam, Jakub Adam, tony mancill
  • Date: 2014-10-11 11:44:05 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20141011114405-yazjvxfzzhmi5sgj
Tags: 3.1.0-1
[ Jakub Adam ]
* New upstream release (Closes: #761524).
* Refreshed d/patches.
* Don't build removed feature org.eclipse.linuxtools.tools.launch
  - merged into org.eclipse.linuxtools.profiling.
* Use javac target 1.7.
* Build new feature org.eclipse.linuxtools.dataviewers.feature
  - required by Valgrind integration.
* Build-depend on eclipse-remote-services-api and eclipse-cdt-autotools.
* Bump Standards-Version to 3.9.6.
* Override incompatible-java-bytecode-format - linuxtools needs Java 7.
* Remove unused codeless-jar override.

[ tony mancill ]
* Tweak short package description to make lintian happy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 * Copyright (c) 2012, 2014 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
 *   Simon Delisle - Updated for support of LTTng Tools 2.2
 
13
 *   Marc-Andre Laperle - Support for creating a live session
 
14
 **********************************************************************/
 
15
package org.eclipse.linuxtools.internal.lttng2.control.ui.views.service;
 
16
 
 
17
import java.util.ArrayList;
 
18
import java.util.Iterator;
 
19
import java.util.List;
 
20
import java.util.regex.Matcher;
 
21
 
 
22
import org.eclipse.core.commands.ExecutionException;
 
23
import org.eclipse.core.runtime.IProgressMonitor;
 
24
import org.eclipse.core.runtime.NullProgressMonitor;
 
25
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IBaseEventInfo;
 
26
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IChannelInfo;
 
27
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IDomainInfo;
 
28
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IEventInfo;
 
29
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IFieldInfo;
 
30
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IProbeEventInfo;
 
31
import org.eclipse.linuxtools.internal.lttng2.control.core.model.ISessionInfo;
 
32
import org.eclipse.linuxtools.internal.lttng2.control.core.model.ISnapshotInfo;
 
33
import org.eclipse.linuxtools.internal.lttng2.control.core.model.IUstProviderInfo;
 
34
import org.eclipse.linuxtools.internal.lttng2.control.core.model.LogLevelType;
 
35
import org.eclipse.linuxtools.internal.lttng2.control.core.model.TraceEventType;
 
36
import org.eclipse.linuxtools.internal.lttng2.control.core.model.TraceLogLevel;
 
37
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.BaseEventInfo;
 
38
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.BufferType;
 
39
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.ChannelInfo;
 
40
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.DomainInfo;
 
41
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.EventInfo;
 
42
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.FieldInfo;
 
43
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.ProbeEventInfo;
 
44
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.SessionInfo;
 
45
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.SnapshotInfo;
 
46
import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.UstProviderInfo;
 
47
import org.eclipse.linuxtools.internal.lttng2.control.ui.views.logging.ControlCommandLogger;
 
48
import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages;
 
49
import org.eclipse.linuxtools.internal.lttng2.control.ui.views.preferences.ControlPreferences;
 
50
import org.eclipse.linuxtools.internal.lttng2.control.ui.views.remote.ICommandResult;
 
51
import org.eclipse.linuxtools.internal.lttng2.control.ui.views.remote.ICommandShell;
 
52
 
 
53
/**
 
54
 * <p>
 
55
 * Service for sending LTTng trace control commands to remote host.
 
56
 * </p>
 
57
 *
 
58
 * @author Bernd Hufmann
 
59
 */
 
60
public class LTTngControlService implements ILttngControlService {
 
61
 
 
62
    // ------------------------------------------------------------------------
 
63
    // Attributes
 
64
    // ------------------------------------------------------------------------
 
65
    /**
 
66
     * The command shell implementation
 
67
     */
 
68
    private final ICommandShell fCommandShell;
 
69
 
 
70
    /**
 
71
     * The version string.
 
72
     */
 
73
    private LttngVersion fVersion = null;
 
74
 
 
75
    // ------------------------------------------------------------------------
 
76
    // Constructors
 
77
    // ------------------------------------------------------------------------
 
78
 
 
79
    /**
 
80
     * Constructor
 
81
     *
 
82
     * @param shell
 
83
     *            - the command shell implementation to use
 
84
     */
 
85
    public LTTngControlService(ICommandShell shell) {
 
86
        fCommandShell = shell;
 
87
    }
 
88
 
 
89
    // ------------------------------------------------------------------------
 
90
    // Accessors
 
91
    // ------------------------------------------------------------------------
 
92
 
 
93
    @Override
 
94
    public String getVersion() {
 
95
        if (fVersion == null) {
 
96
            return "Unknown"; //$NON-NLS-1$
 
97
        }
 
98
        return fVersion.toString();
 
99
    }
 
100
 
 
101
    /**
 
102
     * Sets the version of the LTTng 2.0 control service.
 
103
     * @param version - a version to set
 
104
     */
 
105
    public void setVersion(String version) {
 
106
        fVersion = new LttngVersion(version);
 
107
    }
 
108
 
 
109
    @Override
 
110
    public boolean isVersionSupported(String version) {
 
111
        LttngVersion tmp = new LttngVersion(version);
 
112
        return (fVersion != null && fVersion.compareTo(tmp) >= 0) ? true : false;
 
113
    }
 
114
 
 
115
    /**
 
116
     * Returns the command shell implementation.
 
117
     *
 
118
     * @return the command shell implementation
 
119
     */
 
120
    protected ICommandShell getCommandShell() {
 
121
        return fCommandShell;
 
122
    }
 
123
 
 
124
    // ------------------------------------------------------------------------
 
125
    // Operations
 
126
    // ------------------------------------------------------------------------
 
127
 
 
128
    @Override
 
129
    public String[] getSessionNames(IProgressMonitor monitor) throws ExecutionException {
 
130
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_LIST);
 
131
 
 
132
        ICommandResult result = executeCommand(command.toString(), monitor);
 
133
 
 
134
        // Output:
 
135
        // Available tracing sessions:
 
136
        // 1) mysession1 (/home/user/lttng-traces/mysession1-20120123-083928) [inactive]
 
137
        // 2) mysession (/home/user/lttng-traces/mysession-20120123-083318) [inactive]
 
138
        //
 
139
        // Use lttng list <session_name> for more details
 
140
 
 
141
        ArrayList<String> retArray = new ArrayList<>();
 
142
        int index = 0;
 
143
        while (index < result.getOutput().length) {
 
144
            String line = result.getOutput()[index];
 
145
            Matcher matcher = LTTngControlServiceConstants.SESSION_PATTERN.matcher(line);
 
146
            if (matcher.matches()) {
 
147
                retArray.add(matcher.group(2).trim());
 
148
            }
 
149
            index++;
 
150
        }
 
151
        return retArray.toArray(new String[retArray.size()]);
 
152
    }
 
153
 
 
154
    @Override
 
155
    public ISessionInfo getSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
 
156
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, sessionName);
 
157
        ICommandResult result = executeCommand(command.toString(), monitor);
 
158
 
 
159
        int index = 0;
 
160
 
 
161
        // Output:
 
162
        // Tracing session mysession2: [inactive]
 
163
        // Trace path: /home/eedbhu/lttng-traces/mysession2-20120123-110330
 
164
        ISessionInfo sessionInfo = new SessionInfo(sessionName);
 
165
 
 
166
        while (index < result.getOutput().length) {
 
167
            // Tracing session mysession2: [inactive]
 
168
            // Trace path: /home/eedbhu/lttng-traces/mysession2-20120123-110330
 
169
            //
 
170
            // === Domain: Kernel ===
 
171
            //
 
172
            String line = result.getOutput()[index];
 
173
            Matcher matcher = LTTngControlServiceConstants.TRACE_SESSION_PATTERN.matcher(line);
 
174
            if (matcher.matches()) {
 
175
                sessionInfo.setSessionState(matcher.group(2));
 
176
                index++;
 
177
                continue;
 
178
            }
 
179
 
 
180
            matcher = LTTngControlServiceConstants.TRACE_SNAPSHOT_SESSION_PATTERN.matcher(line);
 
181
            if (matcher.matches()) {
 
182
                sessionInfo.setSessionState(matcher.group(2));
 
183
                // real name will be set later
 
184
                ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
 
185
                sessionInfo.setSnapshotInfo(snapshotInfo);
 
186
                index++;
 
187
                continue;
 
188
            }
 
189
 
 
190
            if (!sessionInfo.isSnapshotSession()) {
 
191
                matcher = LTTngControlServiceConstants.TRACE_NETWORK_PATH_PATTERN.matcher(line);
 
192
                if (matcher.matches()) {
 
193
                    sessionInfo.setStreamedTrace(true);
 
194
                }
 
195
 
 
196
                matcher = LTTngControlServiceConstants.TRACE_SESSION_PATH_PATTERN.matcher(line);
 
197
                if (matcher.matches()) {
 
198
                    sessionInfo.setSessionPath(matcher.group(1).trim());
 
199
                    index++;
 
200
                    continue;
 
201
                }
 
202
            }
 
203
 
 
204
            matcher = LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(line);
 
205
            if (matcher.matches()) {
 
206
                // Create Domain
 
207
                IDomainInfo domainInfo = new DomainInfo(Messages.TraceControl_KernelDomainDisplayName);
 
208
 
 
209
                // set kernel flag
 
210
                domainInfo.setIsKernel(true);
 
211
 
 
212
                // in domain kernel
 
213
                ArrayList<IChannelInfo> channels = new ArrayList<>();
 
214
                index = parseDomain(result.getOutput(), index, channels, domainInfo);
 
215
 
 
216
                if (channels.size() > 0) {
 
217
                    // add domain
 
218
                    sessionInfo.addDomain(domainInfo);
 
219
 
 
220
                    // set channels
 
221
                    domainInfo.setChannels(channels);
 
222
                }
 
223
                continue;
 
224
            }
 
225
 
 
226
            matcher = LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(line);
 
227
            if (matcher.matches()) {
 
228
                IDomainInfo domainInfo = new DomainInfo(Messages.TraceControl_UstGlobalDomainDisplayName);
 
229
 
 
230
                // set kernel flag
 
231
                domainInfo.setIsKernel(false);
 
232
 
 
233
                // in domain UST
 
234
                ArrayList<IChannelInfo> channels = new ArrayList<>();
 
235
                index = parseDomain(result.getOutput(), index, channels, domainInfo);
 
236
 
 
237
                if (channels.size() > 0) {
 
238
                    // add domain
 
239
                    sessionInfo.addDomain(domainInfo);
 
240
 
 
241
                    // set channels
 
242
                    domainInfo.setChannels(channels);
 
243
                }
 
244
                continue;
 
245
            }
 
246
            index++;
 
247
        }
 
248
 
 
249
        if (sessionInfo.isSnapshotSession()) {
 
250
            ISnapshotInfo snapshot = getSnapshotInfo(sessionName, monitor);
 
251
            sessionInfo.setSnapshotInfo(snapshot);
 
252
        }
 
253
 
 
254
        return sessionInfo;
 
255
    }
 
256
 
 
257
    @Override
 
258
    public ISnapshotInfo getSnapshotInfo(String sessionName, IProgressMonitor monitor) throws ExecutionException {
 
259
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_LIST_SNAPSHOT_OUTPUT, LTTngControlServiceConstants.OPTION_SESSION, sessionName);
 
260
        ICommandResult result = executeCommand(command.toString(), monitor);
 
261
 
 
262
        int index = 0;
 
263
 
 
264
        // Output:
 
265
        // [1] snapshot-1: /home/user/lttng-traces/my-20130909-114431
 
266
        // or
 
267
        // [3] snapshot-3: net4://172.0.0.1/
 
268
        ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
 
269
 
 
270
        while (index < result.getOutput().length) {
 
271
            String line = result.getOutput()[index];
 
272
            Matcher matcher = LTTngControlServiceConstants.LIST_SNAPSHOT_OUTPUT_PATTERN.matcher(line);
 
273
            if (matcher.matches()) {
 
274
                snapshotInfo.setId(Integer.valueOf(matcher.group(1)));
 
275
                snapshotInfo.setName(matcher.group(2));
 
276
                snapshotInfo.setSnapshotPath(matcher.group(3));
 
277
 
 
278
                Matcher matcher2 = LTTngControlServiceConstants.SNAPSHOT_NETWORK_PATH_PATTERN.matcher(snapshotInfo.getSnapshotPath());
 
279
                if (matcher2.matches()) {
 
280
                    snapshotInfo.setStreamedSnapshot(true);
 
281
                }
 
282
 
 
283
                index++;
 
284
                break;
 
285
            }
 
286
            index++;
 
287
        }
 
288
 
 
289
        return snapshotInfo;
 
290
    }
 
291
 
 
292
    @Override
 
293
    public List<IBaseEventInfo> getKernelProvider(IProgressMonitor monitor) throws ExecutionException {
 
294
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_LIST_KERNEL);
 
295
        ICommandResult result = executeCommand(command.toString(), monitor, false);
 
296
 
 
297
        List<IBaseEventInfo> events = new ArrayList<>();
 
298
 
 
299
        if (result.getErrorOutput() != null) {
 
300
            // Ignore the following 2 cases:
 
301
            // Spawning a session daemon
 
302
            // Error: Unable to list kernel events
 
303
            // or:
 
304
            // Error: Unable to list kernel events
 
305
            //
 
306
            int index = 0;
 
307
            while (index < result.getErrorOutput().length) {
 
308
                String line = result.getErrorOutput()[index];
 
309
                Matcher matcher = LTTngControlServiceConstants.LIST_KERNEL_NO_KERNEL_PROVIDER_PATTERN.matcher(line);
 
310
                if (matcher.matches()) {
 
311
                    return events;
 
312
                }
 
313
                index++;
 
314
            }
 
315
        }
 
316
 
 
317
        if (isError(result)) {
 
318
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + formatOutput(result)); //$NON-NLS-1$ //$NON-NLS-2$
 
319
        }
 
320
 
 
321
        // Kernel events:
 
322
        // -------------
 
323
        // sched_kthread_stop (type: tracepoint)
 
324
        getProviderEventInfo(result.getOutput(), 0, events);
 
325
        return events;
 
326
    }
 
327
 
 
328
    @Override
 
329
    public List<IUstProviderInfo> getUstProvider() throws ExecutionException {
 
330
        return getUstProvider(new NullProgressMonitor());
 
331
    }
 
332
 
 
333
    @Override
 
334
    public List<IUstProviderInfo> getUstProvider(IProgressMonitor monitor) throws ExecutionException {
 
335
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_LIST_UST);
 
336
 
 
337
        if (isVersionSupported("2.1.0")) { //$NON-NLS-1$
 
338
            command.append(LTTngControlServiceConstants.OPTION_FIELDS);
 
339
        }
 
340
 
 
341
        ICommandResult result = executeCommand(command.toString(), monitor, false);
 
342
        List<IUstProviderInfo> allProviders = new ArrayList<>();
 
343
 
 
344
        // Workaround for versions 2.0.x which causes a segmentation fault for this command
 
345
        // if LTTng Tools is compiled without UST support.
 
346
        if (!isVersionSupported("2.1.0") && (result.getResult() != 0)) { //$NON-NLS-1$
 
347
            return allProviders;
 
348
        }
 
349
 
 
350
        if (result.getErrorOutput() != null) {
 
351
            // Ignore the following 2 cases:
 
352
            // Spawning a session daemon
 
353
            // Error: Unable to list UST events: Listing UST events failed
 
354
            // or:
 
355
            // Error: Unable to list UST events: Listing UST events failed
 
356
            //
 
357
            int index = 0;
 
358
            while (index < result.getErrorOutput().length) {
 
359
                String line = result.getErrorOutput()[index];
 
360
                Matcher matcher = LTTngControlServiceConstants.LIST_UST_NO_UST_PROVIDER_PATTERN.matcher(line);
 
361
                if (matcher.matches()) {
 
362
                    return allProviders;
 
363
                }
 
364
                index++;
 
365
            }
 
366
        }
 
367
 
 
368
        if (isError(result)) {
 
369
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + formatOutput(result)); //$NON-NLS-1$ //$NON-NLS-2$
 
370
        }
 
371
 
 
372
        // Note that field print-outs exists for version >= 2.1.0
 
373
        //
 
374
        // UST events:
 
375
        // -------------
 
376
        //
 
377
        // PID: 3635 - Name:
 
378
        // /home/user/git/lttng-ust/tests/hello.cxx/.libs/lt-hello
 
379
        // ust_tests_hello:tptest_sighandler (loglevel: TRACE_EMERG0) (type:
 
380
        // tracepoint)
 
381
        // ust_tests_hello:tptest (loglevel: TRACE_EMERG0) (type: tracepoint)
 
382
        //    field: doublefield (float)
 
383
        //    field: floatfield (float)
 
384
        //    field: stringfield (string)
 
385
        //
 
386
        // PID: 6459 - Name:
 
387
        // /home/user/git/lttng-ust/tests/hello.cxx/.libs/lt-hello
 
388
        // ust_tests_hello:tptest_sighandler (loglevel: TRACE_EMERG0) (type:
 
389
        // tracepoint)
 
390
        // ust_tests_hello:tptest (loglevel: TRACE_EMERG0) (type: tracepoint)
 
391
        //    field: doublefield (float)
 
392
        //    field: floatfield (float)
 
393
        //    field: stringfield (string)
 
394
 
 
395
        IUstProviderInfo provider = null;
 
396
 
 
397
        int index = 0;
 
398
        while (index < result.getOutput().length) {
 
399
            String line = result.getOutput()[index];
 
400
            Matcher matcher = LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line);
 
401
            if (matcher.matches()) {
 
402
                provider = new UstProviderInfo(matcher.group(2).trim());
 
403
                provider.setPid(Integer.valueOf(matcher.group(1).trim()));
 
404
                List<IBaseEventInfo> events = new ArrayList<>();
 
405
                index = getProviderEventInfo(result.getOutput(), ++index, events);
 
406
                provider.setEvents(events);
 
407
                allProviders.add(provider);
 
408
            } else {
 
409
                index++;
 
410
            }
 
411
        }
 
412
        return allProviders;
 
413
    }
 
414
 
 
415
    @Override
 
416
    public ISessionInfo createSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
 
417
        if (sessionInfo.isStreamedTrace()) {
 
418
            return createStreamedSession(sessionInfo, monitor);
 
419
        }
 
420
 
 
421
        String newName = formatParameter(sessionInfo.getName());
 
422
        String newPath = formatParameter(sessionInfo.getSessionPath());
 
423
 
 
424
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_CREATE_SESSION, newName);
 
425
 
 
426
        if (newPath != null && !"".equals(newPath)) { //$NON-NLS-1$
 
427
            command.append(LTTngControlServiceConstants.OPTION_OUTPUT_PATH);
 
428
            command.append(newPath);
 
429
        }
 
430
 
 
431
        if (sessionInfo.isSnapshotSession()) {
 
432
            command.append(LTTngControlServiceConstants.OPTION_SNAPSHOT);
 
433
        }
 
434
 
 
435
        ICommandResult result = executeCommand(command.toString(), monitor);
 
436
 
 
437
        //Session myssession2 created.
 
438
        //Traces will be written in /home/user/lttng-traces/myssession2-20120209-095418
 
439
        String[] output = result.getOutput();
 
440
 
 
441
        // Get and session name and path
 
442
        String name = null;
 
443
        String path = null;
 
444
 
 
445
        int index = 0;
 
446
        while (index < output.length) {
 
447
            String line = output[index];
 
448
            Matcher nameMatcher = LTTngControlServiceConstants.CREATE_SESSION_NAME_PATTERN.matcher(line);
 
449
            Matcher pathMatcher = LTTngControlServiceConstants.CREATE_SESSION_PATH_PATTERN.matcher(line);
 
450
            if (nameMatcher.matches()) {
 
451
                name = String.valueOf(nameMatcher.group(1).trim());
 
452
            } else if (pathMatcher.matches()) {
 
453
                path = String.valueOf(pathMatcher.group(1).trim());
 
454
            }
 
455
            index++;
 
456
        }
 
457
 
 
458
        // Verify session name
 
459
        if ((name == null) || (!"".equals(sessionInfo.getName()) && !name.equals(sessionInfo.getName()))) { //$NON-NLS-1$
 
460
            // Unexpected name returned
 
461
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
 
462
                    Messages.TraceControl_UnexpectedNameError + ": " + name); //$NON-NLS-1$
 
463
        }
 
464
 
 
465
        sessionInfo.setName(name);
 
466
        // Verify session path
 
467
        if (!sessionInfo.isSnapshotSession() &&
 
468
                ((path == null) || ((sessionInfo.getSessionPath() != null) && (!path.contains(sessionInfo.getSessionPath()))))) {
 
469
            // Unexpected path
 
470
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
 
471
                    Messages.TraceControl_UnexpectedPathError + ": " + name); //$NON-NLS-1$
 
472
        }
 
473
 
 
474
        if (sessionInfo.isSnapshotSession()) {
 
475
            // Make it a snapshot session - content of snapshot info need to
 
476
            // set afterwards using getSession() or getSnapshotInfo()
 
477
            sessionInfo.setSnapshotInfo(new SnapshotInfo("")); //$NON-NLS-1$
 
478
        } else {
 
479
            sessionInfo.setSessionPath(path);
 
480
        }
 
481
 
 
482
        return sessionInfo;
 
483
 
 
484
    }
 
485
 
 
486
    private ISessionInfo createStreamedSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
 
487
 
 
488
        String newName = formatParameter(sessionInfo.getName());
 
489
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_CREATE_SESSION, newName);
 
490
 
 
491
        if (sessionInfo.isSnapshotSession()) {
 
492
            command.append(LTTngControlServiceConstants.OPTION_SNAPSHOT);
 
493
        } else if (sessionInfo.isLive()) {
 
494
            command.append(LTTngControlServiceConstants.OPTION_LIVE);
 
495
            if (sessionInfo.getLiveDelay() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
496
                command.append(sessionInfo.getLiveDelay());
 
497
            }
 
498
        }
 
499
 
 
500
        if (sessionInfo.getNetworkUrl() != null) {
 
501
            command.append(LTTngControlServiceConstants.OPTION_NETWORK_URL);
 
502
            command.append(sessionInfo.getNetworkUrl());
 
503
        } else {
 
504
            command.append(LTTngControlServiceConstants.OPTION_CONTROL_URL);
 
505
            command.append(sessionInfo.getControlUrl());
 
506
 
 
507
            command.append(LTTngControlServiceConstants.OPTION_DATA_URL);
 
508
            command.append(sessionInfo.getDataUrl());
 
509
        }
 
510
 
 
511
        ICommandResult result = executeCommand(command.toString(), monitor);
 
512
 
 
513
        // Verify output
 
514
        String[] output = result.getOutput();
 
515
 
 
516
        // Get and session name and path
 
517
        String name = null;
 
518
        String path = null;
 
519
 
 
520
        int index = 0;
 
521
        while (index < output.length) {
 
522
            String line = output[index];
 
523
            Matcher nameMatcher = LTTngControlServiceConstants.CREATE_SESSION_NAME_PATTERN.matcher(line);
 
524
            Matcher pathMatcher = LTTngControlServiceConstants.CREATE_SESSION_PATH_PATTERN.matcher(line);
 
525
 
 
526
            if (nameMatcher.matches()) {
 
527
                name = String.valueOf(nameMatcher.group(1).trim());
 
528
            } else if (pathMatcher.matches() && (sessionInfo.getNetworkUrl() != null)) {
 
529
                path = String.valueOf(pathMatcher.group(1).trim());
 
530
            }
 
531
            index++;
 
532
        }
 
533
 
 
534
        // Verify session name
 
535
        if ((name == null) || (!"".equals(sessionInfo.getName()) && !name.equals(sessionInfo.getName()))) { //$NON-NLS-1$
 
536
            // Unexpected name returned
 
537
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
 
538
                    Messages.TraceControl_UnexpectedNameError + ": " + name); //$NON-NLS-1$
 
539
        }
 
540
 
 
541
        sessionInfo.setName(name);
 
542
 
 
543
        sessionInfo.setStreamedTrace(true);
 
544
 
 
545
        // Verify session path
 
546
        if (sessionInfo.getNetworkUrl() != null) {
 
547
            if (!sessionInfo.isSnapshotSession() && (path == null)) {
 
548
                // Unexpected path
 
549
                throw new ExecutionException(Messages.TraceControl_CommandError + " " + command + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
 
550
                        Messages.TraceControl_UnexpectedPathError + ": " + name); //$NON-NLS-1$
 
551
            }
 
552
 
 
553
            if (sessionInfo.isSnapshotSession()) {
 
554
                sessionInfo.setStreamedTrace(false);
 
555
            } else {
 
556
                sessionInfo.setSessionPath(path);
 
557
                // Check file protocol
 
558
                Matcher matcher = LTTngControlServiceConstants.TRACE_FILE_PROTOCOL_PATTERN.matcher(path);
 
559
                if (matcher.matches()) {
 
560
                    sessionInfo.setStreamedTrace(false);
 
561
                }
 
562
            }
 
563
        }
 
564
 
 
565
        // When using controlUrl and dataUrl the full session path is not known yet
 
566
        // and will be set later on when listing the session
 
567
 
 
568
        return sessionInfo;
 
569
    }
 
570
 
 
571
    @Override
 
572
    public void destroySession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
 
573
        String newName = formatParameter(sessionName);
 
574
 
 
575
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_DESTROY_SESSION, newName);
 
576
 
 
577
        ICommandResult result = executeCommand(command.toString(), monitor, false);
 
578
        String[] errorOutput = result.getErrorOutput();
 
579
 
 
580
        boolean isError = isError(result);
 
581
        if (isError && (errorOutput != null)) {
 
582
            int index = 0;
 
583
            while (index < errorOutput.length) {
 
584
                String line = errorOutput[index];
 
585
                Matcher matcher = LTTngControlServiceConstants.SESSION_NOT_FOUND_ERROR_PATTERN.matcher(line);
 
586
                if (matcher.matches()) {
 
587
                    // Don't treat this as an error
 
588
                    isError = false;
 
589
                }
 
590
                index++;
 
591
            }
 
592
        }
 
593
 
 
594
        if (isError) {
 
595
            throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + formatOutput(result)); //$NON-NLS-1$ //$NON-NLS-2$
 
596
        }
 
597
 
 
598
        //Session <sessionName> destroyed
 
599
    }
 
600
 
 
601
    @Override
 
602
    public void startSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
 
603
 
 
604
        String newSessionName = formatParameter(sessionName);
 
605
 
 
606
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_START_SESSION, newSessionName);
 
607
 
 
608
        executeCommand(command.toString(), monitor);
 
609
 
 
610
        //Session <sessionName> started
 
611
    }
 
612
 
 
613
    @Override
 
614
    public void stopSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
 
615
        String newSessionName = formatParameter(sessionName);
 
616
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_STOP_SESSION, newSessionName);
 
617
 
 
618
        executeCommand(command.toString(), monitor);
 
619
 
 
620
        //Session <sessionName> stopped
 
621
 
 
622
    }
 
623
 
 
624
    @Override
 
625
    public void enableChannels(String sessionName, List<String> channelNames, boolean isKernel, IChannelInfo info, IProgressMonitor monitor) throws ExecutionException {
 
626
 
 
627
        // no channels to enable
 
628
        if (channelNames.isEmpty()) {
 
629
            return;
 
630
        }
 
631
 
 
632
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_CHANNEL);
 
633
 
 
634
        for (Iterator<String> iterator = channelNames.iterator(); iterator.hasNext();) {
 
635
            String channel = iterator.next();
 
636
            command.append(channel);
 
637
            if (iterator.hasNext()) {
 
638
                command.append(',');
 
639
            }
 
640
        }
 
641
 
 
642
        if (isKernel) {
 
643
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
644
        } else {
 
645
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
646
        }
 
647
 
 
648
        String newSessionName = formatParameter(sessionName);
 
649
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
650
        command.append(newSessionName);
 
651
 
 
652
        if (info != null) {
 
653
//            --discard            Discard event when buffers are full (default)
 
654
 
 
655
//            --overwrite          Flight recorder mode
 
656
            if (info.isOverwriteMode()) {
 
657
                command.append(LTTngControlServiceConstants.OPTION_OVERWRITE);
 
658
            }
 
659
//            --subbuf-size SIZE   Subbuffer size in bytes
 
660
//                                     (default: 4096, kernel default: 262144)
 
661
            if (info.getSubBufferSize() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
662
                command.append(LTTngControlServiceConstants.OPTION_SUB_BUFFER_SIZE);
 
663
                command.append(String.valueOf(info.getSubBufferSize()));
 
664
            }
 
665
 
 
666
//            --num-subbuf NUM     Number of subbufers
 
667
            if (info.getNumberOfSubBuffers() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
668
                command.append(LTTngControlServiceConstants.OPTION_NUM_SUB_BUFFERS);
 
669
                command.append(String.valueOf(info.getNumberOfSubBuffers()));
 
670
            }
 
671
 
 
672
//            --switch-timer USEC  Switch timer interval in usec
 
673
            if (info.getSwitchTimer() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
674
                command.append(LTTngControlServiceConstants.OPTION_SWITCH_TIMER);
 
675
                command.append(String.valueOf(info.getSwitchTimer()));
 
676
            }
 
677
 
 
678
//            --read-timer USEC    Read timer interval in usec
 
679
            if (info.getReadTimer() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
680
                command.append(LTTngControlServiceConstants.OPTION_READ_TIMER);
 
681
                command.append(String.valueOf(info.getReadTimer()));
 
682
            }
 
683
 
 
684
            if (isVersionSupported("2.2.0")) { //$NON-NLS-1$
 
685
//                --buffers-uid  Every application sharing the same UID use the same buffers
 
686
//                --buffers-pid Buffers are allocated per PID
 
687
                if (!isKernel) {
 
688
                    if (info.getBufferType() == BufferType.BUFFER_PER_PID) {
 
689
                        command.append(LTTngControlServiceConstants.OPTION_PER_PID_BUFFERS);
 
690
 
 
691
                    } else if (info.getBufferType() == BufferType.BUFFER_PER_UID) {
 
692
                        command.append(LTTngControlServiceConstants.OPTION_PER_UID_BUFFERS);
 
693
                    }
 
694
                }
 
695
 
 
696
//                -C SIZE   Maximum size of trace files in bytes
 
697
                if (info.getMaxSizeTraceFiles() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
698
                    command.append(LTTngControlServiceConstants.OPTION_MAX_SIZE_TRACE_FILES);
 
699
                    command.append(String.valueOf(info.getMaxSizeTraceFiles()));
 
700
                }
 
701
 
 
702
//                -W NUM   Maximum number of trace files
 
703
                if (info.getMaxNumberTraceFiles() != LTTngControlServiceConstants.UNUSED_VALUE) {
 
704
                    command.append(LTTngControlServiceConstants.OPTION_MAX_TRACE_FILES);
 
705
                    command.append(String.valueOf(info.getMaxNumberTraceFiles()));
 
706
                }
 
707
            }
 
708
        }
 
709
 
 
710
        executeCommand(command.toString(), monitor);
 
711
 
 
712
    }
 
713
 
 
714
    @Override
 
715
    public void disableChannels(String sessionName, List<String> channelNames, boolean isKernel, IProgressMonitor monitor) throws ExecutionException {
 
716
 
 
717
        // no channels to enable
 
718
        if (channelNames.isEmpty()) {
 
719
            return;
 
720
        }
 
721
 
 
722
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_DISABLE_CHANNEL);
 
723
 
 
724
        for (Iterator<String> iterator = channelNames.iterator(); iterator.hasNext();) {
 
725
            String channel = iterator.next();
 
726
            command.append(channel);
 
727
            if (iterator.hasNext()) {
 
728
                command.append(',');
 
729
            }
 
730
        }
 
731
 
 
732
        if (isKernel) {
 
733
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
734
        } else {
 
735
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
736
        }
 
737
 
 
738
        String newSessionName = formatParameter(sessionName);
 
739
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
740
        command.append(newSessionName);
 
741
 
 
742
        executeCommand(command.toString(), monitor);
 
743
    }
 
744
 
 
745
    @Override
 
746
    public void enableEvents(String sessionName, String channelName, List<String> eventNames, boolean isKernel, String filterExpression, IProgressMonitor monitor) throws ExecutionException {
 
747
 
 
748
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
 
749
 
 
750
        if (eventNames == null || eventNames.isEmpty()) {
 
751
            command.append(LTTngControlServiceConstants.OPTION_ALL);
 
752
        } else {
 
753
 
 
754
            StringBuffer eventNameParameter = new StringBuffer();
 
755
            for (Iterator<String> iterator = eventNames.iterator(); iterator.hasNext();) {
 
756
                String event = iterator.next();
 
757
                eventNameParameter.append(event);
 
758
                if (iterator.hasNext()) {
 
759
                    eventNameParameter.append(',');
 
760
                }
 
761
            }
 
762
            command.append(formatParameter(eventNameParameter.toString()));
 
763
        }
 
764
 
 
765
        if (isKernel) {
 
766
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
767
        } else {
 
768
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
769
        }
 
770
 
 
771
        String newSessionName = formatParameter(sessionName);
 
772
 
 
773
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
774
        command.append(newSessionName);
 
775
 
 
776
        if (channelName != null) {
 
777
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
778
            command.append(channelName);
 
779
        }
 
780
 
 
781
        command.append(LTTngControlServiceConstants.OPTION_TRACEPOINT);
 
782
 
 
783
        if (filterExpression != null) {
 
784
            command.append(LTTngControlServiceConstants.OPTION_FILTER);
 
785
            command.append('\'');
 
786
            command.append(filterExpression);
 
787
            command.append('\'');
 
788
        }
 
789
 
 
790
        executeCommand(command.toString(), monitor);
 
791
 
 
792
    }
 
793
 
 
794
    @Override
 
795
    public void enableSyscalls(String sessionName, String channelName, IProgressMonitor monitor) throws ExecutionException {
 
796
 
 
797
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
 
798
 
 
799
        command.append(LTTngControlServiceConstants.OPTION_ALL);
 
800
        command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
801
 
 
802
        String newSessionName = formatParameter(sessionName);
 
803
 
 
804
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
805
        command.append(newSessionName);
 
806
 
 
807
        if (channelName != null) {
 
808
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
809
            command.append(channelName);
 
810
        }
 
811
 
 
812
        command.append(LTTngControlServiceConstants.OPTION_SYSCALL);
 
813
 
 
814
        executeCommand(command.toString(), monitor);
 
815
    }
 
816
 
 
817
    @Override
 
818
    public void enableProbe(String sessionName, String channelName, String eventName, boolean isFunction, String probe, IProgressMonitor monitor) throws ExecutionException {
 
819
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
 
820
 
 
821
        command.append(eventName);
 
822
        command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
823
 
 
824
        String newSessionName = formatParameter(sessionName);
 
825
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
826
        command.append(newSessionName);
 
827
 
 
828
        if (channelName != null) {
 
829
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
830
            command.append(channelName);
 
831
        }
 
832
        if (isFunction) {
 
833
            command.append(LTTngControlServiceConstants.OPTION_FUNCTION_PROBE);
 
834
        } else {
 
835
            command.append(LTTngControlServiceConstants.OPTION_PROBE);
 
836
        }
 
837
 
 
838
        command.append(probe);
 
839
 
 
840
        executeCommand(command.toString(), monitor);
 
841
    }
 
842
 
 
843
    @Override
 
844
    public void enableLogLevel(String sessionName, String channelName, String eventName, LogLevelType logLevelType, TraceLogLevel level, String filterExpression, IProgressMonitor monitor) throws ExecutionException {
 
845
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
 
846
 
 
847
        command.append(eventName);
 
848
        command.append(LTTngControlServiceConstants.OPTION_UST);
 
849
 
 
850
        String newSessionName = formatParameter(sessionName);
 
851
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
852
        command.append(newSessionName);
 
853
 
 
854
        if (channelName != null) {
 
855
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
856
            command.append(channelName);
 
857
        }
 
858
 
 
859
        if (logLevelType == LogLevelType.LOGLEVEL) {
 
860
            command.append(LTTngControlServiceConstants.OPTION_LOGLEVEL);
 
861
        } else if (logLevelType == LogLevelType.LOGLEVEL_ONLY) {
 
862
            command.append(LTTngControlServiceConstants.OPTION_LOGLEVEL_ONLY);
 
863
 
 
864
        } else {
 
865
            return;
 
866
        }
 
867
        command.append(level.getInName());
 
868
 
 
869
        executeCommand(command.toString(), monitor);
 
870
    }
 
871
 
 
872
    @Override
 
873
    public void disableEvent(String sessionName, String channelName, List<String> eventNames, boolean isKernel, IProgressMonitor monitor) throws ExecutionException {
 
874
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_DISABLE_EVENT);
 
875
 
 
876
        if (eventNames == null) {
 
877
            command.append(LTTngControlServiceConstants.OPTION_ALL);
 
878
        } else {
 
879
            // no events to disable
 
880
            if (eventNames.isEmpty()) {
 
881
                return;
 
882
            }
 
883
 
 
884
            StringBuffer eventNameParameter = new StringBuffer();
 
885
            for (Iterator<String> iterator = eventNames.iterator(); iterator.hasNext();) {
 
886
                String event = iterator.next();
 
887
                eventNameParameter.append(event);
 
888
                if (iterator.hasNext()) {
 
889
                    eventNameParameter.append(',');
 
890
                }
 
891
            }
 
892
            command.append(formatParameter(eventNameParameter.toString()));
 
893
        }
 
894
 
 
895
        if (isKernel) {
 
896
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
897
        } else {
 
898
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
899
        }
 
900
 
 
901
        String newSessionName = formatParameter(sessionName);
 
902
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
903
        command.append(newSessionName);
 
904
 
 
905
        if (channelName != null) {
 
906
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
907
            command.append(channelName);
 
908
        }
 
909
 
 
910
        executeCommand(command.toString(), monitor);
 
911
    }
 
912
 
 
913
    @Override
 
914
    public List<String> getContextList(IProgressMonitor monitor) throws ExecutionException {
 
915
 
 
916
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ADD_CONTEXT, LTTngControlServiceConstants.OPTION_HELP);
 
917
 
 
918
        ICommandResult result = executeCommand(command.toString(), monitor);
 
919
 
 
920
        String[] output = result.getOutput();
 
921
 
 
922
        List<String> contexts = new ArrayList<>(0);
 
923
 
 
924
        int index = 0;
 
925
        boolean inList = false;
 
926
        while (index < output.length) {
 
927
            String line = result.getOutput()[index];
 
928
 
 
929
            Matcher startMatcher = LTTngControlServiceConstants.ADD_CONTEXT_HELP_CONTEXTS_INTRO.matcher(line);
 
930
            Matcher endMatcher = LTTngControlServiceConstants.ADD_CONTEXT_HELP_CONTEXTS_END_LINE.matcher(line);
 
931
 
 
932
            if (startMatcher.matches()) {
 
933
                inList = true;
 
934
            } else if (endMatcher.matches()) {
 
935
                break;
 
936
            } else if (inList == true) {
 
937
                String[] tmp = line.split(","); //$NON-NLS-1$
 
938
                for (int i = 0; i < tmp.length; i++) {
 
939
                    contexts.add(tmp[i].trim());
 
940
                }
 
941
            }
 
942
            index++;
 
943
        }
 
944
        return contexts;
 
945
    }
 
946
 
 
947
    @Override
 
948
    public void addContexts(String sessionName, String channelName, String eventName, boolean isKernel, List<String> contextNames, IProgressMonitor monitor) throws ExecutionException {
 
949
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_ADD_CONTEXT);
 
950
 
 
951
        String newSessionName = formatParameter(sessionName);
 
952
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
953
        command.append(newSessionName);
 
954
 
 
955
        if (channelName != null) {
 
956
            command.append(LTTngControlServiceConstants.OPTION_CHANNEL);
 
957
            command.append(channelName);
 
958
        }
 
959
 
 
960
        if (eventName != null) {
 
961
            command.append(LTTngControlServiceConstants.OPTION_EVENT);
 
962
            command.append(eventName);
 
963
        }
 
964
 
 
965
        if (isKernel) {
 
966
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
967
        } else {
 
968
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
969
        }
 
970
 
 
971
        for (Iterator<String> iterator = contextNames.iterator(); iterator.hasNext();) {
 
972
            String context = iterator.next();
 
973
            command.append(LTTngControlServiceConstants.OPTION_CONTEXT_TYPE);
 
974
            command.append(context);
 
975
        }
 
976
 
 
977
        executeCommand(command.toString(), monitor);
 
978
 
 
979
    }
 
980
 
 
981
    @Override
 
982
    public void calibrate(boolean isKernel, IProgressMonitor monitor) throws ExecutionException {
 
983
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_CALIBRATE);
 
984
 
 
985
        if (isKernel) {
 
986
            command.append(LTTngControlServiceConstants.OPTION_KERNEL);
 
987
        } else {
 
988
            command.append(LTTngControlServiceConstants.OPTION_UST);
 
989
        }
 
990
 
 
991
        command.append(LTTngControlServiceConstants.OPTION_FUNCTION_PROBE);
 
992
 
 
993
        executeCommand(command.toString(), monitor);
 
994
    }
 
995
 
 
996
    @Override
 
997
    public void recordSnapshot(String sessionName, IProgressMonitor monitor)
 
998
            throws ExecutionException {
 
999
        StringBuffer command = createCommand(LTTngControlServiceConstants.COMMAND_RECORD_SNAPSHOT);
 
1000
 
 
1001
        String newSessionName = formatParameter(sessionName);
 
1002
        command.append(LTTngControlServiceConstants.OPTION_SESSION);
 
1003
        command.append(newSessionName);
 
1004
 
 
1005
        executeCommand(command.toString(), monitor);
 
1006
    }
 
1007
 
 
1008
    @Override
 
1009
    public void runCommands(IProgressMonitor monitor, List<String> commands) throws ExecutionException {
 
1010
        for (String command : commands) {
 
1011
            if (monitor.isCanceled()) {
 
1012
                return;
 
1013
            }
 
1014
 
 
1015
            if (command.isEmpty() || command.startsWith("#")) { //$NON-NLS-1$
 
1016
                continue;
 
1017
            }
 
1018
            executeCommand(command, monitor);
 
1019
        }
 
1020
    }
 
1021
 
 
1022
    // ------------------------------------------------------------------------
 
1023
    // Helper methods
 
1024
    // ------------------------------------------------------------------------
 
1025
 
 
1026
    /**
 
1027
     * Checks if command result is an error result.
 
1028
     *
 
1029
     * @param result
 
1030
     *            - the command result to check
 
1031
     * @return true if error else false
 
1032
     */
 
1033
    protected boolean isError(ICommandResult result) {
 
1034
        // Check return code and length of returned strings
 
1035
 
 
1036
        if ((result.getResult()) != 0) {
 
1037
            return true;
 
1038
        }
 
1039
 
 
1040
        // Look for error pattern
 
1041
        int index = 0;
 
1042
        while (index < result.getErrorOutput().length) {
 
1043
            String line = result.getErrorOutput()[index];
 
1044
            Matcher matcher = LTTngControlServiceConstants.ERROR_PATTERN.matcher(line);
 
1045
            if (matcher.matches()) {
 
1046
                return true;
 
1047
            }
 
1048
            index++;
 
1049
        }
 
1050
 
 
1051
        return false;
 
1052
    }
 
1053
 
 
1054
    /**
 
1055
     * Formats the output string as single string.
 
1056
     *
 
1057
     * @param result
 
1058
     *            - output array
 
1059
     * @return - the formatted output
 
1060
     */
 
1061
    public static String formatOutput(ICommandResult result) {
 
1062
        if ((result == null) || ((result.getOutput() == null || result.getOutput().length == 0) && (result.getErrorOutput() == null || result.getErrorOutput().length == 0))) {
 
1063
            return ""; //$NON-NLS-1$
 
1064
        }
 
1065
        String[] output = result.getOutput();
 
1066
        String[] errorOutput = result.getErrorOutput();
 
1067
        StringBuffer ret = new StringBuffer();
 
1068
        ret.append("Return Value: "); //$NON-NLS-1$
 
1069
        ret.append(result.getResult());
 
1070
        ret.append("\n"); //$NON-NLS-1$
 
1071
        for (int i = 0; i < output.length; i++) {
 
1072
            ret.append(output[i]).append("\n"); //$NON-NLS-1$
 
1073
        }
 
1074
        ret.append("Error stream:\n"); //$NON-NLS-1$
 
1075
        for (int i = 0; i < errorOutput.length; i++) {
 
1076
           ret.append(errorOutput[i]).append("\n"); //$NON-NLS-1$
 
1077
        }
 
1078
        return ret.toString();
 
1079
    }
 
1080
 
 
1081
    /**
 
1082
     * Parses the domain information.
 
1083
     *
 
1084
     * @param output
 
1085
     *            - a command output array
 
1086
     * @param currentIndex
 
1087
     *            - current index in command output array
 
1088
     * @param channels
 
1089
     *            - list for returning channel information
 
1090
     * @param domainInfo
 
1091
     *            - The domain information
 
1092
     * @return the new current index in command output array
 
1093
     */
 
1094
    protected int parseDomain(String[] output, int currentIndex, List<IChannelInfo> channels, IDomainInfo domainInfo) {
 
1095
        int index = currentIndex;
 
1096
 
 
1097
        // if kernel set the buffer type to shared
 
1098
        if (domainInfo.isKernel()) {
 
1099
            domainInfo.setBufferType(BufferType.BUFFER_SHARED);
 
1100
        }
 
1101
 
 
1102
        // Channels:
 
1103
        // -------------
 
1104
        // - channnel1: [enabled]
 
1105
        //
 
1106
        // Attributes:
 
1107
        // overwrite mode: 0
 
1108
        // subbufers size: 262144
 
1109
        // number of subbufers: 4
 
1110
        // switch timer interval: 0
 
1111
        // read timer interval: 200
 
1112
        // output: splice()
 
1113
 
 
1114
        while (index < output.length) {
 
1115
            String line = output[index];
 
1116
 
 
1117
            if (isVersionSupported("2.2.0")) { //$NON-NLS-1$
 
1118
                Matcher bufferTypeMatcher = LTTngControlServiceConstants.BUFFER_TYPE_PATTERN.matcher(line);
 
1119
                if (bufferTypeMatcher.matches()) {
 
1120
                    String bufferTypeString = getAttributeValue(line);
 
1121
                    if (BufferType.BUFFER_PER_PID.getInName().equals(bufferTypeString)) {
 
1122
                        domainInfo.setBufferType(BufferType.BUFFER_PER_PID);
 
1123
                    } else if (BufferType.BUFFER_PER_UID.getInName().equals(bufferTypeString)) {
 
1124
                        domainInfo.setBufferType(BufferType.BUFFER_PER_UID);
 
1125
                    } else {
 
1126
                        domainInfo.setBufferType(BufferType.BUFFER_TYPE_UNKNOWN);
 
1127
                    }
 
1128
                }
 
1129
            } else {
 
1130
                domainInfo.setBufferType(BufferType.BUFFER_TYPE_UNKNOWN);
 
1131
            }
 
1132
            Matcher outerMatcher = LTTngControlServiceConstants.CHANNELS_SECTION_PATTERN.matcher(line);
 
1133
            Matcher noKernelChannelMatcher = LTTngControlServiceConstants.DOMAIN_NO_KERNEL_CHANNEL_PATTERN.matcher(line);
 
1134
            Matcher noUstChannelMatcher = LTTngControlServiceConstants.DOMAIN_NO_UST_CHANNEL_PATTERN.matcher(line);
 
1135
            if (outerMatcher.matches()) {
 
1136
                IChannelInfo channelInfo = null;
 
1137
                while (index < output.length) {
 
1138
                    String subLine = output[index];
 
1139
 
 
1140
                    Matcher innerMatcher = LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(subLine);
 
1141
                    if (innerMatcher.matches()) {
 
1142
                        channelInfo = new ChannelInfo(""); //$NON-NLS-1$
 
1143
                        // get channel name
 
1144
                        channelInfo.setName(innerMatcher.group(1));
 
1145
 
 
1146
                        // get channel enablement
 
1147
                        channelInfo.setState(innerMatcher.group(2));
 
1148
 
 
1149
                        // set BufferType
 
1150
                        channelInfo.setBufferType(domainInfo.getBufferType());
 
1151
 
 
1152
                        // add channel
 
1153
                        channels.add(channelInfo);
 
1154
 
 
1155
                    } else if (LTTngControlServiceConstants.OVERWRITE_MODE_ATTRIBUTE.matcher(subLine).matches()) {
 
1156
                        String value = getAttributeValue(subLine);
 
1157
                        if (channelInfo != null) {
 
1158
                            channelInfo.setOverwriteMode(!LTTngControlServiceConstants.OVERWRITE_MODE_ATTRIBUTE_FALSE.equals(value));
 
1159
                        }
 
1160
                    } else if (LTTngControlServiceConstants.SUBBUFFER_SIZE_ATTRIBUTE.matcher(subLine).matches()) {
 
1161
                        if (channelInfo != null) {
 
1162
                            channelInfo.setSubBufferSize(Long.valueOf(getAttributeValue(subLine)));
 
1163
                        }
 
1164
 
 
1165
                    } else if (LTTngControlServiceConstants.NUM_SUBBUFFERS_ATTRIBUTE.matcher(subLine).matches()) {
 
1166
                        if (channelInfo != null) {
 
1167
                            channelInfo.setNumberOfSubBuffers(Integer.valueOf(getAttributeValue(subLine)));
 
1168
                        }
 
1169
 
 
1170
                    } else if (LTTngControlServiceConstants.SWITCH_TIMER_ATTRIBUTE.matcher(subLine).matches()) {
 
1171
                        if (channelInfo != null) {
 
1172
                            channelInfo.setSwitchTimer(Long.valueOf(getAttributeValue(subLine)));
 
1173
                        }
 
1174
 
 
1175
                    } else if (LTTngControlServiceConstants.READ_TIMER_ATTRIBUTE.matcher(subLine).matches()) {
 
1176
                        if (channelInfo != null) {
 
1177
                            channelInfo.setReadTimer(Long.valueOf(getAttributeValue(subLine)));
 
1178
                        }
 
1179
 
 
1180
                    } else if (LTTngControlServiceConstants.OUTPUT_ATTRIBUTE.matcher(subLine).matches()) {
 
1181
                        if (channelInfo != null) {
 
1182
                            channelInfo.setOutputType(getAttributeValue(subLine));
 
1183
                        }
 
1184
 
 
1185
                    } else if (LTTngControlServiceConstants.EVENT_SECTION_PATTERN.matcher(subLine).matches()) {
 
1186
                        List<IEventInfo> events = new ArrayList<>();
 
1187
                        index = parseEvents(output, index, events);
 
1188
                        if (channelInfo != null) {
 
1189
                            channelInfo.setEvents(events);
 
1190
                        }
 
1191
                        // we want to stay at the current index to be able to
 
1192
                        // exit the domain
 
1193
                        continue;
 
1194
                    } else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(subLine).matches()) {
 
1195
                        return index;
 
1196
 
 
1197
                    } else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(subLine).matches()) {
 
1198
                        return index;
 
1199
                    }
 
1200
                    index++;
 
1201
                }
 
1202
            } else if (noKernelChannelMatcher.matches() || noUstChannelMatcher.matches()) {
 
1203
                // domain indicates that no channels were found -> return
 
1204
                index++;
 
1205
                return index;
 
1206
            }
 
1207
            index++;
 
1208
        }
 
1209
        return index;
 
1210
    }
 
1211
 
 
1212
    /**
 
1213
     * Parses the event information within a domain.
 
1214
     *
 
1215
     * @param output
 
1216
     *            - a command output array
 
1217
     * @param currentIndex
 
1218
     *            - current index in command output array
 
1219
     * @param events
 
1220
     *            - list for returning event information
 
1221
     * @return the new current index in command output array
 
1222
     */
 
1223
    protected int parseEvents(String[] output, int currentIndex, List<IEventInfo> events) {
 
1224
        int index = currentIndex;
 
1225
 
 
1226
        while (index < output.length) {
 
1227
            String line = output[index];
 
1228
            if (LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(line).matches()) {
 
1229
                // end of channel
 
1230
                return index;
 
1231
            } else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(line).matches()) {
 
1232
                // end of domain
 
1233
                return index;
 
1234
            } else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(line).matches()) {
 
1235
                // end of domain
 
1236
                return index;
 
1237
            }
 
1238
 
 
1239
            Matcher matcher = LTTngControlServiceConstants.EVENT_PATTERN.matcher(line);
 
1240
            Matcher matcher2 = LTTngControlServiceConstants.WILDCARD_EVENT_PATTERN.matcher(line);
 
1241
 
 
1242
            if (matcher.matches()) {
 
1243
                IEventInfo eventInfo = new EventInfo(matcher.group(1).trim());
 
1244
                eventInfo.setLogLevelType(matcher.group(2).trim());
 
1245
                eventInfo.setLogLevel(matcher.group(3).trim());
 
1246
                eventInfo.setEventType(matcher.group(4).trim());
 
1247
                eventInfo.setState(matcher.group(5));
 
1248
                String filter = matcher.group(6);
 
1249
                if (filter != null) {
 
1250
                    filter = filter.substring(1, filter.length() - 1); // remove '[' and ']'
 
1251
                    eventInfo.setFilterExpression(filter);
 
1252
                }
 
1253
                events.add(eventInfo);
 
1254
                index++;
 
1255
            } else if (matcher2.matches()) {
 
1256
                IEventInfo eventInfo = new EventInfo(matcher2.group(1).trim());
 
1257
                eventInfo.setLogLevel(TraceLogLevel.LEVEL_UNKNOWN);
 
1258
                eventInfo.setEventType(matcher2.group(2).trim());
 
1259
                eventInfo.setState(matcher2.group(3));
 
1260
                String filter = matcher2.group(4);
 
1261
                if (filter != null) {
 
1262
                    filter = filter.substring(1, filter.length() - 1); // remove '[' and ']'
 
1263
                    eventInfo.setFilterExpression(filter);
 
1264
                }
 
1265
 
 
1266
                if ((eventInfo.getEventType() == TraceEventType.PROBE) ||
 
1267
                        (eventInfo.getEventType() == TraceEventType.FUNCTION)){
 
1268
                    IProbeEventInfo probeEvent = new ProbeEventInfo(eventInfo.getName());
 
1269
                    probeEvent.setLogLevel(eventInfo.getLogLevel());
 
1270
                    probeEvent.setEventType(eventInfo.getEventType());
 
1271
                    probeEvent.setState(eventInfo.getState());
 
1272
 
 
1273
                    // Overwrite eventinfo
 
1274
                    eventInfo = probeEvent;
 
1275
 
 
1276
                    // myevent2 (type: probe) [enabled]
 
1277
                    // addr: 0xc0101340
 
1278
                    // myevent0 (type: function) [enabled]
 
1279
                    // offset: 0x0
 
1280
                    // symbol: init_post
 
1281
                    index++;
 
1282
                    while (index < output.length) {
 
1283
                        String probeLine = output[index];
 
1284
                        // parse probe
 
1285
                        Matcher addrMatcher = LTTngControlServiceConstants.PROBE_ADDRESS_PATTERN.matcher(probeLine);
 
1286
                        Matcher offsetMatcher = LTTngControlServiceConstants.PROBE_OFFSET_PATTERN.matcher(probeLine);
 
1287
                        Matcher symbolMatcher = LTTngControlServiceConstants.PROBE_SYMBOL_PATTERN.matcher(probeLine);
 
1288
                        if (addrMatcher.matches()) {
 
1289
                            String addr = addrMatcher.group(2).trim();
 
1290
                            probeEvent.setAddress(addr);
 
1291
                        } else if (offsetMatcher.matches()) {
 
1292
                            String offset = offsetMatcher.group(2).trim();
 
1293
                            probeEvent.setOffset(offset);
 
1294
                        } else if (symbolMatcher.matches()) {
 
1295
                            String symbol = symbolMatcher.group(2).trim();
 
1296
                            probeEvent.setSymbol(symbol);
 
1297
                        } else if ((LTTngControlServiceConstants.EVENT_PATTERN.matcher(probeLine).matches()) || (LTTngControlServiceConstants.WILDCARD_EVENT_PATTERN.matcher(probeLine).matches())) {
 
1298
                            break;
 
1299
                        } else if (LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(probeLine).matches()) {
 
1300
                            break;
 
1301
                        } else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(probeLine).matches()) {
 
1302
                            // end of domain
 
1303
                            break;
 
1304
                        } else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(probeLine).matches()) {
 
1305
                            // end of domain
 
1306
                            break;
 
1307
                        }
 
1308
                        index++;
 
1309
                    }
 
1310
                    events.add(eventInfo);
 
1311
                } else {
 
1312
                    events.add(eventInfo);
 
1313
                    index++;
 
1314
                    continue;
 
1315
                }
 
1316
            } else {
 
1317
                index++;
 
1318
            }
 
1319
        }
 
1320
 
 
1321
        return index;
 
1322
    }
 
1323
 
 
1324
    /**
 
1325
     * Parses a line with attributes: <attribute Name>: <attribute value>
 
1326
     *
 
1327
     * @param line
 
1328
     *            - attribute line to parse
 
1329
     * @return the attribute value as string
 
1330
     */
 
1331
    protected String getAttributeValue(String line) {
 
1332
        String[] temp = line.split("\\: "); //$NON-NLS-1$
 
1333
        return temp[1];
 
1334
    }
 
1335
 
 
1336
    /**
 
1337
     * Parses the event information within a provider.
 
1338
     *
 
1339
     * @param output
 
1340
     *            - a command output array
 
1341
     * @param currentIndex
 
1342
     *            - current index in command output array
 
1343
     * @param events
 
1344
     *            - list for returning event information
 
1345
     * @return the new current index in command output array
 
1346
     */
 
1347
    protected int getProviderEventInfo(String[] output, int currentIndex, List<IBaseEventInfo> events) {
 
1348
        int index = currentIndex;
 
1349
        IBaseEventInfo eventInfo = null;
 
1350
        while (index < output.length) {
 
1351
            String line = output[index];
 
1352
            Matcher matcher = LTTngControlServiceConstants.PROVIDER_EVENT_PATTERN.matcher(line);
 
1353
            if (matcher.matches()) {
 
1354
                // sched_kthread_stop (loglevel: TRACE_EMERG0) (type: tracepoint)
 
1355
                eventInfo = new BaseEventInfo(matcher.group(1).trim());
 
1356
                eventInfo.setLogLevel(matcher.group(2).trim());
 
1357
                eventInfo.setEventType(matcher.group(3).trim());
 
1358
                events.add(eventInfo);
 
1359
                index++;
 
1360
            } else if (LTTngControlServiceConstants.EVENT_FIELD_PATTERN.matcher(line).matches()) {
 
1361
                if (eventInfo != null) {
 
1362
                    List<IFieldInfo> fields = new ArrayList<>();
 
1363
                    index = getFieldInfo(output, index, fields);
 
1364
                    eventInfo.setFields(fields);
 
1365
                } else {
 
1366
                    index++;
 
1367
                }
 
1368
            }
 
1369
            else if (LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line).matches()) {
 
1370
                return index;
 
1371
            } else {
 
1372
                index++;
 
1373
            }
 
1374
        }
 
1375
        return index;
 
1376
    }
 
1377
 
 
1378
 
 
1379
    /**
 
1380
     * Parse a field's information.
 
1381
     *
 
1382
     * @param output
 
1383
     *            A command output array
 
1384
     * @param currentIndex
 
1385
     *            The current index in the command output array
 
1386
     * @param fields
 
1387
     *            List for returning the field information
 
1388
     * @return The new current index in the command output array
 
1389
     */
 
1390
    protected int getFieldInfo(String[] output, int currentIndex, List<IFieldInfo> fields) {
 
1391
        int index = currentIndex;
 
1392
        IFieldInfo fieldInfo = null;
 
1393
        while (index < output.length) {
 
1394
            String line = output[index];
 
1395
            Matcher matcher = LTTngControlServiceConstants.EVENT_FIELD_PATTERN.matcher(line);
 
1396
            if (matcher.matches()) {
 
1397
                // field: content (string)
 
1398
                fieldInfo = new FieldInfo(matcher.group(2).trim());
 
1399
                fieldInfo.setFieldType(matcher.group(3).trim());
 
1400
                fields.add(fieldInfo);
 
1401
            } else if (LTTngControlServiceConstants.PROVIDER_EVENT_PATTERN.matcher(line).matches()) {
 
1402
                return index;
 
1403
            } else if (LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line).matches()) {
 
1404
                return index;
 
1405
            }
 
1406
            index++;
 
1407
        }
 
1408
        return index;
 
1409
    }
 
1410
 
 
1411
    /**
 
1412
     * Formats a command parameter for the command execution i.e. adds quotes
 
1413
     * at the beginning and end if necessary.
 
1414
     * @param parameter - parameter to format
 
1415
     * @return formated parameter
 
1416
     */
 
1417
    protected String formatParameter(String parameter) {
 
1418
        if (parameter != null) {
 
1419
            StringBuffer newString = new StringBuffer();
 
1420
            newString.append(parameter);
 
1421
 
 
1422
            if (parameter.contains(" ") || parameter.contains("*")) { //$NON-NLS-1$ //$NON-NLS-2$
 
1423
                newString.insert(0, "\""); //$NON-NLS-1$
 
1424
                newString.append("\""); //$NON-NLS-1$
 
1425
            }
 
1426
            return newString.toString();
 
1427
        }
 
1428
        return null;
 
1429
    }
 
1430
 
 
1431
    /**
 
1432
     * @param strings array of string that makes up a command line
 
1433
     * @return string buffer with created command line
 
1434
     */
 
1435
    protected StringBuffer createCommand(String... strings) {
 
1436
        StringBuffer command = new StringBuffer();
 
1437
        command.append(LTTngControlServiceConstants.CONTROL_COMMAND);
 
1438
        command.append(getTracingGroupOption());
 
1439
        command.append(getVerboseOption());
 
1440
        for (String string : strings) {
 
1441
            command.append(string);
 
1442
        }
 
1443
        return command;
 
1444
    }
 
1445
 
 
1446
    /**
 
1447
     * @return the tracing group option if configured in the preferences
 
1448
     */
 
1449
    protected String getTracingGroupOption() {
 
1450
        if (!ControlPreferences.getInstance().isDefaultTracingGroup() && !ControlPreferences.getInstance().getTracingGroup().equals("")) { //$NON-NLS-1$
 
1451
            return LTTngControlServiceConstants.OPTION_TRACING_GROUP + ControlPreferences.getInstance().getTracingGroup();
 
1452
        }
 
1453
        return ""; //$NON-NLS-1$
 
1454
    }
 
1455
 
 
1456
    /**
 
1457
     * @return the verbose option as configured in the preferences
 
1458
     */
 
1459
    protected String getVerboseOption() {
 
1460
        if (ControlPreferences.getInstance().isLoggingEnabled()) {
 
1461
            String level = ControlPreferences.getInstance().getVerboseLevel();
 
1462
            if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_VERBOSE.equals(level)) {
 
1463
                return LTTngControlServiceConstants.OPTION_VERBOSE;
 
1464
            }
 
1465
            if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_V_VERBOSE.equals(level)) {
 
1466
                return LTTngControlServiceConstants.OPTION_VERY_VERBOSE;
 
1467
            }
 
1468
            if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_V_V_VERBOSE.equals(level)) {
 
1469
                return LTTngControlServiceConstants.OPTION_VERY_VERY_VERBOSE;
 
1470
            }
 
1471
        }
 
1472
        return ""; //$NON-NLS-1$
 
1473
    }
 
1474
 
 
1475
    /**
 
1476
     * Method that logs the command and command result if logging is enabled as
 
1477
     * well as forwards the command execution to the shell.
 
1478
     *
 
1479
     * @param command
 
1480
     *            - the command to execute
 
1481
     * @param monitor
 
1482
     *            - a progress monitor
 
1483
     * @return the command result
 
1484
     * @throws ExecutionException
 
1485
     *             If the command fails
 
1486
     */
 
1487
    protected ICommandResult executeCommand(String command,
 
1488
            IProgressMonitor monitor) throws ExecutionException {
 
1489
        return executeCommand(command, monitor, true);
 
1490
    }
 
1491
 
 
1492
    /**
 
1493
     * Method that logs the command and command result if logging is enabled as
 
1494
     * well as forwards the command execution to the shell.
 
1495
     *
 
1496
     * @param command
 
1497
     *            - the command to execute
 
1498
     * @param monitor
 
1499
     *            - a progress monitor
 
1500
     * @param checkForError
 
1501
     *            - true to verify command result, else false
 
1502
     * @return the command result
 
1503
     * @throws ExecutionException
 
1504
     *             in case of error result
 
1505
     */
 
1506
    protected ICommandResult executeCommand(String command,
 
1507
            IProgressMonitor monitor, boolean checkForError)
 
1508
            throws ExecutionException {
 
1509
        if (ControlPreferences.getInstance().isLoggingEnabled()) {
 
1510
            ControlCommandLogger.log(command);
 
1511
        }
 
1512
 
 
1513
        ICommandResult result = fCommandShell.executeCommand(
 
1514
                command.toString(), monitor);
 
1515
 
 
1516
        if (ControlPreferences.getInstance().isLoggingEnabled()) {
 
1517
            ControlCommandLogger.log(formatOutput(result));
 
1518
        }
 
1519
 
 
1520
        if (checkForError && isError(result)) {
 
1521
            throw new ExecutionException(Messages.TraceControl_CommandError
 
1522
                    + " " + command.toString() + "\n" + formatOutput(result)); //$NON-NLS-1$ //$NON-NLS-2$
 
1523
        }
 
1524
 
 
1525
        return result;
 
1526
    }
 
1527
}