| /******************************************************************************* |
| * Copyright (c) 2017 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.function.Predicate; |
| import java.util.regex.Pattern; |
| import java.util.regex.PatternSyntaxException; |
| |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.StructuredViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| |
| /** |
| * A filter extending the |
| * <code>org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TreePatternFilter<code>. |
| * |
| * The user can now enter multiple filters (separated by '/'). The filter also |
| * detects a match if a subsequence of a tree element matches the pattern. |
| * |
| * @author Mikael Ferland |
| * @since 3.2 |
| */ |
| public class MultiTreePatternFilter extends TreePatternFilter { |
| |
| /** |
| * List of Predicates to test the column texts, ordered from leaf to root. |
| */ |
| private final List<Predicate<String>> fPredicates = new ArrayList<>(); |
| |
| @Override |
| public void setPattern(String patternString) { |
| fPredicates.clear(); |
| super.setPattern(patternString); |
| if (patternString == null || patternString.isEmpty()) { |
| return; |
| } |
| |
| /* |
| * The asterisk (*) wildcard needs to be converted to a period (.) for it to be |
| * recognized by the Pattern class during regex compilation |
| */ |
| String[] split = patternString.replace('*', '.').split("/"); //$NON-NLS-1$ |
| for (int i = split.length - 1; i >= 0; i--) { |
| String filter = split[i]; |
| Predicate<String> predicate; |
| try { |
| Pattern pattern = Pattern.compile(filter, Pattern.CASE_INSENSITIVE); |
| predicate = s -> pattern.matcher(s).find(); |
| } catch (PatternSyntaxException e) { |
| predicate = s -> s.contains(filter); |
| } |
| fPredicates.add(predicate); |
| } |
| } |
| |
| @Override |
| protected boolean isLeafMatch(Viewer viewer, Object element) { |
| Object node = element; |
| StructuredViewer structuredViewer = (StructuredViewer) viewer; |
| ITableLabelProvider labelProvider = (ITableLabelProvider) structuredViewer.getLabelProvider(); |
| ITreeContentProvider treeContentProvider = (ITreeContentProvider) structuredViewer.getContentProvider(); |
| |
| // Ensure the tree element and its parent(s) match the filter text |
| for (Predicate<String> p : fPredicates) { |
| // Retrieve tree element text and make verification. Text is at column 0 |
| String labelText = labelProvider.getColumnText(node, 0); |
| if (labelText == null || !p.test(labelText)) { |
| return false; |
| } |
| |
| // Retrieve parent element |
| node = treeContentProvider.getParent(node); |
| } |
| return true; |
| } |
| } |