--- a/cnd.gotodeclaration/nbproject/project.xml +++ a/cnd.gotodeclaration/nbproject/project.xml @@ -55,7 +55,7 @@ 1 - 1.2 + 1.17 --- a/cnd.gotodeclaration/src/org/netbeans/modules/cnd/gotodeclaration/matcher/NameMatcherFactory.java +++ a/cnd.gotodeclaration/src/org/netbeans/modules/cnd/gotodeclaration/matcher/NameMatcherFactory.java @@ -27,9 +27,8 @@ */ package org.netbeans.modules.cnd.gotodeclaration.matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; import org.netbeans.modules.cnd.api.model.services.CsmSelect; +import org.netbeans.spi.jumpto.support.NameMatcher; import org.netbeans.spi.jumpto.type.SearchType; /** @@ -39,141 +38,9 @@ * @author Vladimir Kvashin */ public class NameMatcherFactory { - - private NameMatcherFactory() { - } - - private static abstract class BaseNameMatcher implements NameMatcher { - - protected String patternText; - - protected BaseNameMatcher(String patternText) { - this.patternText = patternText; - } - } - - - private static final class ExactNameMatcher extends BaseNameMatcher implements NameMatcher { - - public ExactNameMatcher(String patternText) { - super(patternText); - } - - @Override - public final boolean accept(String name) { - return patternText.equals(name); - } - } - - private static final class CaseInsensitiveExactNameMatcher extends BaseNameMatcher implements NameMatcher { - - public CaseInsensitiveExactNameMatcher(String patternText) { - super(patternText); - } - - @Override - public final boolean accept(String name) { - return patternText.equalsIgnoreCase(name); - } - } - - private static final class PrefixNameMatcher extends BaseNameMatcher implements NameMatcher { - - public PrefixNameMatcher(String patternText) { - super(patternText); - } - - @Override - public final boolean accept(String name) { - return name != null && name.startsWith(patternText); - } - } - - private static final class CaseInsensitivePrefixNameMatcher extends BaseNameMatcher implements NameMatcher { - - public CaseInsensitivePrefixNameMatcher(String patternText) { - super(patternText.toLowerCase()); - } - - @Override - public final boolean accept(String name) { - return name != null && name.toLowerCase().startsWith(patternText); - } - } - - private static final class RegExpNameMatcher implements NameMatcher { - - Pattern pattern; - - public RegExpNameMatcher(String patternText, boolean caseSensitive) { - pattern = Pattern.compile(patternText, caseSensitive ? 0 : Pattern.CASE_INSENSITIVE); - } - - @Override - public final boolean accept(String name) { - return name != null && pattern.matcher(name).matches(); - } - } - - private static final class CamelCaseNameMatcher implements NameMatcher { - - Pattern pattern; - - public CamelCaseNameMatcher(String name) { - if (name.length() == 0) { - throw new IllegalArgumentException (); - } - final StringBuilder patternString = new StringBuilder (); - for (int i=0; i + + + Added support SPI to implement name filters + + + + + + + Added support SPI to implement common filters used by Go To Type, Go To Symbol, + Go To File. + + + + + Added SPI for Go to File dialog --- a/jumpto/manifest.mf +++ a/jumpto/manifest.mf @@ -2,5 +2,5 @@ OpenIDE-Module: org.netbeans.modules.jumpto/1 OpenIDE-Module-Layer: org/netbeans/modules/jumpto/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jumpto/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.16 +OpenIDE-Module-Specification-Version: 1.17 AutoUpdate-Show-In-Client: false --- a/jumpto/nbproject/project.xml +++ a/jumpto/nbproject/project.xml @@ -225,6 +225,7 @@ org.netbeans.spi.jumpto.file org.netbeans.spi.jumpto.symbol org.netbeans.spi.jumpto.type + org.netbeans.spi.jumpto.support --- a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java +++ a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java @@ -68,8 +68,6 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.AbstractAction; import javax.swing.DefaultListCellRenderer; @@ -100,6 +98,8 @@ import org.netbeans.spi.jumpto.file.FileDescriptor; import org.netbeans.spi.jumpto.file.FileProvider; import org.netbeans.spi.jumpto.file.FileProviderFactory; +import org.netbeans.spi.jumpto.support.NameMatcher; +import org.netbeans.spi.jumpto.support.NameMatcherFactory; import org.netbeans.spi.jumpto.type.SearchType; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; @@ -467,7 +467,8 @@ } } //Ask GTF providers - final FileProvider.Context ctx = FileProviderAccessor.getInstance().createContext(text, toJumpToSearchType(searchType), currentProject); + final SearchType jumpToSearchType = toJumpToSearchType(searchType); + final FileProvider.Context ctx = FileProviderAccessor.getInstance().createContext(text, jumpToSearchType, currentProject); final FileProvider.Result fpR = FileProviderAccessor.getInstance().createResult(files,new String[1], ctx); for (FileProvider provider : getProviders()) { currentProvider = provider; @@ -497,6 +498,7 @@ allFolders = searchSources(root, allFolders, excludes, filters); } //Looking for matching files in all found folders + final NameMatcher matcher = NameMatcherFactory.createNameMatcher(text, jumpToSearchType); for (FileObject folder: allFolders) { assert folder.isFolder(); Enumeration filesInFolder = folder.getData(false); @@ -504,7 +506,7 @@ FileObject file = filesInFolder.nextElement(); if (file.isFolder()) continue; - if (isMatchedFileObject(searchType, file, text)) { + if (matcher.accept(file.getNameExt())) { Project project = FileOwnerQuery.getOwner(file); boolean preferred = project != null && currentProject != null ? project.getProjectDirectory() == currentProject.getProjectDirectory() : false; String relativePath = FileUtil.getRelativePath(project.getProjectDirectory(), file); @@ -564,134 +566,6 @@ // } } return result; - } - - private boolean isMatchedFileObject(QuerySupport.Kind searchType, FileObject file, String text) { - boolean isMatched = false; - switch (searchType) { - case EXACT: { - isMatched = file.getNameExt().equals(text); - break; - } - case PREFIX: { - if (text.length() == 0) { - isMatched = true; - } else { - isMatched = file.getNameExt().startsWith(text); - } - break; - } - case CASE_INSENSITIVE_PREFIX: { - if (text.length() == 0) { - isMatched = true; - } else { - isMatched = file.getNameExt().toLowerCase().startsWith(text.toLowerCase()); - } - break; - } - case CAMEL_CASE: { - if (text.length() == 0) { - throw new IllegalArgumentException (); - } - { - StringBuilder sb = new StringBuilder(); - String prefix = null; - int lastIndex = 0; - int index; - do { - index = findNextUpper(text, lastIndex + 1); - String token = text.substring(lastIndex, index == -1 ? text.length(): index); - if ( lastIndex == 0 ) { - prefix = token; - } - sb.append(token); - sb.append( index != -1 ? "[\\p{javaLowerCase}\\p{Digit}_\\$]*" : ".*"); // NOI18N - lastIndex = index; - } - while(index != -1); - - final Pattern pattern = Pattern.compile(sb.toString()); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - break; - - } - - case CASE_INSENSITIVE_REGEXP: - if (text.length() == 0) { - throw new IllegalArgumentException (); - } else { - if (Character.isJavaIdentifierStart(text.charAt(0))) { - Pattern pattern = Pattern.compile(text,Pattern.CASE_INSENSITIVE); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - else { - Pattern pattern = Pattern.compile(text,Pattern.CASE_INSENSITIVE|Pattern.DOTALL); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - break; - } - case REGEXP: - if (text.length() == 0) { - throw new IllegalArgumentException (); - } else { - if (Character.isJavaIdentifierStart(text.charAt(0))) { - final Pattern pattern = Pattern.compile(text); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - else { - final Pattern pattern = Pattern.compile(text,Pattern.DOTALL); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - break; - } - - case CASE_INSENSITIVE_CAMEL_CASE: { - if (text.length() == 0) { - throw new IllegalArgumentException (); - } - { - StringBuilder sb = new StringBuilder(); - String prefix = null; - int lastIndex = 0; - int index; - do { - index = findNextUpper(text, lastIndex + 1); - String token = text.substring(lastIndex, index == -1 ? text.length(): index); - if ( lastIndex == 0 ) { - prefix = token; - } - sb.append(token); - sb.append( index != -1 ? "[\\p{javaLowerCase}\\p{Digit}_\\$]*" : ".*"); // NOI18N - lastIndex = index; - } - while(index != -1); - - final Pattern pattern = Pattern.compile(sb.toString(),Pattern.CASE_INSENSITIVE); - Matcher m = pattern.matcher(file.getNameExt()); - isMatched = m.matches(); - } - break; - } - default: - throw new UnsupportedOperationException (searchType.toString()); - - } - return isMatched; - }//checkMatch - private static int findNextUpper(String text, int offset ) { - - for( int i = offset; i < text.length(); i++ ) { - if ( Character.isUpperCase(text.charAt(i)) ) { - return i; - } - } - return -1; } private boolean checkAgainstFilters(FileObject folder, FileObjectFilter[] filters) { --- a/jumpto/src/org/netbeans/spi/jumpto/support/NameMatcher.java +++ a/jumpto/src/org/netbeans/spi/jumpto/support/NameMatcher.java @@ -0,0 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * Portions Copyrighted 2007 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.jumpto.support; + +/** + * Used for encapsulation of the different matching algorithms + * (such as String.equals, String.equalsIgnoreCase, String.startWith, etc) + */ +public interface NameMatcher { + + /** + * Determine whether the name matches a pattern or not + * return true + */ + boolean accept(String name); +} --- a/jumpto/src/org/netbeans/spi/jumpto/support/NameMatcherFactory.java +++ a/jumpto/src/org/netbeans/spi/jumpto/support/NameMatcherFactory.java @@ -0,0 +1,180 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * Portions Copyrighted 2007 Sun Microsystems, Inc. + */ +package org.netbeans.spi.jumpto.support; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import org.netbeans.spi.jumpto.type.SearchType; +import org.openide.util.Parameters; + +/** + * A factory that provides comparators + * depending on SearchType + * + * @author Vladimir Kvashin + */ +public final class NameMatcherFactory { + + private NameMatcherFactory() { + } + + private static abstract class BaseNameMatcher implements NameMatcher { + + protected final String patternText; + + protected BaseNameMatcher(String patternText) { + this.patternText = patternText; + } + } + + private static final class ExactNameMatcher extends BaseNameMatcher { + + public ExactNameMatcher(String patternText) { + super(patternText); + } + + @Override + public final boolean accept(String name) { + return patternText.equals(name); + } + } + + private static final class CaseInsensitiveExactNameMatcher extends BaseNameMatcher { + + public CaseInsensitiveExactNameMatcher(String patternText) { + super(patternText); + } + + @Override + public final boolean accept(String name) { + return patternText.equalsIgnoreCase(name); + } + } + + private static final class PrefixNameMatcher extends BaseNameMatcher { + + public PrefixNameMatcher(String patternText) { + super(patternText); + } + + @Override + public final boolean accept(String name) { + return name != null && name.startsWith(patternText); + } + } + + private static final class CaseInsensitivePrefixNameMatcher extends BaseNameMatcher { + + public CaseInsensitivePrefixNameMatcher(String patternText) { + super(patternText.toLowerCase()); + } + + @Override + public final boolean accept(String name) { + return name != null && name.toLowerCase().startsWith(patternText); + } + } + + private static final class RegExpNameMatcher implements NameMatcher { + + private final Pattern pattern; + + public RegExpNameMatcher(String patternText, boolean caseSensitive) { + pattern = Pattern.compile(patternText, caseSensitive ? 0 : Pattern.CASE_INSENSITIVE); + } + + @Override + public final boolean accept(String name) { + return name != null && pattern.matcher(name).matches(); + } + } + + private static final class CamelCaseNameMatcher implements NameMatcher { + + private final Pattern pattern; + + public CamelCaseNameMatcher(String name) { + if (name.length() == 0) { + throw new IllegalArgumentException (); + } + final StringBuilder patternString = new StringBuilder (); + for (int i=0; i beans = new ArrayList(cache.size()); for (AbstractBeanTypeDescriptor beanTypeDescriptor : cache) { - if (cacheRefresh || matcher.match(beanTypeDescriptor.getSimpleName())) { + if (cacheRefresh || matcher.accept(beanTypeDescriptor.getSimpleName())) { beans.add(beanTypeDescriptor); } } @@ -212,84 +214,4 @@ lastRefreshText = null; lastRefreshSearchType = null; } - - private interface Matcher { - - boolean match(String str); - } - - private static Pattern camelCaseBlock = Pattern.compile("(\\p{javaUpperCase}(?:\\p{javaLowerCase}|\\d|\\.|\\-)*)"); // NOI18N - - private Matcher getMatcher(String searchText, SearchType searchType) { - switch (searchType) { - case EXACT_NAME: - return new StringMatcher(searchText, false, true); - case CASE_INSENSITIVE_EXACT_NAME: - return new StringMatcher(searchText, false, false); - case PREFIX: - return new StringMatcher(searchText, true, true); - case CASE_INSENSITIVE_PREFIX: - return new StringMatcher(searchText, true, false); - case REGEXP: - String regex = searchText + "*"; // NOI18N - - regex = regex.replace("*", ".*").replace('?', '.'); // NOI18N - - return new RegExpMatcher(regex, true); - case CASE_INSENSITIVE_REGEXP: - regex = searchText + "*"; // NOI18N - - regex = regex.replace("*", ".*").replace('?', '.'); // NOI18N - - return new RegExpMatcher(regex, false); - case CAMEL_CASE: - java.util.regex.Matcher m = camelCaseBlock.matcher(searchText); - StringBuilder sb = new StringBuilder(); - while (m.find()) { - sb.append(m.group()).append("(?:\\p{javaLowerCase}|\\d|\\.|\\-)*"); // NOI18N - - } - sb.append(".*"); // NOI18N - return new RegExpMatcher(sb.toString(), false); - } - - assert false; // probably a new type got added to SearchType, would need fixing on our part - - return null; - } - - private static final class RegExpMatcher implements Matcher { - - private final String regex; - private final boolean caseSensitive; - private final Pattern pattern; - - public RegExpMatcher(String regex, boolean caseSensitive) { - this.regex = regex; - this.caseSensitive = caseSensitive; - this.pattern = caseSensitive ? Pattern.compile(regex) : Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - } - - public boolean match(String str) { - return pattern.matcher(str).matches(); - } - } - - private static final class StringMatcher implements Matcher { - - private final String searchText; - private final boolean prefix; - private final boolean caseSensitive; - - public StringMatcher(String searchText, boolean prefix, boolean caseSensitive) { - this.searchText = searchText; - this.prefix = prefix; - this.caseSensitive = caseSensitive; - } - - public boolean match(String str) { - int length = prefix ? searchText.length() : Math.max(str.length(), searchText.length()); - return str.regionMatches(caseSensitive, 0, searchText, 0, length); - } - } }