diff --git a/jumpto/apichanges.xml b/jumpto/apichanges.xml --- a/jumpto/apichanges.xml +++ b/jumpto/apichanges.xml @@ -105,8 +105,23 @@ - - + + + Added SPI for Go to File dialog + + + + + + + Added SPI to allow friend modules to participate on searching files + in the Go To File dialog. The supplied FileProvider can handle file + search in recognized source groups. + + + + + Added SPI for Go to Symbol dialog @@ -119,7 +134,7 @@ Added SPI to provide content of the for Go to Symbol dialog. - + diff --git a/jumpto/manifest.mf b/jumpto/manifest.mf --- a/jumpto/manifest.mf +++ b/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.14 +OpenIDE-Module-Specification-Version: 1.15 AutoUpdate-Show-In-Client: false diff --git a/jumpto/nbproject/project.xml b/jumpto/nbproject/project.xml --- a/jumpto/nbproject/project.xml +++ b/jumpto/nbproject/project.xml @@ -215,12 +215,13 @@ org.netbeans.modules.cnd.gotodeclaration + org.netbeans.modules.csl.api org.netbeans.modules.gsf org.netbeans.modules.java.sourceui org.netbeans.modules.javafx.editor org.netbeans.modules.spring.beans - org.netbeans.modules.csl.api org.netbeans.api.jumpto.type + org.netbeans.spi.jumpto.file org.netbeans.spi.jumpto.symbol org.netbeans.spi.jumpto.type diff --git a/jumpto/src/org/netbeans/modules/jumpto/file/FileDescription.java b/jumpto/src/org/netbeans/modules/jumpto/file/FileDescription.java --- a/jumpto/src/org/netbeans/modules/jumpto/file/FileDescription.java +++ b/jumpto/src/org/netbeans/modules/jumpto/file/FileDescription.java @@ -44,146 +44,90 @@ package org.netbeans.modules.jumpto.file; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; import java.awt.Image; import java.beans.BeanInfo; -import java.util.Comparator; -import javax.swing.DefaultListCellRenderer; import javax.swing.Icon; import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JViewport; -import javax.swing.SwingConstants; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectInformation; import org.netbeans.api.project.ProjectUtils; import org.openide.cookies.EditCookie; import org.openide.cookies.OpenCookie; import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; import org.openide.util.ImageUtilities; -import org.openide.util.NbBundle; /** Contains interesting information about file found in the search. * * @author Petr Hrebejk + * @author Tomas Zezula + * todo: SPI interface if needed. Now FileObject added to result seems to be enough + * and everyone will use the default impl anyway. */ public class FileDescription { - -// static long time; - - public static final String SEARCH_IN_PROGRES = NbBundle.getMessage(FileDescription.class, "TXT_SearchingOtherProjects"); // NOI18N /** * The icon used if unknown project, i.e. {@code project == null}. * In such case, we use {@code find.png} - "a file belongs to the find". */ public static Icon UNKNOWN_PROJECT_ICON = ImageUtilities.loadImageIcon( "org/netbeans/modules/jumpto/resources/find.gif", false); // NOI18N - private final FileObject fileObject; - private final String relativePath; + private final String ownerPath; private final Project project; // Project the file belongs to - + private Icon icon; private String projectName; private Icon projectIcon; private boolean prefered; - - private static final String EMPTY_STRING = ""; // NOI18N - - public FileDescription(FileObject file, String relativePath, + + public FileDescription(FileObject file, String ownerPath, Project project, boolean prefered) { this.fileObject = file; - this.relativePath = relativePath; + this.ownerPath = ownerPath; this.project = project; this.prefered = prefered; } - - public String getName() { + + public String getFileName() { return fileObject.getNameExt(); // NOI18N } - + public synchronized Icon getIcon() { - if ( icon == null ) { DataObject od = getDataObject(); Image i = od.getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16); icon = new ImageIcon( i ); } - return icon; } - - public String getRelativePath() { - return relativePath; + + public String getOwnerPath() { + return ownerPath; } - + public synchronized String getProjectName() { if ( projectName == null ) { initProjectInfo(); - } + } return projectName; } - + public synchronized Icon getProjectIcon() { if ( projectIcon == null ) { initProjectInfo(); - } + } return projectIcon; } - -// public synchronized boolean isVisible() { -// -// long t = System.currentTimeMillis(); -// -// if ( fileObject == null ) { -// fileObject = FileUtil.toFileObject(file); -// } -// boolean visible = fileObject == null ? false : VisibilityQuery.getDefault().isVisible(fileObject); -// if ( !visible ) { -// addTime( t ); -// return false; -// } -// -// // XXX PERF needs to cache parents. -// while( fileObject.getParent() != null ) { -// fileObject = fileObject.getParent(); -// if ( fileObject.equals(sourceGroup.getRootFolder() ) ) { -// addTime( t ); -// return true; -// } -// if ( !VisibilityQuery.getDefault().isVisible(fileObject) ) { -// addTime( t ); -// return false; -// } -// } -// addTime( t ); -// return true; -// } -// -// private void addTime( long t ) { -//// time += System.currentTimeMillis() - t; -//// System.out.println("isVisible time " + time); -// } - + + public boolean isFromCurrentProject() { + return prefered; + } + public void open() { - DataObject od = getDataObject(); - if ( od != null ) { - EditCookie ec = (EditCookie) od.getCookie(EditCookie.class); - if (ec != null) { ec.edit(); } @@ -196,11 +140,11 @@ } } - - public FileObject getFileObject() { + + public FileObject getFileObject() { return fileObject; } - + private DataObject getDataObject() { try { org.openide.filesystems.FileObject fo = getFileObject(); @@ -210,7 +154,7 @@ return null; } } - + private void initProjectInfo() { // Issue #167198: A file may not belong to any project. // Hence, FileOwnerQuery.getOwner(file) can return null as a project, @@ -222,248 +166,8 @@ projectIcon = pi.getIcon(); } else { - projectName = EMPTY_STRING; + projectName = ""; //NOI18N projectIcon = UNKNOWN_PROJECT_ICON; } } - - // Innerclasses ------------------------------------------------------------ - - public static class FDComarator implements Comparator { - - private boolean usePrefered; - private boolean caseSensitive; - - public FDComarator(boolean usePrefered, boolean caseSensitive ) { - this.usePrefered = usePrefered; - this.caseSensitive = caseSensitive; - } - - public int compare(FileDescription o1, FileDescription o2) { - - // If prefered prefer prefered - if ( usePrefered ) { - if ( o1.prefered && !o2.prefered ) { - return -1; - } - if ( !o1.prefered && o2.prefered ) { - return 1; - } - } - - // File name - int cmpr = compareStrings( o1.getName(), o2.getName(), caseSensitive ); - if ( cmpr != 0 ) { - return cmpr; - } - - // Project name - cmpr = compareStrings( o1.getProjectName(), o2.getProjectName(), caseSensitive ); - if ( cmpr != 0 ) { - return cmpr; - } - - // Relative location - cmpr = compareStrings( o1.getRelativePath(), o2.getRelativePath(), caseSensitive ); - - return cmpr; - - } - - private int compareStrings(String s1, String s2, boolean caseSensitive) { - if( s1 == null ) { - s1 = EMPTY_STRING; - } - if ( s2 == null ) { - s2 = EMPTY_STRING; - } - - - return caseSensitive ? s1.compareTo( s2 ) : s1.compareToIgnoreCase( s2 ); - } - } - - private static class RendererComponent extends JPanel { - private FileDescription fd; - - void setDescription(FileDescription fd) { - this.fd = fd; - putClientProperty(TOOL_TIP_TEXT_KEY, null); - } - - @Override - public String getToolTipText() { - String text = (String) getClientProperty(TOOL_TIP_TEXT_KEY); - if( text == null ) { - if( fd != null) { - text = FileUtil.getFileDisplayName(fd.getFileObject()); - } - putClientProperty(TOOL_TIP_TEXT_KEY, text); - } - return text; - } - } - - public static class Renderer extends DefaultListCellRenderer implements ChangeListener { - - public static Icon WAIT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/wait.gif", false); // NOI18N - - - private RendererComponent rendererComponent; - private JLabel jlName = new JLabel(); - private JLabel jlPath = new JLabel(); - private JLabel jlPrj = new JLabel(); - private int DARKER_COLOR_COMPONENT = 5; - private int LIGHTER_COLOR_COMPONENT = 80; - private Color fgColor; - private Color fgColorLighter; - private Color bgColor; - private Color bgColorDarker; - private Color bgSelectionColor; - private Color fgSelectionColor; - private Color bgColorGreener; - private Color bgColorDarkerGreener; - - private JList jList; - - private boolean colorPrefered; - - public Renderer( JList list ) { - - jList = list; - - Container container = list.getParent(); - if ( container instanceof JViewport ) { - ((JViewport)container).addChangeListener(this); - stateChanged(new ChangeEvent(container)); - } - - rendererComponent = new RendererComponent(); - rendererComponent.setLayout(new BorderLayout()); - rendererComponent.add( jlName, BorderLayout.WEST ); - rendererComponent.add( jlPath, BorderLayout.CENTER); - rendererComponent.add( jlPrj, BorderLayout.EAST ); - - - jlName.setOpaque(false); - jlPath.setOpaque(false); - jlPrj.setOpaque(false); - - jlName.setFont(list.getFont()); - jlPath.setFont(list.getFont()); - jlPrj.setFont(list.getFont()); - - - jlPrj.setHorizontalAlignment(RIGHT); - jlPrj.setHorizontalTextPosition(LEFT); - - // setFont( list.getFont() ); - fgColor = list.getForeground(); - fgColorLighter = new Color( - Math.min( 255, fgColor.getRed() + LIGHTER_COLOR_COMPONENT), - Math.min( 255, fgColor.getGreen() + LIGHTER_COLOR_COMPONENT), - Math.min( 255, fgColor.getBlue() + LIGHTER_COLOR_COMPONENT) - ); - - bgColor = list.getBackground(); - bgColorDarker = new Color( - Math.abs(bgColor.getRed() - DARKER_COLOR_COMPONENT), - Math.abs(bgColor.getGreen() - DARKER_COLOR_COMPONENT), - Math.abs(bgColor.getBlue() - DARKER_COLOR_COMPONENT) - ); - bgSelectionColor = list.getSelectionBackground(); - fgSelectionColor = list.getSelectionForeground(); - - - bgColorGreener = new Color( - Math.abs(bgColor.getRed() - 20), - Math.min(255, bgColor.getGreen() + 10 ), - Math.abs(bgColor.getBlue() - 20) ); - - - bgColorDarkerGreener = new Color( - Math.abs(bgColorDarker.getRed() - 35), - Math.min(255, bgColorDarker.getGreen() + 5 ), - Math.abs(bgColorDarker.getBlue() - 35) ); - } - - public @Override Component getListCellRendererComponent( JList list, - Object value, - int index, - boolean isSelected, - boolean hasFocus) { - - // System.out.println("Renderer for index " + index ); - - int height = list.getFixedCellHeight(); - int width = list.getFixedCellWidth() - 1; - - width = width < 200 ? 200 : width; - - // System.out.println("w, h " + width + ", " + height ); - - Dimension size = new Dimension( width, height ); - rendererComponent.setMaximumSize(size); - rendererComponent.setPreferredSize(size); - - if ( isSelected ) { - jlName.setForeground(fgSelectionColor); - jlPath.setForeground(fgSelectionColor); - jlPrj.setForeground(fgSelectionColor); - rendererComponent.setBackground(bgSelectionColor); - } - else { - jlName.setForeground(fgColor); - jlPath.setForeground(fgColorLighter); - jlPrj.setForeground(fgColor); - rendererComponent.setBackground( index % 2 == 0 ? bgColor : bgColorDarker ); - } - - if ( value instanceof FileDescription ) { - FileDescription fd = (FileDescription)value; - jlName.setIcon(fd.getIcon()); - jlName.setText(fd.getName()); - jlPath.setIcon(null); - jlPath.setHorizontalAlignment(SwingConstants.LEFT); - jlPath.setText(fd.getRelativePath().length() > 0 ? " (" + fd.getRelativePath() + ")" : " ()"); //NOI18N - jlPrj.setText(fd.getProjectName()); - jlPrj.setIcon(fd.getProjectIcon()); - if ( !isSelected ) { - rendererComponent.setBackground( index % 2 == 0 ? - ( fd.prefered && colorPrefered ? bgColorGreener : bgColor ) : - ( fd.prefered && colorPrefered ? bgColorDarkerGreener : bgColorDarker ) ); - } - rendererComponent.setDescription(fd); - } - else { - jlName.setText( "" ); // NOI18M - jlName.setIcon(null); - jlPath.setIcon(Renderer.WAIT_ICON); - jlPath.setHorizontalAlignment(SwingConstants.CENTER); - jlPath.setText( value.toString() ); - jlPrj.setIcon(null); - jlPrj.setText( "" ); // NOI18N - } - - return rendererComponent; - } - - public void stateChanged(ChangeEvent event) { - - JViewport jv = (JViewport)event.getSource(); - - jlName.setText( "Sample" ); // NOI18N - jlName.setIcon( new ImageIcon() ); - - jList.setFixedCellHeight(jlName.getPreferredSize().height); - jList.setFixedCellWidth(jv.getExtentSize().width); - } - - public void setColorPrefered( boolean colorPrefered ) { - this.colorPrefered = colorPrefered; - } - - } - - } diff --git a/jumpto/src/org/netbeans/modules/jumpto/file/FileProviderAccessor.java b/jumpto/src/org/netbeans/modules/jumpto/file/FileProviderAccessor.java new file mode 100644 --- /dev/null +++ b/jumpto/src/org/netbeans/modules/jumpto/file/FileProviderAccessor.java @@ -0,0 +1,82 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 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]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jumpto.file; + +import java.util.List; +import org.netbeans.api.project.Project; +import org.netbeans.spi.jumpto.file.FileProvider; +import org.netbeans.spi.jumpto.type.SearchType; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; + +/** + * + * @author Tomas Zezula + */ +public abstract class FileProviderAccessor { + + private static volatile FileProviderAccessor instance; + + public static synchronized FileProviderAccessor getInstance() { + if (instance == null) { + try { + Class.forName(FileProvider.Context.class.getName(), true, FileProviderAccessor.class.getClassLoader()); + assert instance != null; + } catch (ClassNotFoundException cnf) { + Exceptions.printStackTrace(cnf); + } + } + assert instance != null; + return instance; + } + + public static void setInstance(final FileProviderAccessor theInstance) { + assert theInstance != null; + instance = theInstance; + } + + public abstract FileProvider.Context createContext(String text, SearchType searchType, Project currentProject); + + public abstract void setRoot(FileProvider.Context ctx, FileObject root); + + public abstract FileProvider.Result createResult(List result, String[] message, FileProvider.Context ctx); + + public abstract int getRetry(FileProvider.Result result); +} diff --git a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java b/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java --- a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java +++ b/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchAction.java @@ -45,6 +45,10 @@ package org.netbeans.modules.jumpto.file; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Rectangle; @@ -56,7 +60,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Enumeration; +import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -64,12 +70,21 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.AbstractAction; +import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; +import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JViewport; import javax.swing.ListCellRenderer; import javax.swing.ListModel; +import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; @@ -80,6 +95,9 @@ import org.netbeans.modules.jumpto.type.Models; import org.netbeans.modules.parsing.spi.indexing.support.IndexResult; import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport; +import org.netbeans.spi.jumpto.file.FileProvider; +import org.netbeans.spi.jumpto.file.FileProviderFactory; +import org.netbeans.spi.jumpto.type.SearchType; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.awt.Mnemonics; @@ -87,6 +105,7 @@ import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.util.HelpCtx; +import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; @@ -109,6 +128,7 @@ private JButton openBtn; private FileSearchPanel panel; private Dimension initialDimension; + private Iterable providers; public FileSearchAction() { super( NbBundle.getMessage(FileSearchAction.class, "CTL_FileSearchAction") ); @@ -135,7 +155,7 @@ public ListCellRenderer getListCellRenderer( JList list ) { - return new FileDescription.Renderer( list ); + return new Renderer( list ); } @@ -205,31 +225,10 @@ private FileDescription[] getSelectedFiles() { FileDescription[] result = null; -// try { - panel = new FileSearchPanel(this, findCurrentProject()); - dialog = createDialog(panel); - -// Node[] arr = TopComponent.getRegistry ().getActivatedNodes(); -// String initSearchText = null; -// if (arr.length > 0) { -// EditorCookie ec = arr[0].getCookie (EditorCookie.class); -// if (ec != null) { -// JEditorPane[] openedPanes = ec.getOpenedPanes (); -// if (openedPanes != null) { -// initSearchText = org.netbeans.editor.Utilities.getSelectionOrIdentifier(openedPanes [0]); -// if (initSearchText != null && org.openide.util.Utilities.isJavaIdentifier(initSearchText)) { -// panel.setInitialText(initSearchText); -// } -// } -// } -// } - - dialog.setVisible(true); - result = panel.getSelectedFiles(); - -// } catch (IOException ex) { -// ErrorManager.getDefault().notify(ex); -// } + panel = new FileSearchPanel(this, findCurrentProject()); + dialog = createDialog(panel); + dialog.setVisible(true); + result = panel.getSelectedFiles(); return result; } @@ -306,11 +305,12 @@ // } private void cleanup() { - //System.out.println("CLEANUP"); - //Thread.dumpStack(); if ( dialog != null ) { // Closing event for some reson sent twice - + //Free SPI + synchronized (this) { + providers = null; + } // Save dialog size only when changed final int currentWidth = dialog.getWidth(); final int currentHeight = dialog.getHeight(); @@ -323,8 +323,25 @@ dialog.dispose(); this.dialog = null; //GoToTypeAction.this.cache = null; - FileSearchOptions.flush(); + } + } + + private Iterable getProviders() { + synchronized (this) { + if (providers != null) { + return providers; + } + } + final List result = new LinkedList(); + for (FileProviderFactory fpf : Lookup.getDefault().lookupAll(FileProviderFactory.class)) { + result.add(fpf.createFileProvider()); + } + synchronized (this) { + if (providers == null) { + providers = Collections.unmodifiableList(result); + } + return providers; } } @@ -339,6 +356,7 @@ private class Worker implements Runnable { private volatile boolean isCanceled = false; + private volatile FileProvider currentProvider; private final String text; private final QuerySupport.Kind searchType; @@ -391,8 +409,13 @@ if ( panel.time != -1 ) { LOGGER.fine( "Worker for text " + text + " canceled after " + ( System.currentTimeMillis() - createTime ) + " ms." ); } + FileProvider provider; synchronized (this) { isCanceled = true; + provider = currentProvider; + } + if (provider != null) { + provider.cancel(); } } @@ -402,12 +425,11 @@ case CASE_INSENSITIVE_PREFIX: case CASE_INSENSITIVE_REGEXP: searchField = FileIndexer.FIELD_CASE_INSENSITIVE_NAME; break; - default: searchField = FileIndexer.FIELD_NAME; break; } - Collection roots = QuerySupport.findRoots((Project) null, null, Collections.emptyList(), Collections.emptyList()); + final Collection roots = new ArrayList(QuerySupport.findRoots((Project) null, null, Collections.emptyList(), Collections.emptyList())); try { QuerySupport q = QuerySupport.forRoots(FileIndexer.ID, FileIndexer.VERSION, roots.toArray(new FileObject [roots.size()])); Collection results = q.query(searchField, text, searchType); @@ -430,18 +452,43 @@ files.add(fd); LOGGER.finer("Found: " + file.getPath() + ", project=" + project + ", currentProject=" + currentProject + ", preferred=" + preferred); } + if (isCanceled) { + return files; + } + + final Project[] projects = OpenProjects.getDefault().getOpenProjects(); + final List sgRoots = new LinkedList(); + for (Project p : projects) { + for (SourceGroup group: ProjectUtils.getSources(p).getSourceGroups(Sources.TYPE_GENERIC)) { + sgRoots.add(group.getRootFolder()); + } + } + //Ask GTF providers + final FileProvider.Context ctx = FileProviderAccessor.getInstance().createContext(text, toJumpToSearchType(searchType), currentProject); + final FileProvider.Result fpR = FileProviderAccessor.getInstance().createResult(files,new String[1], ctx); + for (FileProvider provider : getProviders()) { + currentProvider = provider; + try { + for (FileObject root : sgRoots) { + FileProviderAccessor.getInstance().setRoot(ctx, root); + boolean recognized = provider.computeFiles(ctx, fpR); + if (recognized) { + roots.add(root); + } + } + } finally { + currentProvider = null; + if (isCanceled) { + return files; + } + } + } + //PENDING Now we have to search folders which not included in Search API - Project[] projects = OpenProjects.getDefault().getOpenProjects(); - Enumeration projectFolders; Collection allFolders = new ArrayList(); final FileObjectFilter[] filters = new FileObjectFilter[]{SearchInfoFactory.VISIBILITY_FILTER, SearchInfoFactory.SHARABILITY_FILTER}; - for (Project p : projects) { - Sources s = ProjectUtils.getSources(p); - SourceGroup[] groups = s.getSourceGroups(Sources.TYPE_GENERIC); - for (SourceGroup group: groups) { - FileObject root = group.getRootFolder(); - allFolders = searchSources(root, allFolders, roots, filters); - } + for (FileObject root : sgRoots) { + allFolders = searchSources(root, allFolders, roots, filters); } //Looking for matching files in all found folders for (FileObject folder: allFolders) { @@ -467,7 +514,7 @@ } } } - Collections.sort(files, new FileDescription.FDComarator(panel.isPreferedProject(), panel.isCaseSensitive())); + Collections.sort(files, new FDComarator(panel.isPreferedProject(), panel.isCaseSensitive())); return files; } catch (PatternSyntaxException pse) { return Collections.emptyList(); @@ -475,45 +522,26 @@ LOGGER.log(Level.WARNING, null, ioe); return Collections.emptyList(); } + } - -// // TODO: Search twice, first for current project, then for all projects -// List items; -// // Multiple providers: merge results -// items = new ArrayList(128); -// String[] message = new String[1]; -// TypeProvider.Context context = TypeProviderAccessor.DEFAULT.createContext(null, text, nameKind); -// TypeProvider.Result result = TypeProviderAccessor.DEFAULT.createResult(items, message); -// if (typeProviders == null) { -// typeProviders = Lookup.getDefault().lookupAll(TypeProvider.class); -// } -// for (TypeProvider provider : typeProviders) { -// if (isCanceled) { -// return null; -// } -// current = provider; -// long start = System.currentTimeMillis(); -// try { -// LOGGER.fine("Calling TypeProvider: " + provider); -// provider.computeTypeNames(context, result); -// } finally { -// current = null; -// } -// long delta = System.currentTimeMillis() - start; -// LOGGER.fine("Provider '" + provider.getDisplayName() + "' took " + delta + " ms."); -// -// } -// if ( !isCanceled ) { -// //time = System.currentTimeMillis(); -// Collections.sort(items, new TypeComparator()); -// panel.setWarning(message[0]); -// //sort += System.currentTimeMillis() - time; -// //LOGGER.fine("PERF - " + " GSS: " + gss + " GSB " + gsb + " CP: " + cp + " SFB: " + sfb + " GTN: " + gtn + " ADD: " + add + " SORT: " + sort ); -// return items; -// } -// else { -// return null; -// } + private SearchType toJumpToSearchType(final QuerySupport.Kind searchType) { + switch (searchType) { + case CAMEL_CASE: + case CASE_INSENSITIVE_CAMEL_CASE: + return org.netbeans.spi.jumpto.type.SearchType.CAMEL_CASE; + case CASE_INSENSITIVE_PREFIX: + return org.netbeans.spi.jumpto.type.SearchType.CASE_INSENSITIVE_PREFIX; + case CASE_INSENSITIVE_REGEXP: + return org.netbeans.spi.jumpto.type.SearchType.CASE_INSENSITIVE_REGEXP; + case EXACT: + return org.netbeans.spi.jumpto.type.SearchType.EXACT_NAME; + case PREFIX: + return org.netbeans.spi.jumpto.type.SearchType.PREFIX; + case REGEXP: + return org.netbeans.spi.jumpto.type.SearchType.REGEXP; + default: + throw new IllegalArgumentException(); + } } } // End of Worker class @@ -681,7 +709,242 @@ panel.setSelectedFile(); } } - } - + + //Inner classes + public static class FDComarator implements Comparator { + + private boolean usePrefered; + private boolean caseSensitive; + + public FDComarator(boolean usePrefered, boolean caseSensitive ) { + this.usePrefered = usePrefered; + this.caseSensitive = caseSensitive; + } + + public int compare(FileDescription o1, FileDescription o2) { + + // If prefered prefer prefered + if ( usePrefered ) { + if ( o1.isFromCurrentProject() && !o2.isFromCurrentProject()) { + return -1; + } + if ( !o1.isFromCurrentProject() && o2.isFromCurrentProject()) { + return 1; + } + } + + // File name + int cmpr = compareStrings( o1.getFileName(), o2.getFileName(), caseSensitive ); + if ( cmpr != 0 ) { + return cmpr; + } + + // Project name + cmpr = compareStrings( o1.getProjectName(), o2.getProjectName(), caseSensitive ); + if ( cmpr != 0 ) { + return cmpr; + } + + // Relative location + cmpr = compareStrings( o1.getOwnerPath(), o2.getOwnerPath(), caseSensitive ); + + return cmpr; + + } + + private int compareStrings(String s1, String s2, boolean caseSensitive) { + if( s1 == null ) { + s1 = ""; //NOI18N + } + if ( s2 == null ) { + s2 = ""; //NOI18N + } + + + return caseSensitive ? s1.compareTo( s2 ) : s1.compareToIgnoreCase( s2 ); + } + } + + private static class RendererComponent extends JPanel { + private FileDescription fd; + + void setDescription(FileDescription fd) { + this.fd = fd; + putClientProperty(TOOL_TIP_TEXT_KEY, null); + } + + @Override + public String getToolTipText() { + String text = (String) getClientProperty(TOOL_TIP_TEXT_KEY); + if( text == null ) { + if( fd != null) { + text = FileUtil.getFileDisplayName(fd.getFileObject()); + } + putClientProperty(TOOL_TIP_TEXT_KEY, text); + } + return text; + } + } + + public static class Renderer extends DefaultListCellRenderer implements ChangeListener { + + public static Icon WAIT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/wait.gif", false); // NOI18N + + private RendererComponent rendererComponent; + private JLabel jlName = new JLabel(); + private JLabel jlPath = new JLabel(); + private JLabel jlPrj = new JLabel(); + private int DARKER_COLOR_COMPONENT = 5; + private int LIGHTER_COLOR_COMPONENT = 80; + private Color fgColor; + private Color fgColorLighter; + private Color bgColor; + private Color bgColorDarker; + private Color bgSelectionColor; + private Color fgSelectionColor; + private Color bgColorGreener; + private Color bgColorDarkerGreener; + + private JList jList; + + private boolean colorPrefered; + + public Renderer( JList list ) { + + jList = list; + + Container container = list.getParent(); + if ( container instanceof JViewport ) { + ((JViewport)container).addChangeListener(this); + stateChanged(new ChangeEvent(container)); + } + + rendererComponent = new RendererComponent(); + rendererComponent.setLayout(new BorderLayout()); + rendererComponent.add( jlName, BorderLayout.WEST ); + rendererComponent.add( jlPath, BorderLayout.CENTER); + rendererComponent.add( jlPrj, BorderLayout.EAST ); + + + jlName.setOpaque(false); + jlPath.setOpaque(false); + jlPrj.setOpaque(false); + + jlName.setFont(list.getFont()); + jlPath.setFont(list.getFont()); + jlPrj.setFont(list.getFont()); + + + jlPrj.setHorizontalAlignment(RIGHT); + jlPrj.setHorizontalTextPosition(LEFT); + + // setFont( list.getFont() ); + fgColor = list.getForeground(); + fgColorLighter = new Color( + Math.min( 255, fgColor.getRed() + LIGHTER_COLOR_COMPONENT), + Math.min( 255, fgColor.getGreen() + LIGHTER_COLOR_COMPONENT), + Math.min( 255, fgColor.getBlue() + LIGHTER_COLOR_COMPONENT) + ); + + bgColor = list.getBackground(); + bgColorDarker = new Color( + Math.abs(bgColor.getRed() - DARKER_COLOR_COMPONENT), + Math.abs(bgColor.getGreen() - DARKER_COLOR_COMPONENT), + Math.abs(bgColor.getBlue() - DARKER_COLOR_COMPONENT) + ); + bgSelectionColor = list.getSelectionBackground(); + fgSelectionColor = list.getSelectionForeground(); + + + bgColorGreener = new Color( + Math.abs(bgColor.getRed() - 20), + Math.min(255, bgColor.getGreen() + 10 ), + Math.abs(bgColor.getBlue() - 20) ); + + + bgColorDarkerGreener = new Color( + Math.abs(bgColorDarker.getRed() - 35), + Math.min(255, bgColorDarker.getGreen() + 5 ), + Math.abs(bgColorDarker.getBlue() - 35) ); + } + + public @Override Component getListCellRendererComponent( JList list, + Object value, + int index, + boolean isSelected, + boolean hasFocus) { + + // System.out.println("Renderer for index " + index ); + + int height = list.getFixedCellHeight(); + int width = list.getFixedCellWidth() - 1; + + width = width < 200 ? 200 : width; + + // System.out.println("w, h " + width + ", " + height ); + + Dimension size = new Dimension( width, height ); + rendererComponent.setMaximumSize(size); + rendererComponent.setPreferredSize(size); + + if ( isSelected ) { + jlName.setForeground(fgSelectionColor); + jlPath.setForeground(fgSelectionColor); + jlPrj.setForeground(fgSelectionColor); + rendererComponent.setBackground(bgSelectionColor); + } + else { + jlName.setForeground(fgColor); + jlPath.setForeground(fgColorLighter); + jlPrj.setForeground(fgColor); + rendererComponent.setBackground( index % 2 == 0 ? bgColor : bgColorDarker ); + } + + if ( value instanceof FileDescription ) { + FileDescription fd = (FileDescription)value; + jlName.setIcon(fd.getIcon()); + jlName.setText(fd.getFileName()); + jlPath.setIcon(null); + jlPath.setHorizontalAlignment(SwingConstants.LEFT); + jlPath.setText(fd.getOwnerPath().length() > 0 ? " (" + fd.getOwnerPath() + ")" : " ()"); //NOI18N + jlPrj.setText(fd.getProjectName()); + jlPrj.setIcon(fd.getProjectIcon()); + if ( !isSelected ) { + rendererComponent.setBackground( index % 2 == 0 ? + ( fd.isFromCurrentProject() && colorPrefered ? bgColorGreener : bgColor ) : + ( fd.isFromCurrentProject() && colorPrefered ? bgColorDarkerGreener : bgColorDarker ) ); + } + rendererComponent.setDescription(fd); + } + else { + jlName.setText( "" ); // NOI18M + jlName.setIcon(null); + jlPath.setIcon(Renderer.WAIT_ICON); + jlPath.setHorizontalAlignment(SwingConstants.CENTER); + jlPath.setText( value.toString() ); + jlPrj.setIcon(null); + jlPrj.setText( "" ); // NOI18N + } + + return rendererComponent; + } + + @Override + public void stateChanged(ChangeEvent event) { + + JViewport jv = (JViewport)event.getSource(); + + jlName.setText( "Sample" ); // NOI18N + jlName.setIcon( new ImageIcon() ); + + jList.setFixedCellHeight(jlName.getPreferredSize().height); + jList.setFixedCellWidth(jv.getExtentSize().width); + } + + public void setColorPrefered( boolean colorPrefered ) { + this.colorPrefered = colorPrefered; + } + + } } diff --git a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchPanel.java b/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchPanel.java --- a/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchPanel.java +++ b/jumpto/src/org/netbeans/modules/jumpto/file/FileSearchPanel.java @@ -75,8 +75,9 @@ * @author Petr Hrebejk, Andrei Badea */ public class FileSearchPanel extends javax.swing.JPanel implements ActionListener { - - private static final int BRIGHTER_COLOR_COMPONENT = 10; + + public static final String SEARCH_IN_PROGRES = NbBundle.getMessage(FileSearchPanel.class, "TXT_SearchingOtherProjects"); // NOI18N + private static final int BRIGHTER_COLOR_COMPONENT = 10; private final ContentProvider contentProvider; private final Project currentProject; private boolean containsScrollPane; @@ -160,7 +161,7 @@ if (model.getSize() > 0 || getText() == null || getText().trim().length() == 0 ) { resultList.setModel(model); resultList.setSelectedIndex(0); - ((FileDescription.Renderer) resultList.getCellRenderer()).setColorPrefered(isPreferedProject()); + ((FileSearchAction.Renderer) resultList.getCellRenderer()).setColorPrefered(isPreferedProject()); setListPanelContent(null,false); if ( time != -1 ) { FileSearchAction.LOGGER.fine("Real search time " + (System.currentTimeMillis() - time) + " ms."); @@ -219,7 +220,7 @@ else if ( message != null ) { jTextFieldLocation.setText(""); messageLabel.setText(message); - messageLabel.setIcon( waitIcon ? FileDescription.Renderer.WAIT_ICON : null); + messageLabel.setIcon( waitIcon ? FileSearchAction.Renderer.WAIT_ICON : null); if ( containsScrollPane ) { listPanel.remove( resultScrollPane ); listPanel.add( messageLabel ); @@ -445,7 +446,7 @@ if ( "selectNextRow".equals(actionKey) && ( selectedIndex == modelSize - 1 || ( selectedIndex == modelSize - 2 && - model.getElementAt(modelSize - 1) == FileDescription.SEARCH_IN_PROGRES ) + model.getElementAt(modelSize - 1) == SEARCH_IN_PROGRES ) ) ) { resultList.setSelectedIndex(0); resultList.ensureIndexIsVisible(0); @@ -455,7 +456,7 @@ selectedIndex == 0 ) { int last = modelSize - 1; - if ( model.getElementAt(last) == FileDescription.SEARCH_IN_PROGRES ) { + if ( model.getElementAt(last) == SEARCH_IN_PROGRES ) { last--; } diff --git a/jumpto/src/org/netbeans/spi/jumpto/file/FileProvider.java b/jumpto/src/org/netbeans/spi/jumpto/file/FileProvider.java new file mode 100644 --- /dev/null +++ b/jumpto/src/org/netbeans/spi/jumpto/file/FileProvider.java @@ -0,0 +1,241 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 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]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.jumpto.file; + +import java.util.List; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.SourceGroup; +import org.netbeans.modules.jumpto.file.FileDescription; +import org.netbeans.modules.jumpto.file.FileProviderAccessor; +import org.netbeans.spi.jumpto.type.SearchType; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; +import org.openide.util.Parameters; + +/** + * A FileProvider participates in the Goto File dialog by providing matched files + * for given {@link SourceGroup}. + * The FileProviders are registered in global {@link Lookup} + * + * @since 1.15 + * @author Tomas Zezula + */ +public interface FileProvider { + + /** + * Compute a list of files that match the given search text for the given + * search type. This might be a slow operation, and the infrastructure may end + * up calling {@link #cancel} on the file provider during the operation, in which + * case the method can return incomplete results. + *

+ * Note that a useful performance optimization is for the FileProvider to cache + * a few of its most recent search results, and if the next search (e.g. more user + * keystrokes) is a simple narrowing of the search, just filter the previous search + * result. The same {@link FileProvider} instance is used during the GoTo File session and + * it's freed when the GoTo File dialog is closed. + * + * @param context search context containg search text, type, project and {@link SourceGroup} root + * @param result filled with files and optional message + * @return returns true if the root was handled by this FileProvider. When false + * next provider is used. + */ + boolean computeFiles(Context context, Result result); + + /** + * Cancel the current operation, if possible. This might be called if the user + * has typed something (including the backspace key) which makes the current + * search obsolete and a new one should be initiated. + */ + void cancel(); + + /** + * Represents search context. + * Contains search type (such as prefix, regexp), search text, + * {@link SourceGroup} root and project where to search. + * + */ + public static final class Context { + + // + private final String text; + private final SearchType type; + private final Project currentProject; + private FileObject sourceGroupRoot; + private Project project; + // + + /** + * Returns project owning the {@link SourceGroup} root + * @return project to search in. + */ + public Project getProject() { + if (project == null) { + project = FileOwnerQuery.getOwner(this.sourceGroupRoot); + } + return project; + } + + /** + * Returns the {@link SourceGroup} root to search files in. + * @return root to search in. + */ + public FileObject getRoot() { return sourceGroupRoot;} + + /** + * Return the text used for search. + * + * @return The text used for the search; e.g. when getSearchType() == SearchType.PREFIX, + * text is the prefix that all returned types should start with. + */ + public String getText() { return text; } + + /** + * Return the type of search. + * + * @return Type of search performed, such as prefix, regexp or camel case. + */ + public SearchType getSearchType() { return type; } + + // + private Context(String text, SearchType type, Project currentProject) { + Parameters.notNull("text", text); //NOI18N + Parameters.notNull("type", type); //NOI18N + this.text = text; + this.type = type; + this.currentProject = currentProject; + } + + private Project getCurrentProject() { + return currentProject; + } + + static { + FileProviderAccessor.setInstance(new FileProviderAccessor() { + @Override + public Context createContext(String text, SearchType searchType, Project currentProject) { + return new Context(text, searchType,currentProject); + } + @Override + public Result createResult(List result, String[] message, Context ctx) { + return new Result(result, message, ctx); + } + @Override + public int getRetry(Result result) { + return result.retry; + } + + @Override + public void setRoot(Context ctx, FileObject root) { + ctx.sourceGroupRoot = root; + ctx.project = null; + } + }); + } + // + } + + /** + * Represents a collection of files that match + * the given search criteria. Moreover, it can contain message + * for the user, such as an incomplete search result. + * + */ + public static final class Result { + + // + private final List result; + private final String[] message; + private final Context ctx; + private int retry; + // + + /** + * Optional message. It can inform the user about result, e.g. + * that result can be incomplete etc. + * + * @param msg message + */ + public void setMessage(String msg) { + message[0] = msg; + } + + /** + * Adds a file into the result + * + * @param file The file to be added to result + */ + public void addFile (final FileObject file) { + Parameters.notNull("file", file); //NOI18N + final String path = FileUtil.getRelativePath(ctx.getRoot(), file); + if (path != null) { + final Project prj = ctx.getProject(); + final Project curPrj = ctx.getCurrentProject(); + result.add(new FileDescription(file, path, prj, + curPrj != null && prj != null && curPrj.getProjectDirectory() == prj.getProjectDirectory())); + } + } + + /** + * Notify caller that a provider should be called again because + * of incomplete or inaccurate results. + * + * Method can be used when long running task blocks the provider + * to complete the data. + * + */ + public void pendingResult() { + retry = 2000; + } + + // + private Result(final List result, final String[] message, final Context ctx) { + Parameters.notNull("result", result); //NOI18N + Parameters.notNull("message", message); //NOI18N + Parameters.notNull("ctx", ctx); + this.result = result; + this.message = message; + this.ctx = ctx; + } + // + } + +} diff --git a/jumpto/src/org/netbeans/spi/jumpto/file/FileProviderFactory.java b/jumpto/src/org/netbeans/spi/jumpto/file/FileProviderFactory.java new file mode 100644 --- /dev/null +++ b/jumpto/src/org/netbeans/spi/jumpto/file/FileProviderFactory.java @@ -0,0 +1,69 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 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]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.jumpto.file; + +/** + * Factory to create {@link FileProvider}s + * @since 1.15 + * @author Tomas Zezula + */ +public interface FileProviderFactory { + /** + * Describe this provider with an internal name, used by logging. + * @return An internal String uniquely identifying {@link FileProvider}, such as + * "java" + */ + String name(); + + /** + * Describe this provider for the user, used by logging. + * @return A display name describing the {@link FileProvider} + */ + String getDisplayName(); + + + /** + * Reurns a {@link FileProvider} used in one session of Go To File action. + * The returned provider is freed when the Go To File dialog is closed. + * The {@link FileProvider} may cache some data to improve performance. + * @return a new {@link FileProvider} + */ + FileProvider createFileProvider(); +} diff --git a/jumpto/test/unit/src/org/netbeans/spi/jumpto/file/FileProviderTest.java b/jumpto/test/unit/src/org/netbeans/spi/jumpto/file/FileProviderTest.java new file mode 100644 --- /dev/null +++ b/jumpto/test/unit/src/org/netbeans/spi/jumpto/file/FileProviderTest.java @@ -0,0 +1,89 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 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]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.jumpto.file; + + +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import org.netbeans.junit.NbTestCase; +import org.netbeans.modules.jumpto.file.FileDescription; +import org.netbeans.modules.jumpto.file.FileProviderAccessor; +import org.netbeans.spi.jumpto.type.SearchType; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * + * @author Tomas Zezula + */ +public class FileProviderTest extends NbTestCase { + + private FileObject root; + private FileObject dataFile; + + public FileProviderTest(final String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + clearWorkDir(); + final File cwd = getWorkDir(); + root = FileUtil.createFolder(new File(cwd,"test")); //NOI18N + dataFile = FileUtil.createData(root, "foo/test.txt"); //NOI18N + } + + public void testFileProvider() { + final FileProvider.Context ctx = FileProviderAccessor.getInstance().createContext("foo", SearchType.EXACT_NAME, null); //NOI18N + final List data = new LinkedList(); + final String[] msg = new String[1]; + final FileProvider.Result result = FileProviderAccessor.getInstance().createResult(data, msg, ctx); + FileProviderAccessor.getInstance().setRoot(ctx, root); + final String testMsg = "Test Message"; //NOI18N + result.addFile(dataFile); + result.setMessage(testMsg); + assertEquals(1, data.size()); + assertEquals(dataFile, data.iterator().next().getFileObject()); + assertEquals(testMsg, msg[0]); + } + +}