blob: 73fb40826da4eea395ee08173292da7512bfefed [file] [log] [blame]
/*******************************************************************************
* 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;
}
}