1 /*******************************************************************************
2 * Copyright (c) 2011 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Bernd Hufmann - Initial API and implementation
12 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng
.ui
.tracecontrol
.wizards
;
17 import org
.eclipse
.jface
.wizard
.WizardPage
;
18 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.tracecontrol
.model
.TraceResource
;
19 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.tracecontrol
.model
.TraceResource
.TraceState
;
20 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.tracecontrol
.model
.config
.TraceConfig
;
21 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.tracecontrol
.Messages
;
22 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.tracecontrol
.TraceControlConstants
;
23 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.tracecontrol
.subsystems
.TraceSubSystem
;
24 import org
.eclipse
.rse
.services
.clientserver
.messages
.SystemMessageException
;
25 import org
.eclipse
.rse
.ui
.SystemBasePlugin
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.events
.VerifyEvent
;
28 import org
.eclipse
.swt
.events
.VerifyListener
;
29 import org
.eclipse
.swt
.layout
.GridData
;
30 import org
.eclipse
.swt
.layout
.GridLayout
;
31 import org
.eclipse
.swt
.widgets
.Button
;
32 import org
.eclipse
.swt
.widgets
.Composite
;
33 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
34 import org
.eclipse
.swt
.widgets
.Display
;
35 import org
.eclipse
.swt
.widgets
.Event
;
36 import org
.eclipse
.swt
.widgets
.Group
;
37 import org
.eclipse
.swt
.widgets
.Label
;
38 import org
.eclipse
.swt
.widgets
.Listener
;
39 import org
.eclipse
.swt
.widgets
.Text
;
42 * <b><u>UstTraceChannelConfigurationPage</u></b>
44 * Wizard page implementation to configure a trace (Kernel and UST).
47 public class TraceConfigurationPage
extends WizardPage
{
49 // ------------------------------------------------------------------------
51 // ------------------------------------------------------------------------
52 private ConfigureTraceWizard fWizard
;
53 private String fTraceName
;
54 private String fTraceTransport
;
55 private String fTracePath
;
57 private int fNumChannel
;
58 private boolean fIsAppend
;
59 private boolean fIsNetwork
;
60 private Text fNameText
;
61 private Text fTransportText
;
62 private Text fPathText
;
63 private Text fNumLttdThreadsText
;
64 private Button fHostButton
;
65 private Button fTargetButton
;
66 private Button fIsAppendButton
;
67 private Button fFlightRecorderButton
;
68 private Button fNormalButton
;
69 private Display fDisplay
;
70 private String fTraceNameError
;
71 private String fTracePathError
;
72 private Button fBrowseButton
;
74 private TraceResource fTraceResource
;
75 private TraceConfig fOldTraceConfig
;
76 private TraceSubSystem fSubSystem
;
78 // ------------------------------------------------------------------------
80 // ------------------------------------------------------------------------
87 public TraceConfigurationPage(ConfigureTraceWizard wizard
) {
88 super("TraceConfigurationPage"); //$NON-NLS-1$
89 setTitle(Messages
.ConfigureTraceDialog_Title
);
90 // setDescription("set description...");
91 this.fWizard
= wizard
;
92 setPageComplete(false);
93 fTraceNameError
= ""; //$NON-NLS-1$
94 fTracePathError
= ""; //$NON-NLS-1$
95 fTraceResource
= this.fWizard
.getSelectedTrace();
96 fOldTraceConfig
= fTraceResource
.getTraceConfig();
97 fSubSystem
= (TraceSubSystem
)this.fWizard
.getSelectedTrace().getSubSystem();
100 // ------------------------------------------------------------------------
102 // ------------------------------------------------------------------------
106 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
109 public void createControl(Composite parent
) {
110 GridData griddata
= new GridData();
112 griddata
= new GridData();
113 Composite composite1
= new Composite(parent
, SWT
.NONE
);
114 GridLayout compositeLayout1
= new GridLayout(4, false);
115 composite1
.setSize(520, 300);
116 composite1
.setLayout(compositeLayout1
);
117 griddata
.horizontalSpan
= 3;
118 griddata
.widthHint
= 520;
119 griddata
.minimumWidth
= 520;
120 composite1
.setLayoutData(griddata
);
121 fDisplay
= this.getShell().getDisplay();
122 setControl(composite1
);
123 Label nameLabel
= new Label(composite1
, SWT
.NULL
);
124 nameLabel
.setText(Messages
.NewTraceDialog_TraceName
+ ":"); //$NON-NLS-1$
125 griddata
= new GridData();
126 griddata
.verticalIndent
= 20;
127 nameLabel
.setLayoutData(griddata
);
129 fNameText
= new Text(composite1
, SWT
.SINGLE
| SWT
.BORDER
);
130 if (fTraceResource
.isUst()) {
131 fNameText
.setText(TraceControlConstants
.Lttng_Ust_TraceName
);
132 fNameText
.setEnabled(false);
135 griddata
= new GridData();
136 griddata
.horizontalAlignment
= SWT
.FILL
;
137 griddata
.grabExcessHorizontalSpace
= true;
138 griddata
.verticalIndent
= 20;
139 griddata
.horizontalSpan
= 3;
140 fNameText
.setLayoutData(griddata
);
141 fNameText
.setText(fTraceResource
.getName());
142 fNameText
.setEnabled(false);
144 Label transportLabel
= new Label(composite1
, SWT
.NULL
);
145 transportLabel
.setText(Messages
.ConfigureTraceDialog_Trace_Transport
+ ":"); //$NON-NLS-1$
146 griddata
= new GridData();
147 transportLabel
.setLayoutData(griddata
);
149 fTransportText
= new Text(composite1
, SWT
.SINGLE
| SWT
.BORDER
);
150 griddata
= new GridData();
151 griddata
.horizontalAlignment
= SWT
.FILL
;
152 griddata
.grabExcessHorizontalSpace
= true;
153 griddata
.horizontalSpan
= 3;
154 fTransportText
.setLayoutData(griddata
);
155 fTransportText
.setText(TraceControlConstants
.Lttng_Trace_Transport_Relay
);
156 fTransportText
.setEnabled(false); // relay is the only allowed value
157 if (fOldTraceConfig
!= null) {
158 fTransportText
.setText(fOldTraceConfig
.getTraceTransport());
161 griddata
= new GridData();
162 Group composite21
= new Group(composite1
, SWT
.SHADOW_OUT
);
163 composite21
.setSize(300, 300);
164 composite21
.setText(Messages
.ConfigureTraceDialog_Trace_Location
);
165 griddata
.horizontalAlignment
= SWT
.FILL
;
166 griddata
.horizontalSpan
= 4;
167 griddata
.verticalIndent
= 10;
168 griddata
.widthHint
= 300;
169 griddata
.minimumWidth
= 300;
170 composite21
.setLayoutData(griddata
);
171 GridLayout compositeLayout21
= new GridLayout(4, false);
172 composite21
.setLayout(compositeLayout21
);
173 fTargetButton
= new Button(composite21
, SWT
.RADIO
);
174 fTargetButton
.setText(Messages
.ConfigureTraceDialog_Target
);
175 fTargetButton
.setSelection(true);
177 fHostButton
= new Button(composite21
, SWT
.RADIO
);
178 fHostButton
.setText(Messages
.ConfigureTraceDialog_Host
);
179 griddata
= new GridData();
180 griddata
.horizontalSpan
= 3;
181 fHostButton
.setLayoutData(griddata
);
182 fHostButton
.addListener(SWT
.Selection
, new Listener() {
184 public void handleEvent(Event e
) {
185 if (fHostButton
.getSelection()) {
186 fBrowseButton
.setEnabled(true);
188 fBrowseButton
.setEnabled(false);
190 fIsNetwork
= fHostButton
.getSelection();
191 validatePathName(fPathText
.getText());
196 Label pathLabel
= new Label(composite21
, SWT
.NULL
);
197 pathLabel
.setText(Messages
.ConfigureTraceDialog_Trace_Path
);
198 griddata
= new GridData();
199 griddata
.verticalIndent
= 10;
200 pathLabel
.setLayoutData(griddata
);
202 fPathText
= new Text(composite21
, SWT
.SINGLE
| SWT
.BORDER
);
203 griddata
= new GridData();
204 griddata
.horizontalAlignment
= SWT
.FILL
;
205 griddata
.grabExcessHorizontalSpace
= true;
206 griddata
.verticalIndent
= 10;
207 fPathText
.setLayoutData(griddata
);
208 fPathText
.setData(""); //$NON-NLS-1$
210 fBrowseButton
= new Button(composite21
, SWT
.PUSH
);
211 fBrowseButton
.setText(Messages
.ConfigureTraceDialog_Browse
+ "..."); //$NON-NLS-1$
212 griddata
= new GridData();
213 griddata
.grabExcessHorizontalSpace
= false;
214 griddata
.widthHint
= 100;
215 griddata
.verticalIndent
= 10;
216 fBrowseButton
.setLayoutData(griddata
);
217 fBrowseButton
.setEnabled(false);
218 fBrowseButton
.addListener(SWT
.Selection
, new Listener() {
220 public void handleEvent(Event event
) {
221 DirectoryDialog dialog
= new DirectoryDialog(fDisplay
.getActiveShell());
222 String newPath
= dialog
.open();
223 if (newPath
!= null) {
224 fPathText
.setText(newPath
);
229 fNameText
.addListener(SWT
.Modify
, new Listener() {
231 public void handleEvent(Event event
) {
232 validateTraceName(fNameText
.getText());
237 fTransportText
.addListener(SWT
.Modify
, new Listener() {
239 public void handleEvent(Event event
) {
244 fPathText
.addListener(SWT
.Modify
, new Listener() {
246 public void handleEvent(Event event
) {
247 if (!fPathText
.isEnabled()) {
250 validatePathName(fPathText
.getText());
255 griddata
= new GridData();
256 Composite composite2
= new Composite(composite1
, SWT
.NONE
);
257 GridLayout compositeLayout2
= new GridLayout(2, false);
258 composite2
.setLayout(compositeLayout2
);
259 griddata
.horizontalSpan
= 4;
260 griddata
.widthHint
= 500;
261 griddata
.minimumWidth
= 500;
262 composite2
.setLayoutData(griddata
);
264 Label numLttdThreadsLabel
= new Label(composite2
, SWT
.NULL
);
265 numLttdThreadsLabel
.setText(Messages
.ConfigureTraceDialog_Num_Lttd_Threads
+ ":"); //$NON-NLS-1$);
266 griddata
= new GridData();
267 griddata
.verticalIndent
= 10;
268 numLttdThreadsLabel
.setLayoutData(griddata
);
270 fNumLttdThreadsText
= new Text(composite2
, SWT
.SINGLE
| SWT
.BORDER
);
271 griddata
= new GridData();
272 griddata
.horizontalAlignment
= SWT
.BEGINNING
;
273 griddata
.verticalIndent
= 10;
274 griddata
.widthHint
= 50;
275 griddata
.minimumWidth
= 50;
276 fNumLttdThreadsText
.setLayoutData(griddata
);
277 if (fTraceResource
.isUst()) {
278 fNumLttdThreadsText
.setText("1"); //$NON-NLS-1$
279 fNumLttdThreadsText
.setEnabled(false);
281 fNumLttdThreadsText
.setText("2"); //$NON-NLS-1$
284 fNumLttdThreadsText
.addVerifyListener(new VerifyListener() {
286 public void verifyText(VerifyEvent e
) {
287 e
.doit
= e
.text
.matches("[0-9]*"); //$NON-NLS-1$
291 fNumLttdThreadsText
.addListener(SWT
.Modify
, new Listener() {
293 public void handleEvent(Event event
) {
298 fIsAppendButton
= new Button(composite1
, SWT
.CHECK
);
299 fIsAppendButton
.setText(Messages
.ConfigureTraceDialog_Append
);
300 griddata
= new GridData();
301 griddata
.horizontalAlignment
= SWT
.BEGINNING
;
302 griddata
.horizontalSpan
= 4;
303 griddata
.verticalIndent
= 10;
304 fIsAppendButton
.setLayoutData(griddata
);
306 fIsAppendButton
.addListener(SWT
.Selection
, new Listener() {
308 public void handleEvent(Event e
) {
309 fIsAppend
= fIsAppendButton
.getSelection();
312 if (fTraceResource
.isUst()) {
313 fIsAppendButton
.setEnabled(false);
316 griddata
= new GridData();
317 Group composite22
= new Group(composite1
, SWT
.SHADOW_OUT
);
318 composite22
.setText(Messages
.ConfigureTraceDialog_Trace_Mode
);
319 griddata
.horizontalSpan
= 4;
320 griddata
.verticalIndent
= 10;
321 composite22
.setLayoutData(griddata
);
322 GridLayout compositeLayout22
= new GridLayout(2, false);
323 composite22
.setLayout(compositeLayout22
);
324 fNormalButton
= new Button(composite22
, SWT
.RADIO
);
325 fNormalButton
.setText(Messages
.ConfigureTraceDialog_Mode_Normal
);
326 fFlightRecorderButton
= new Button(composite22
, SWT
.RADIO
);
327 fFlightRecorderButton
.setText(Messages
.ConfigureTraceDialog_Mode_Flight_Recorder
);
328 fMode
= TraceConfig
.NORMAL_MODE
;
329 fNormalButton
.setSelection(true);
330 fNormalButton
.addListener(SWT
.Selection
, new Listener() {
332 public void handleEvent(Event e
) {
333 if (fNormalButton
.getSelection()) {
334 fMode
= TraceConfig
.NORMAL_MODE
;
338 fFlightRecorderButton
.addListener(SWT
.Selection
, new Listener() {
340 public void handleEvent(Event e
) {
341 if (fFlightRecorderButton
.getSelection()) {
342 fMode
= TraceConfig
.FLIGHT_RECORDER_MODE
;
346 if (fTraceResource
.isUst()) {
347 fFlightRecorderButton
.setEnabled(false);
348 fNormalButton
.setEnabled(false);
351 if(fOldTraceConfig
!= null) {
352 fPathText
.setText(fOldTraceConfig
.getTracePath());
353 fTargetButton
.setSelection(!fOldTraceConfig
.isNetworkTrace());
354 fHostButton
.setSelection(fOldTraceConfig
.isNetworkTrace());
355 fIsNetwork
= fOldTraceConfig
.isNetworkTrace();
356 fBrowseButton
.setEnabled(true);
357 fNumLttdThreadsText
.setText(String
.valueOf(fOldTraceConfig
.getNumChannel()));
358 fIsAppendButton
.setSelection(fOldTraceConfig
.getIsAppend());
359 fIsAppend
= fOldTraceConfig
.getIsAppend();
360 fFlightRecorderButton
.setSelection(fOldTraceConfig
.getMode() == TraceConfig
.FLIGHT_RECORDER_MODE
);
361 fNormalButton
.setSelection(fOldTraceConfig
.getMode() == TraceConfig
.NORMAL_MODE
);
364 // Depending on the state disable fields, it's only informational then
365 if ((fTraceResource
.getTraceState() == TraceState
.STARTED
) || (fTraceResource
.getTraceState() == TraceState
.PAUSED
)) {
366 fPathText
.setEnabled(false);
367 fBrowseButton
.setEnabled(false);
368 fTargetButton
.setEnabled(false);
369 fHostButton
.setEnabled(false);
370 fIsAppendButton
.setEnabled(false);
371 fNumLttdThreadsText
.setEnabled(false);
372 fFlightRecorderButton
.setEnabled(false);
373 fNormalButton
.setEnabled(false);
378 fDisplay
.getActiveShell().addListener(SWT
.Traverse
, new Listener() {
380 public void handleEvent(Event event
) {
381 if (event
.detail
== SWT
.TRAVERSE_ESCAPE
) {
390 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
393 public void dispose() {
398 * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
401 public void setVisible(boolean visible
) {
405 super.setVisible(visible
);
409 * Validates the trace name which has to be unique.
411 protected boolean validateTraceName(String name
) {
412 if (name
.length() > 0) {
413 TraceResource
[] traces
= new TraceResource
[0];
415 traces
= fSubSystem
.getAllTraces();
416 } catch (SystemMessageException e
) {
417 SystemBasePlugin
.logError("TraceConfigurationPage ", e
); //$NON-NLS-1$
419 for (int i
= 0; i
< traces
.length
; i
++) {
420 if (traces
[i
].getName().compareTo(name
) == 0) {
421 fTraceNameError
= Messages
.NewTraceDialog_Error_Already_Exists
;
422 setErrorMessage(fTraceNameError
);
426 final char[] chars
= name
.toCharArray();
427 for (int x
= 0; x
< chars
.length
; x
++) {
428 final char c
= chars
[x
];
429 if ((x
== 0) && !(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')))) {
430 fTraceNameError
= Messages
.NewTraceDialog_Error_Invalid_First_Char
;
431 setErrorMessage(fTraceNameError
);
434 if (!((c
>= 'a') && (c
<= 'z')) && !((c
>= 'A') && (c
<= 'Z')) && !((c
>= '0') && (c
<= '9'))) {
435 fTraceNameError
= Messages
.NewTraceDialog_Error_Invalid_Name
;
436 setErrorMessage(fTraceNameError
);
442 if (fTracePathError
.length() > 0) {
443 setErrorMessage(fTracePathError
);
445 setErrorMessage(null);
447 fTraceNameError
= ""; //$NON-NLS-1$
452 * Validates the trace path.
454 private boolean validatePathName(String path
) {
455 if (path
.length() > 0) {
456 final char c0
= path
.charAt(0);
458 fTracePathError
= Messages
.ConfigureTraceDialog_Error_Invalid_Path
;
459 setErrorMessage(fTracePathError
);
462 String
[] folders
= path
.split("/"); //$NON-NLS-1$
463 for (int i
= 0; i
< folders
.length
; i
++) {
464 final char[] chars
= folders
[i
].toCharArray();
465 for (int x
= 0; x
< chars
.length
; x
++) {
466 final char c
= chars
[x
];
467 if ((c
>= 'a') && (c
<= 'z')) {
468 continue; // lowercase
470 if ((c
>= 'A') && (c
<= 'Z')) {
471 continue; // uppercase
473 if ((c
>= '0') && (c
<= '9')) {
476 fTracePathError
= Messages
.ConfigureTraceDialog_Error_Invalid_Folder
;
477 setErrorMessage(fTracePathError
);
481 if (path
.length() > 1) {
482 for (int i
= 0; i
< path
.length() - 1; i
++) {
483 if ((path
.charAt(i
) == '/') && (path
.charAt(i
+ 1) == '/')) {
484 fTracePathError
= Messages
.ConfigureTraceDialog_Error_Multiple_Seps
;
485 setErrorMessage(fTracePathError
);
491 if (fHostButton
.getSelection()) {
492 File file
= new File(path
);
494 fTracePathError
= Messages
.ConfigureTraceDialog_Error_File_Exists
;
495 setErrorMessage(fTracePathError
);
498 if (path
.length() > 1 && !file
.getParentFile().canWrite()) {
499 fTracePathError
= Messages
.ConfigureTraceDialog_Error_Can_Not_Write
;
500 setErrorMessage(fTracePathError
);
505 if (fTraceNameError
.length() > 0) {
506 setErrorMessage(fTraceNameError
);
508 setErrorMessage(null);
510 fTracePathError
= ""; //$NON-NLS-1$
515 * Validates all input values.
517 private void validate() {
518 if ((fNameText
.getText() == null) || (fTransportText
.getText() == null) || (fTransportText
.getText().length() == 0) || (fNameText
.getText().length() == 0)
519 || (fNumLttdThreadsText
.getText().length() == 0) || (fNumLttdThreadsText
.getText().length() == 0)) {
520 setPageComplete(false);
523 if (fPathText
.getText().length() == 0) {
524 setPageComplete(false);
527 if ((fTracePathError
.length() > 0) || (fTraceNameError
.length() > 0)) {
528 setPageComplete(false);
531 fTraceName
= fNameText
.getText();
532 fTraceTransport
= fTransportText
.getText();
533 fTracePath
= fPathText
.getText();
534 fNumChannel
= Integer
.parseInt(fNumLttdThreadsText
.getText());
536 if (fTraceNameError
.length() == 0) {
537 setErrorMessage(null);
538 setPageComplete(true);
540 setErrorMessage(fTraceNameError
);
541 setPageComplete(false);
546 * Gets the trace configuration.
548 * @return trace configuration
550 public TraceConfig
getTraceConfig() {
551 TraceConfig newTraceConfig
= new TraceConfig();
552 newTraceConfig
.setTraceName(fTraceName
);
553 newTraceConfig
.setTraceTransport(fTraceTransport
);
554 newTraceConfig
.setTracePath(fTracePath
);
555 newTraceConfig
.setNetworkTrace(fIsNetwork
);
556 newTraceConfig
.setIsAppend(fIsAppend
);
557 newTraceConfig
.setMode(fMode
);
558 newTraceConfig
.setNumChannel(fNumChannel
);
560 return newTraceConfig
;
564 * Gets if trace is a local trace (i.e. if trace output is stored on host
565 * where client is running)
567 * @return isLocalTrace
569 public boolean isLocalTrace() {
570 return fHostButton
.getSelection();