|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.tasklist.suggestions; import org.openide.loaders.DataObject; import org.openide.awt.StatusDisplayer; import org.openide.util.NbBundle; import org.openide.util.Lookup; import org.openide.util.Cancellable; import org.openide.util.Utilities; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.windows.WindowManager; import org.openide.windows.Mode; import org.openide.windows.TopComponent; import org.openide.text.CloneableEditorSupport; import org.openide.nodes.Node; import org.openide.ErrorManager; import org.netbeans.modules.tasklist.providers.SuggestionContext; import org.netbeans.modules.tasklist.providers.SuggestionProvider; import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider; import org.netbeans.apihole.tasklist.SPIHole; import org.netbeans.modules.tasklist.client.SuggestionManager; import javax.swing.*; import java.util.*; import java.lang.ref.WeakReference; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.lang.reflect.InvocationTargetException; /** * Scans for suggestions by delegating to * plugged-in providers. * * @todo Should I use FileObjects instead of DataObjects when passing * file identity around? It seems weird that I don't allow * scanning on secondary files (although it seems right in the * cases I can think of - we don't want to scan .class files, * .o files, .form files, ...). Pros: DataObject layer is a classification * layer that defines EditorCookies etc. Cons: Too many dependencies * on possibly slow and leaking code. * * @author Petr Kuzel */ public final class SuggestionsScanner implements Cancellable { /** Optional progress monitor */ private ScanProgress progressMonitor; /** * Contains already scanned dataobjects. * It'd be very memory intensive so only preferred * are stored. * Other duplicities (unlikely) can cause * suggestion duplicities. */ private final Set scanned = new HashSet(); /** Target suggestion list. */ private SuggestionList list; private ProviderAcceptor typeFilter; // target manager impl private final SuggestionManagerImpl manager; private final SuggestionProviders registry; // keep default instance (only if a client exists) private static Reference instance; private volatile boolean interrupted; private int suggestionsCounter; private int usabilityLimit = 503; private boolean workaround38476; // list that replaces direct manager regiltration private List cummulateInList; private SuggestionsScanner() { manager = (SuggestionManagerImpl) Lookup.getDefault().lookup(SuggestionManager.class); registry = SuggestionProviders.getDefault(); } public static SuggestionsScanner getDefault() { if (instance == null) { return createDefault(); } SuggestionsScanner scanner = (SuggestionsScanner) instance.get(); if (scanner == null) { return createDefault(); } else { return scanner; } } private static SuggestionsScanner createDefault() { SuggestionsScanner scanner = new SuggestionsScanner(); instance = new WeakReference(scanner); return scanner; } /** * Scans recursively for suggestions notifing given progress monitor. * @param folders containers to be scanned. It must be DataObject subclasses! * @param list * @param monitor */ public final synchronized void scan(DataObject.Container[] folders, SuggestionList list, ScanProgress monitor) { scan(folders, list, monitor, ProviderAcceptor.ALL); } /** * Scans recursively for suggestions notifing given progress monitor. * @param folders containers to be scanned. It must be DataObject subclasses! * @param list * @param monitor * @param filter suggestion provider filter */ public final synchronized void scan(DataObject.Container[] folders, SuggestionList list, ScanProgress monitor, ProviderAcceptor filter) { try { typeFilter = filter; progressMonitor = monitor; scan(folders, list, true); } finally { typeFilter = null; progressMonitor = null; if (monitor != null) monitor.scanFinished(); } } /** * Iterate over the folder recursively (optional) and scan all files. * We skip CVS and SCCS folders intentionally. Would be nice if * the filesystem hid these things from us. * * @param folders containers to be scanned. It must be DataObject subclasses! * @param list target suggestions list * @param recursive use descent policy */ private final synchronized void scan(DataObject.Container[] folders, SuggestionList list, boolean recursive) { lowMemoryWarning = false; lowMemoryWarningCount = 0; interrupted = false; assureMemory(REQUIRED_PER_ITERATION, true); // guard low memory condition suggestionsCounter = 0; try { this.list = list; // scan opened files first these are most specifics // it should also improve perceived performance workaround38476 = true; scanPreferred(folders, recursive); workaround38476 = false; if (progressMonitor != null) { int estimate = -1; progressMonitor.estimate(estimate); for (int i = 0; i < folders.length; i++) { // it's faster to check at FS level however we can miss some links (.shadow) FileObject fo = ((DataObject)folders[i]).getPrimaryFile(); estimate += countFolders(fo); } progressMonitor.estimate(estimate); progressMonitor.scanStarted(); } for (int i = 0; i < folders.length; i++) { if (shouldStop()) return; DataObject.Container folder = folders[i]; scanFolder(folder, recursive); } } finally { scanned.clear(); } } /** * Return all opened top components in editor mode. * @return never null */ static TopComponent[] openedTopComponents() { final Object[] wsResult = new Object[1]; try { if (SwingUtilities.isEventDispatchThread()) { Mode editorMode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE); if (editorMode == null) { return new TopComponent[0]; } else { return editorMode.getTopComponents(); } } else { // I just hope that we are not called from non-AWT thread // still holding AWTTreeLock otherwise deadlock SwingUtilities.invokeAndWait(new Runnable() { public void run() { Mode editorMode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE); if (editorMode == null) { wsResult[0] = new TopComponent[0]; } else { wsResult[0] = editorMode.getTopComponents(); } } }); return (TopComponent[]) wsResult[0]; } } catch (InterruptedException e) { return new TopComponent[0]; } catch (InvocationTargetException e) { return new TopComponent[0]; } } /** * Determines if given dataobject lies in scan context * and scans it. * * @param folders scan context * @param recursive iff true scan context is scanned recusively */ private void scanPreferred(DataObject.Container[] folders, boolean recursive) { TopComponent[] views = openedTopComponents(); DataObject[] roots = null; for (int i = 0; i |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.