1 /**********************************************************************
2 * Copyright (c) 2015 École Polytechnique de Montréal
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 * Patrick-Jeffrey Pollo Guilbert, William Enright,
11 * William Tri-Khiem Truong - Initial API and implementation
12 **********************************************************************/
14 package org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.dialogs
;
16 import java
.io
.BufferedReader
;
18 import java
.io
.FileNotFoundException
;
19 import java
.io
.FileReader
;
20 import java
.io
.FilenameFilter
;
21 import java
.io
.IOException
;
22 import java
.net
.MalformedURLException
;
24 import java
.util
.ArrayList
;
25 import java
.util
.List
;
27 import javax
.xml
.parsers
.DocumentBuilder
;
28 import javax
.xml
.parsers
.DocumentBuilderFactory
;
29 import javax
.xml
.parsers
.ParserConfigurationException
;
31 import org
.eclipse
.core
.runtime
.PlatformObject
;
32 import org
.eclipse
.jface
.dialogs
.TitleAreaDialog
;
33 import org
.eclipse
.jface
.layout
.GridLayoutFactory
;
34 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
35 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
36 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
37 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
38 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
39 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
40 import org
.eclipse
.jface
.viewers
.TreeViewer
;
41 import org
.eclipse
.jface
.viewers
.Viewer
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.events
.HelpEvent
;
44 import org
.eclipse
.swt
.events
.HelpListener
;
45 import org
.eclipse
.swt
.graphics
.Color
;
46 import org
.eclipse
.swt
.layout
.GridData
;
47 import org
.eclipse
.swt
.widgets
.Composite
;
48 import org
.eclipse
.swt
.widgets
.Control
;
49 import org
.eclipse
.swt
.widgets
.Shell
;
50 import org
.eclipse
.swt
.widgets
.Text
;
51 import org
.eclipse
.tracecompass
.internal
.lttng2
.control
.ui
.views
.messages
.Messages
;
52 import org
.eclipse
.ui
.PartInitException
;
53 import org
.eclipse
.ui
.PlatformUI
;
54 import org
.eclipse
.ui
.dialogs
.FilteredTree
;
55 import org
.eclipse
.ui
.dialogs
.PatternFilter
;
56 import org
.w3c
.dom
.Comment
;
57 import org
.w3c
.dom
.Document
;
58 import org
.w3c
.dom
.Node
;
59 import org
.w3c
.dom
.NodeList
;
60 import org
.xml
.sax
.SAXException
;
65 * Dialog box using profiles
68 * @author William Enright, Patrick-Jeffrey Pollo Guilbert, William Tri-Khiem
73 public class ProfileDialog
extends TitleAreaDialog
{
75 private Composite fBase
;
76 private Composite fLabel
;
77 private CheckboxTreeViewer fCbtv
;
78 private Text descriptionText
;
79 private ArrayList
<File
> fSessionFiles
= new ArrayList
<>();
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
88 * - a shell for the display of the dialog
90 public ProfileDialog(Shell parentShell
) {
96 protected Control
createDialogArea(Composite parent
) {
98 setTitle(Messages
.TraceControl_BasicMode
);
99 setMessage(Messages
.TraceControl_SelectBasicProfile
);
101 Composite parentComp
= (Composite
) super.createDialogArea(parent
);
103 fBase
= new Composite(parentComp
, SWT
.NONE
);
105 // Creating composite for label group
106 fLabel
= new Composite(parentComp
, SWT
.NONE
);
107 fLabel
.setLayout(GridLayoutFactory
.swtDefaults().numColumns(1).create());
108 fLabel
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
110 descriptionText
= new Text(fLabel
, SWT
.READ_ONLY
| SWT
.BORDER
| SWT
.MULTI
);
111 descriptionText
.setText(Messages
.TraceControl_NoProfileSelected
+ "\n\n\n\n\n"); //$NON-NLS-1$
112 descriptionText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
113 descriptionText
.setBackground(new Color(null, 255, 255, 255));
114 fBase
.addHelpListener(new HelpListener() {
117 public void helpRequested(HelpEvent e
) {
119 PlatformUI
.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL("http://archive.eclipse.org/tracecompass/doc/org.eclipse.tracecompass.doc.user/LTTng-Tracer-Control.html#Control_View")); //$NON-NLS-1$
120 } catch (PartInitException e1
) {
122 } catch (MalformedURLException e1
) {
129 fBase
.setLayout(GridLayoutFactory
.swtDefaults().numColumns(1).create());
130 fBase
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
131 FilteredTree ft
= new FilteredTree(fBase
, SWT
.MULTI
| SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.BORDER
, new PatternFilter(), true) {
133 protected TreeViewer
doCreateTreeViewer(Composite aparent
, int style
) {
134 fCbtv
= new CheckboxTreeViewer(fBase
);
135 fCbtv
.getTree().setLayoutData(new GridData(GridData
.FILL_BOTH
));
136 fCbtv
.setContentProvider(new BasicContentProvider());
138 fCbtv
.setInput(initialize());
139 } catch (IOException e
) {
147 ft
.setBounds(0, 0, 500, 500);
148 fCbtv
.addSelectionChangedListener(new ProfileSelectionChangedListener());
153 // Updates text to be displayed in the textbox for profile description
154 private void updateSelectionText(IStructuredSelection sel
, boolean uncheck
)
156 Object
[] obj
= fCbtv
.getCheckedElements();
159 if (fCbtv
.getCheckedElements().length
== 0)
161 descriptionText
.setText(Messages
.NoSelectionDescription
);
163 else if (fCbtv
.getCheckedElements().length
!= 1 && fCbtv
.getCheckedElements().length
!= 0)
165 descriptionText
.setText(Messages
.TraceControl_MultipleSelectionDescription
);
168 TreeParent checkedElement
;
169 boolean commentFound
= false;
171 checkedElement
= (TreeParent
) obj
[0];
173 checkedElement
= (TreeParent
) sel
.getFirstElement();
176 TreeParent currentParent
= checkedElement
.getParent();
177 String parentPath
= currentParent
.getName();
179 if (fCbtv
.getChecked(checkedElement
))
181 DocumentBuilderFactory factory
= DocumentBuilderFactory
.newInstance();
183 DocumentBuilder builder
= factory
.newDocumentBuilder();
184 factory
.setIgnoringComments(false);
185 String fullPath
= parentPath
+ checkedElement
.getName();
186 Document document
= builder
.parse(new File(fullPath
));
187 document
.getDocumentElement().normalize();
188 NodeList nl
= document
.getChildNodes();
189 for (int i
= 0; i
< nl
.getLength(); i
++) {
190 if (nl
.item(i
).getNodeType() == Node
.COMMENT_NODE
) {
192 Comment comment
= (Comment
) nl
.item(i
);
193 descriptionText
.setText(comment
.getData());
198 descriptionText
.setText(Messages
.TraceControl_SingleSelectionDescription
);
200 } catch (ParserConfigurationException e
) {
202 } catch (SAXException e
) {
204 } catch (IOException e
) {
213 private List
<TreeParent
> addCustomFolders() throws IOException
215 String basicPath
= getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
216 basicPath
= basicPath
+ "resources/folders.txt"; //$NON-NLS-1$
217 String thisLine
= ""; //$NON-NLS-1$
218 List
<TreeParent
> folderList
= new ArrayList
<>();
220 try (BufferedReader reader
= new BufferedReader(new FileReader(basicPath
))) {
221 while ((thisLine
= reader
.readLine()) != null) {
223 for (String retval
: thisLine
.split("\n")) { //$NON-NLS-1$
224 if (!retval
.equals("")) { //$NON-NLS-1$
225 List
<TreeParent
> filesList
= new ArrayList
<>();
226 TreeParent newParent
= new TreeParent(thisLine
);
227 filesList
= addFilesFromFolder(thisLine
);
229 for (int i
= 0; i
< filesList
.size(); i
++)
231 newParent
.addChild(new TreeParent(filesList
.get(i
).getName()));
233 folderList
.add(newParent
);
237 } catch (FileNotFoundException e
) {
238 System
.out
.printf(Messages
.TraceControl_ReadingPathError
, basicPath
);
243 private List
<TreeParent
> addFilesFromFolder(String folderPath
)
245 List
<TreeParent
> fileList
= new ArrayList
<>();
246 File dir
= new File(folderPath
);
247 File
[] files
= dir
.listFiles(new FilenameFilter() {
249 public boolean accept(File dir1
, String name
) {
250 return name
.toLowerCase().endsWith(Messages
.TraceControl_LttngSuffix
);
258 fSessionFiles
.add(f
);
259 fileList
.add(new TreeParent(f
.getName()));
266 private TreeParent
initialize() throws IOException
{
268 String absolutePath
= getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
269 String defaultPath
= absolutePath
+ "resources/"; //$NON-NLS-1$
271 TreeParent root
= new TreeParent("Root"); //$NON-NLS-1$
273 List
<TreeParent
> sessionFilesList
= new ArrayList
<>();
274 sessionFilesList
= addFilesFromFolder(defaultPath
);
276 TreeParent defaultTP
= new TreeParent(defaultPath
);
278 for (int i
= 0; i
< sessionFilesList
.size(); i
++)
280 defaultTP
.addChild(sessionFilesList
.get(i
));
283 root
.addChild(defaultTP
);
285 List
<TreeParent
> customList
= new ArrayList
<>();
286 customList
= addCustomFolders();
288 for (TreeParent tp
: customList
)
296 private final class ProfileSelectionChangedListener
implements ISelectionChangedListener
{
298 public void selectionChanged(SelectionChangedEvent event
) {
300 if (!(event
.getSelection().isEmpty()) && event
.getSelection() instanceof IStructuredSelection
)
302 IStructuredSelection sel
= (IStructuredSelection
) event
.getSelection();
304 updateSelectionText(sel
, false);
305 Object selectedObject
= sel
.getFirstElement();
306 updateCheckedProfiles(sel
, selectedObject
);
310 private void updateCheckedProfiles(IStructuredSelection sel
, Object selectedObject
) {
311 // Check if all the other brothers are checked, if so, check parent
312 // TreeObject is checked
313 if (fCbtv
.getChecked(selectedObject
)) {
314 ArrayList
<TreeObject
> allParents
= ((TreeObject
) selectedObject
).getAllParents();
315 for (TreeObject parentAbove
: allParents
) {
316 Boolean brothersChecked
= true;
317 ArrayList
<TreeObject
> allChildren
= ((TreeParent
) parentAbove
).getAllChildren();
318 for (TreeObject child
: allChildren
) {
319 // TreeParent is checked
320 if (!fCbtv
.getChecked(child
)) {
321 brothersChecked
= false;
324 if (brothersChecked
) {
325 fCbtv
.setChecked(parentAbove
, true);
330 if (selectedObject
.getClass() == TreeParent
.class)
332 // TreeParent is checked, must check all children
333 if (fCbtv
.getChecked(selectedObject
)) {
334 ArrayList
<TreeObject
> allChildren
= ((TreeParent
) selectedObject
).getAllChildren();
335 for (TreeObject child
: allChildren
) {
336 fCbtv
.setChecked(child
, true);
338 fCbtv
.expandToLevel(selectedObject
, AbstractTreeViewer
.ALL_LEVELS
);
340 // TreeParent is unchecked, must uncheck children and parent,
343 ArrayList
<TreeObject
> allChildren
= ((TreeParent
) selectedObject
).getAllChildren();
344 for (TreeObject child
: allChildren
) {
345 fCbtv
.setChecked(child
, false);
346 updateSelectionText(sel
, true);
348 ArrayList
<TreeObject
> allParents
= ((TreeObject
) selectedObject
).getAllParents();
349 for (TreeObject parentAbove
: allParents
) {
350 fCbtv
.setChecked(parentAbove
, false);
351 updateSelectionText(sel
, true);
355 } else if (selectedObject
.getClass() == TreeObject
.class) {
356 // TreeObject is checked
357 if (fCbtv
.getChecked(selectedObject
)) {
360 // TreeObject is unchecked
362 ArrayList
<TreeObject
> allParents
= ((TreeObject
) selectedObject
).getAllParents();
363 for (TreeObject parentAbove
: allParents
) {
364 fCbtv
.setChecked(parentAbove
, false);
371 class TreeObject
extends PlatformObject
{
373 private TreeParent parent
;
375 public TreeObject(String name
) {
379 public String
getName() {
383 public void setParent(TreeParent parent
) {
384 this.parent
= parent
;
387 public TreeParent
getParent() {
391 public ArrayList
<TreeObject
> getAllParents() {
392 ArrayList
<TreeObject
> both
= new ArrayList
<>();
393 TreeObject parentTemp
= getParent();
394 if (parentTemp
!= null) { // is not root, has more parents
395 both
.add(parentTemp
);
396 both
.addAll(parentTemp
.getAllParents());
403 public String
toString() {
409 class TreeParent
extends TreeObject
{
410 private ArrayList
<TreeObject
> children
;
412 public TreeParent(String name
) {
414 children
= new ArrayList
<>();
417 public void addChild(TreeObject child
) {
419 child
.setParent(this);
422 public void removeChild(TreeObject child
) {
423 children
.remove(child
);
424 child
.setParent(null);
427 public TreeObject
[] getChildren() {
428 return children
.toArray(new TreeObject
[children
.size()]);
431 public ArrayList
<TreeObject
> getAllChildren()
433 ArrayList
<TreeObject
> both
= new ArrayList
<>();
434 for (Object child
: getChildren()) {
435 if (child
.getClass() == TreeParent
.class) { // is a parent
436 both
.add((TreeObject
) child
);
437 both
.addAll(((TreeParent
) child
).getAllChildren());
439 both
.add((TreeObject
) child
);
445 public boolean hasChildren() {
446 return children
.size() > 0;
450 class BasicContentProvider
implements ITreeContentProvider
{
451 private TreeParent invisibleRoot
;
454 public void inputChanged(Viewer v
, Object oldInput
, Object newInput
) {
458 public void dispose() {
462 public Object
[] getElements(Object parent
) {
463 if (parent
.equals(null)) {
464 if (invisibleRoot
== null) {
466 invisibleRoot
= initialize();
467 } catch (IOException e
) {
471 return getChildren(invisibleRoot
);
473 return getChildren(parent
);
477 public Object
getParent(Object child
) {
478 if (child
instanceof TreeObject
) {
479 return ((TreeObject
) child
).getParent();
485 public Object
[] getChildren(Object parent
) {
486 if (parent
instanceof TreeParent
) {
487 return ((TreeParent
) parent
).getChildren();
489 return new Object
[0];
493 public boolean hasChildren(Object parent
) {
494 if (parent
instanceof TreeParent
) {
495 return ((TreeParent
) parent
).hasChildren();
502 protected boolean isResizable() {
507 protected void okPressed()
509 Object
[] checkedElements
= fCbtv
.getCheckedElements();
511 if (checkedElements
.length
!= 0) {
512 ArrayList
<File
> temp
= new ArrayList
<>();
513 for (Object checked
: checkedElements
) {
514 String sessionName
= ((TreeParent
) checked
).toString();
515 if (sessionName
.endsWith(Messages
.ProfileDialog_LTTNG_Suffix
)) {
517 for (File f
: fSessionFiles
) {
518 if (f
.getAbsolutePath().endsWith(sessionName
)) {
524 fSessionFiles
= temp
;
531 * @return the list of checked files
533 public ArrayList
<File
> getCheckedFiles() {
534 return fSessionFiles
;