blob: f55b7e00e4fe3fb2416308ab100056e20b718e67 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.search.internal.core.text;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.search.core.text.TextSearchScope;
public class FileNamePatternSearchScope extends TextSearchScope {
/**
* Returns a scope for the given resources.
* @param description description of the scope
* @param resources the resources to be contained
* @param includeDerived specifies if derived resources are included or not
* @return a scope for the given resources.
*/
public static FileNamePatternSearchScope newSearchScope(String description, IResource[] resources, boolean includeDerived) {
return new FileNamePatternSearchScope(description, removeRedundantEntries(resources, includeDerived), includeDerived);
}
private static final boolean IS_CASE_SENSITIVE_FILESYSTEM = !new File("Temp").equals(new File("temp")); //$NON-NLS-1$ //$NON-NLS-2$
private final String fDescription;
private final IResource[] fRootElements;
private final Set<String> fFileNamePatterns;
private Matcher fFileNameMatcher;
private boolean fVisitDerived;
private FileNamePatternSearchScope(String description, IResource[] resources, boolean visitDerived) {
Assert.isNotNull(description);
fDescription= description;
fRootElements= resources;
fFileNamePatterns= new HashSet<>(3);
fFileNameMatcher= null;
fVisitDerived= visitDerived;
}
/**
* Returns the description of the scope
* @return the description of the scope
*/
public String getDescription() {
return fDescription;
}
@Override
public IResource[] getRoots() {
return fRootElements;
}
@Override
public boolean contains(IResourceProxy proxy) {
if (!fVisitDerived && proxy.isDerived()) {
return false; // all resources in a derived folder are considered to be derived, see bug 103576
}
if (proxy.getType() == IResource.FILE) {
return matchesFileName(proxy.getName());
}
return true;
}
/**
* Adds an file name pattern to the scope.
*
* @param pattern the pattern
*/
public void addFileNamePattern(String pattern) {
if (fFileNamePatterns.add(pattern)) {
fFileNameMatcher= null; // clear cache
}
}
public void setFileNamePattern(Pattern pattern) {
fFileNameMatcher= pattern.matcher(""); //$NON-NLS-1$
}
public Pattern getFileNamePattern() {
return getFileNameMatcher().pattern();
}
/**
* Returns if derived resources are included in the scope.
*
* @return if set derived resources are included in the scope.
*/
public boolean isIncludeDerived() {
return fVisitDerived;
}
private Matcher getFileNameMatcher() {
if (fFileNameMatcher == null) {
Pattern pattern;
if (fFileNamePatterns.isEmpty()) {
pattern= Pattern.compile(".*"); //$NON-NLS-1$
} else {
String[] patternStrings= fFileNamePatterns.toArray(new String[fFileNamePatterns.size()]);
pattern= PatternConstructor.createPattern(patternStrings, IS_CASE_SENSITIVE_FILESYSTEM);
}
fFileNameMatcher= pattern.matcher(""); //$NON-NLS-1$
}
return fFileNameMatcher;
}
/**
* Tests if a file name matches to the file name patterns contained in the scope
* @param fileName The file name to test
* @return returns true if the file name is matching to a file name pattern
*/
private boolean matchesFileName(String fileName) {
return getFileNameMatcher().reset(fileName).matches();
}
/**
* Returns a description for the file name patterns in the scope
* @return the description of the scope
*/
public String getFileNamePatternDescription() {
String[] ext= fFileNamePatterns.toArray(new String[fFileNamePatterns.size()]);
Arrays.sort(ext);
StringBuffer buf= new StringBuffer();
for (int i= 0; i < ext.length; i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
buf.append(ext[i]);
}
return buf.toString();
}
private static IResource[] removeRedundantEntries(IResource[] elements, boolean includeDerived) {
ArrayList<IResource> res= new ArrayList<>();
for (int i= 0; i < elements.length; i++) {
IResource curr= elements[i];
addToList(res, curr, includeDerived);
}
return res.toArray(new IResource[res.size()]);
}
private static void addToList(ArrayList<IResource> res, IResource curr, boolean includeDerived) {
if (!includeDerived && curr.isDerived(IResource.CHECK_ANCESTORS)) {
return;
}
IPath currPath= curr.getFullPath();
for (int k= res.size() - 1; k >= 0 ; k--) {
IResource other= res.get(k);
IPath otherPath= other.getFullPath();
if (otherPath.isPrefixOf(currPath)) {
return;
}
if (currPath.isPrefixOf(otherPath)) {
res.remove(k);
}
}
res.add(curr);
}
}