/******************************************************************************* * Copyright (c) 2000, 2007 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 com.aptana.ide.search.epl.internal.filesystem.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.runtime.Path; import org.eclipse.search.internal.core.text.PatternConstructor; import com.aptana.ide.search.epl.filesystem.text.FileSystemTextSearchScope; /** * @author Pavel Petrochenko */ public final class FileNamePatternSearchScope extends FileSystemTextSearchScope { /** * 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, File[] resources, boolean includeDerived) { return new FileNamePatternSearchScope(description, FileNamePatternSearchScope.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 File[] fRootElements; private final Set fFileNamePatterns; private Matcher fFileNameMatcher; private boolean fVisitDerived; private FileNamePatternSearchScope(String description, File[] resources, boolean visitDerived) { Assert.isNotNull(description); this.fDescription = description; this.fRootElements = resources; this.fFileNamePatterns = new HashSet(3); this.fFileNameMatcher = null; this.fVisitDerived = visitDerived; } /** * Returns the description of the scope * * @return the description of the scope */ public String getDescription() { return this.fDescription; } /** * @see com.aptana.ide.search.epl.filesystem.text.FileSystemTextSearchScope#getRoots() */ public File[] getRoots() { return this.fRootElements; } /** * @see com.aptana.ide.search.epl.filesystem.text.FileSystemTextSearchScope#contains(java.io.File) */ public boolean contains(File proxy) { if (proxy.isFile()) { return this.matchesFileName(proxy.getName()); } return true; } /** * Adds an file name pattern to the scope. * * @param pattern */ public void addFileNamePattern(String pattern) { if (this.fFileNamePatterns.add(pattern)) { this.fFileNameMatcher = null; // clear cache } } /** * @param pattern */ public void setFileNamePattern(Pattern pattern) { this.fFileNameMatcher = pattern.matcher(""); //$NON-NLS-1$ } /** * @return */ public Pattern getFileNamePattern() { return this.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 this.fVisitDerived; } private Matcher getFileNameMatcher() { if (this.fFileNameMatcher == null) { Pattern pattern; if (this.fFileNamePatterns.isEmpty()) { pattern = Pattern.compile(".*"); //$NON-NLS-1$ } else { String[] patternStrings = (String[]) this.fFileNamePatterns.toArray(new String[this.fFileNamePatterns .size()]); pattern = PatternConstructor.createPattern(patternStrings, FileNamePatternSearchScope.IS_CASE_SENSITIVE_FILESYSTEM); } this.fFileNameMatcher = pattern.matcher(""); //$NON-NLS-1$ } return this.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 this.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 = (String[]) this.fFileNamePatterns.toArray(new String[this.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 File[] removeRedundantEntries(File[] elements, boolean includeDerived) { ArrayList res = new ArrayList(); for (int i = 0; i < elements.length; i++) { File curr = elements[i]; FileNamePatternSearchScope.addToList(res, curr, includeDerived); } return (File[]) res.toArray(new File[res.size()]); } private static void addToList(ArrayList res, File curr, boolean includeDerived) { if (!includeDerived && FileNamePatternSearchScope.isDerived(curr)) { return; } IPath currPath = new Path(curr.getAbsolutePath()); for (int k = res.size() - 1; k >= 0; k--) { File other = (File) res.get(k); IPath otherPath = new Path(other.getAbsolutePath()); if (otherPath.isPrefixOf(currPath)) { return; } if (currPath.isPrefixOf(otherPath)) { res.remove(k); } } res.add(curr); } private static boolean isDerived(File curr) { return false; } /** * @param files * @param fileNamePatterns * @return */ public static FileSystemTextSearchScope newSearchScope(File[] files, String[] fileNamePatterns) { FileNamePatternSearchScope fileNamePatternSearchScope = new FileNamePatternSearchScope("", files, true); //$NON-NLS-1$ for (int a = 0; a < fileNamePatterns.length; a++) { fileNamePatternSearchScope.addFileNamePattern(fileNamePatterns[a]); } return fileNamePatternSearchScope; } }