KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > suggestions > SuggestionManagerImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tasklist.suggestions;
21
22 import org.netbeans.apihole.tasklist.SPIHole;
23 import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider;
24 import org.netbeans.modules.tasklist.providers.SuggestionContext;
25 import org.netbeans.modules.tasklist.providers.SuggestionProvider;
26 import org.netbeans.modules.tasklist.suggestions.settings.ManagerSettings;
27 import org.openide.ErrorManager;
28 import org.openide.loaders.DataObject;
29 import org.openide.windows.TopComponent;
30
31 import javax.swing.text.Document JavaDoc;
32 import java.util.*;
33
34 /**
35  * Actual suggestion manager provided to clients when the Suggestions
36  * module is running.
37  * <p>
38  * It's (not yet well implemented) bridge between providers and their
39  * clients.
40  *
41  * @author Tor Norbye
42  */

43 final public class SuggestionManagerImpl extends DefaultSuggestionManager {
44
45     private final boolean stats = System.getProperty("netbeans.tasklist.stats") != null;
46
47
48     /** Create nnew SuggestionManagerImpl. Public because it needs to be
49      * instantiated via lookup, but DON'T go creating instances of this class!
50      */

51     public SuggestionManagerImpl() {
52     }
53
54     /**
55      * Return true iff the user appears to be "reading" the
56      * suggestions. This means it will return false if the
57      * Suggestion window is not open. This means that if a suggestion
58      * is only temporarily interesting, this method lets you
59      * skip creating a suggestion since if the suggestion window
60      * isn't open, the user won't see it anyway, and since this
61      * is a temporarily-interesting suggestion by the time the
62      * window is opened the suggestion isn't relevant anymore.
63      * (Yes, it's obviously possible that the suggestion window
64      * is open but the user is NOT looking at it; that will be
65      * fixed in tasklist version 24.0 when we have eye scanning
66      * hardware and access-APIs.)
67      * <p>
68      * {@link SuggestionView} for details.
69      *
70      * @param id The String id of the Suggestion Type we're
71      * interested in. You may pass null to ask about any/all
72      * Suggestion Types. See the {@link org.netbeans.modules.tasklist.client.Suggestion} documentation
73      for how Suggestion Types are registered and named.
74      *
75      * @return True iff the suggestions are observed by the user.
76      */

77     public boolean isObserved(String JavaDoc id) {
78         TopComponent.Registry registry = TopComponent.getRegistry();
79         Set opened = registry.getOpened();
80         Iterator it = opened.iterator();
81         while (it.hasNext()) {
82             TopComponent next = (TopComponent) it.next();
83             if (next instanceof SuggestionView) {
84                 SuggestionView view = (SuggestionView) next;
85                 if (view.isObserved(id)) return true;
86             }
87         }
88         return false;
89     }
90
91     /** Keep track of our "view state" since we get a few stray
92      * messages from the component listener.
93      */

94     boolean running = false;
95     boolean prepared = false;
96
97     /** When the Suggestions window is made visible, we notify all the
98      providers that they should run. But that's not correct if there
99      was a filter in effect when you left the window. Thus, we need to
100      check if a SuggestionProvider should be notified. Since I know
101      the filter accepts one and only one SuggestionProvider, for
102      performance reasons it's fastest to just remember which
103      SuggestionProvider is allowed-through. When null, it means there's
104      no filter in effect and all should pass through. */

105     SuggestionProvider unfiltered = null;
106
107
108     // messages got from SuggestionView class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109
// it's the second role, live list of suggestions
110

111     /** Called when the Suggestions View is opened */
112     public void dispatchPrepare() {
113         if (!prepared) {
114             List providers = getProviders();
115             ListIterator it = providers.listIterator();
116             while (it.hasNext()) {
117                 SuggestionProvider provider = (SuggestionProvider) it.next();
118                 try {
119                     provider.notifyPrepare();
120                 } catch (RuntimeException JavaDoc e) {
121                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
122
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
123                 } catch (ThreadDeath JavaDoc e) {
124                     throw e;
125                 } catch (Error JavaDoc e) {
126                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
127
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
128                 }
129             }
130             prepared = true;
131         }
132     }
133
134     /** Called when the Suggestions View is made visible
135      *
136      * @todo If a filter was in effect when we left the window, we should
137      * NOT notify the filtered-out SuggestionProviders!
138      */

139     public void dispatchRun() {
140         if (!running) {
141             if (!prepared) {
142                 dispatchPrepare();
143             }
144             List providers = getProviders();
145             ListIterator it = providers.listIterator();
146             while (it.hasNext()) {
147                 SuggestionProvider provider = (SuggestionProvider) it.next();
148                 if ((unfiltered == null) ||
149                         (unfiltered == provider)) {
150                     try {
151                         provider.notifyRun();
152                     } catch (RuntimeException JavaDoc e) {
153                         ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
154
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
155                     } catch (ThreadDeath JavaDoc e) {
156                         throw e;
157                     } catch (Error JavaDoc e) {
158                         ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
159
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
160                     }
161
162                 }
163             }
164             running = true;
165         }
166     }
167
168     // FIXME should be called on last view/client stop
169
/** Called when the Suggestions View is hidden */
170     public void dispatchStop() {
171         if (running) {
172             List providers = getProviders();
173             ListIterator it = providers.listIterator();
174             while (it.hasNext()) {
175                 SuggestionProvider provider = (SuggestionProvider) it.next();
176                 if ((unfiltered == null) ||
177                         (unfiltered == provider)) {
178                     try {
179                         provider.notifyStop();
180                     } catch (RuntimeException JavaDoc e) {
181                         ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
182
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
183                     } catch (ThreadDeath JavaDoc e) {
184                         throw e;
185                     } catch (Error JavaDoc e) {
186                         ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
187
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
188                     }
189
190                 }
191             }
192             running = false;
193         }
194     }
195
196     /** Called when the Suggestions View is closed */
197     public void notifyViewClosed() {
198         if (prepared) {
199             if (running) {
200                 dispatchStop();
201             }
202             List providers = getProviders();
203             ListIterator it = providers.listIterator();
204             while (it.hasNext()) {
205                 SuggestionProvider provider = (SuggestionProvider) it.next();
206                 provider.notifyFinish();
207             }
208             prepared = false;
209         }
210
211     }
212
213
214     // there is only one SuggestionManager instance
215
private SuggestionList list = null;
216
217     /**
218      * Return the live TaskList that we're managing
219      */

220     public final SuggestionList getList() {
221         if (list == null) {
222             list = new SuggestionList();
223         }
224         return list;
225     }
226
227
228     /**
229      * Return true iff the type of suggestion indicated by the
230      * id argument is enabled. By default, all suggestion types
231      * are enabled, but users can disable suggestion types they're
232      * not interested in.
233      * <p>
234      *
235      * @param id The String id of the Suggestion Type. See the
236      * {@link org.netbeans.modules.tasklist.client.Suggestion} documentation for how Suggestion Types
237      * are registered and named.
238      *
239      * @return True iff the given suggestion type is enabled
240      */

241     public synchronized boolean isEnabled(String JavaDoc id) {
242         ManagerSettings settings = ManagerSettings.getDefault();
243         return settings != null ? settings.isEnabled(id) : true;
244     }
245
246     /**
247      * Store whether or not a particular Suggestion type should be
248      * enabled.
249      * <p>
250      *
251      * @param id The String id of the Suggestion Type. See the
252      * {@link org.netbeans.modules.tasklist.client.Suggestion} documentation for how Suggestion Types
253      * are registered and named.
254      * @param enabled True iff the suggestion type should be enabled
255      * @param dontSave If true, don't save the registry file. Used for batch
256      * updates where we call setEnabled repeatedly and plan to
257      * call writeTypeRegistry() at the end.
258      */

259     public synchronized void setEnabled(String JavaDoc id, boolean enabled,
260                                         boolean dontSave) {
261         SuggestionType type = SuggestionTypes.getDefault().getType(id);
262
263         ManagerSettings.getDefault().setEnabled(id, enabled);
264
265         // Enable/disable providers "live"
266
toggleProvider(type, enabled);
267
268         if (!dontSave) {
269             writeTypeRegistry();
270         }
271
272     }
273
274     /** Enable/disable a provider identified by a type. The provider
275      * will only be disabled if all of its OTHER types are disabled. */

276     private void toggleProvider(SuggestionType type, boolean enable) {
277         // Update the suggestions list: when disabling, rip out suggestions
278
// of the same type, and when enabling, trigger a recompute in case
279
// we have pending suggestions
280
SuggestionProvider provider = getProvider(type);
281         if (provider == null) {
282             // This seems to happen when modules are uninstalled for example
283
return;
284         }
285         // XXX Note - there could be multiple providers for a type!
286
// You really should iterate here!!!
287
toggleProvider(provider, type, enable, false);
288     }
289
290     /** Same as toggleProvider, but the allTypes parameter allows you
291      * to specify that ALL the types should be enabled/disabled */

292     private void toggleProvider(SuggestionProvider provider,
293                                 SuggestionType type, boolean enable,
294                                 boolean allTypes) {
295         if (enable) {
296             // XXX This isn't exactly right. Make sure we do the
297
// right life cycle for each provider.
298
// especially handle DocumetSuggestionProviders
299
provider.notifyPrepare();
300             provider.notifyRun();
301         } else {
302             if (!allTypes) {
303                 String JavaDoc typeName = provider.getType();
304                 if (!typeName.equals(type.getName())) {
305                     if (isEnabled(typeName)) {
306                         // Found other enabled provider - bail
307
getList().removeCategory(type);
308                         return;
309                     }
310                 }
311             }
312
313             // Remove suggestions of this type
314
// XXX This isn't exactly right. Make sure we do the
315
// right life cycle for each provider.
316
// especially handle DocumetSuggestionProviders
317
provider.notifyStop();
318             provider.notifyFinish();
319
320             String JavaDoc typeName = provider.getType();
321             if (isEnabled(typeName)) {
322                 // Found other enabled provider - bail
323
getList().removeCategory(type);
324                 return;
325             }
326         }
327     }
328
329     /**
330      * Return true iff the type of suggestion indicated by the
331      * type argument should produce a confirmation dialog
332      * By default, all suggestion types have confirmation dialogs
333      * (if they provide one) but users can select to skip these.
334      * <p>
335      * The only way to get it back is to disable the type, and
336      * re-enable it.
337      *
338      * @param type The Suggestion Type. See the
339      * {@link org.netbeans.modules.tasklist.client.Suggestion} documentation for how Suggestion Types
340      * are registered and named.
341      *
342      * @return True iff the given suggestion type should have a
343      * confirmation dialog.
344      */

345     public synchronized boolean isConfirm(SuggestionType type) {
346         return ManagerSettings.getDefault().isConfirm(type);
347     }
348
349
350     /**
351      * Store whether or not a particular Suggestion type should produce
352      * a confirmation popup.
353      * <p>
354      *
355      * @param type The Suggestion Type. See the
356      * {@link org.netbeans.modules.tasklist.client.Suggestion} documentation for how Suggestion Types
357      * are registered and named.
358      * @param write Write to disk the update iff true.
359      * @param confirm True iff the suggestion type should have a confirmation
360      * dialog
361      */

362     synchronized void setConfirm(SuggestionType type, boolean confirm, boolean write) {
363         ManagerSettings.getDefault().setConfirm(type, confirm);
364         if (write) {
365             writeTypeRegistry();
366         }
367     }
368
369     /** Notify the SuggestionManager that a particular category filter
370      * is in place.
371      *
372      * @param type SuggestionType to be shown, or
373      * null if the view should not be filtered (e.g. show all)
374      */

375     public void notifyFiltered(SuggestionList tasklist, SuggestionType type) {
376         SuggestionType prevFilterType = getUnfilteredType();
377         setUnfilteredType(type);
378
379         if (type != null) {
380             // "Flatten" the list when I'm filtering so that I don't show
381
// category nodes!
382
List oldList = tasklist.getTasks();
383
384             if (oldList != null) {
385                 List allTasks = new ArrayList(oldList.size());
386                 allTasks.addAll(oldList);
387                 tasklist.clear();
388                 Collection types = SuggestionTypes.getDefault().getAllTypes();
389                 Iterator it = types.iterator();
390                 while (it.hasNext()) {
391                     SuggestionType t = (SuggestionType) it.next();
392                     ArrayList list = new ArrayList(100);
393                     Iterator all = allTasks.iterator();
394                     SuggestionImpl category =
395                             tasklist.getCategoryTask(t, false);
396                     tasklist.removeCategory(category, true);
397                     while (all.hasNext()) {
398                         SuggestionImpl sg = (SuggestionImpl) all.next();
399                         if (sg.getSType() == t) {
400                             if ((sg == category) &&
401                                     sg.hasSubtasks()) { // category node
402
list.addAll(sg.getSubtasks());
403                             } else {
404                                 list.add(sg);
405                             }
406                         }
407                     }
408                     // XXX what a hell means these register over here
409
register(t.getName(), list, null, tasklist, true);
410                 }
411             }
412         } else {
413             tasklist.clearCategoryTasks();
414             List oldList = tasklist.getTasks();
415             List suggestions = new ArrayList();
416             if (oldList != null)
417                 suggestions.addAll(oldList);
418             tasklist.clear();
419             Iterator it = suggestions.iterator();
420             List group = null;
421             SuggestionType prevType = null;
422             while (it.hasNext()) {
423                 SuggestionImpl s = (SuggestionImpl) it.next();
424                 if (s.getSType() != prevType) {
425                     if (group != null) {
426                         register(prevType.getName(), group, null,
427                                 tasklist, true);
428                         group.clear();
429                     } else {
430                         group = new ArrayList(50);
431                     }
432                     prevType = s.getSType();
433                 }
434                 if (group == null) {
435                     group = new ArrayList(50);
436                 }
437                 group.add(s);
438             }
439             if ((group != null) && (group.size() > 0)) {
440                 register(prevType.getName(), group, null, tasklist, true);
441             }
442         }
443
444         unfiltered = null;
445
446         // Do NOT NOT NOT confuse disabling modules for performance
447
// (to achieve filtering) with disabling modules done by the
448
// user! In particular, applying a filter and then removing it
449
// should not leave previously undisabled module disabled!
450

451         List providers = getProviders();
452         SuggestionTypes suggestionTypes = SuggestionTypes.getDefault();
453         ListIterator it = providers.listIterator();
454         while (it.hasNext()) {
455             SuggestionProvider provider = (SuggestionProvider) it.next();
456
457             // XXX This will process diabled providers/types as well!
458
String JavaDoc typeName = provider.getType();
459             if (type != null) {
460                 // We're adding a filter: gotta disable all providers
461
// that do not provide the given type
462
boolean enabled = false;
463                 SuggestionType tp = suggestionTypes.getType(typeName);
464                 if (tp == type) {
465                     enabled = true;
466                 }
467                 if (enabled) {
468                     // The provider should be enabled - it provides info
469
// for this type
470
unfiltered = provider;
471                     if (prevFilterType != null) {
472                         SuggestionType sg = suggestionTypes.getType(typeName);
473                         toggleProvider(provider, sg, true, true);
474                     } // else:
475
// The provider is already enabled - we're coming
476
// from an unfiltered view (and disabled providers
477
// in an unfiltered view shouldn't be available as
478
// filter categories)
479
} else {
480                     SuggestionType sg = suggestionTypes.getType(typeName);
481                     toggleProvider(provider, sg, false, true);
482                 }
483             } else {
484                 // We're removing a filter: enable all providers
485
// (that are not already disabled by the user); and
486
// don't enable a module that's already enabled (the
487
// previously filtered type - prevFilterType)
488
boolean isPrev = false;
489                 SuggestionType tp = suggestionTypes.getType(typeName);
490                 if (prevFilterType == tp) {
491                     // This provider is responsible for the previous
492
// filter - nothing to do (already enabled)
493
// bail
494
isPrev = true;
495                     break;
496                 }
497                 if (isPrev) {
498                     continue;
499                 }
500
501                 SuggestionType sg = suggestionTypes.getType(typeName);
502                 toggleProvider(provider, sg, true, true);
503             }
504
505         }
506     }
507
508
509
510     public boolean isExpandedType(SuggestionType type) {
511         return ManagerSettings.getDefault().isExpandedType(type);
512     }
513
514
515     public void setExpandedType(SuggestionType type, boolean expanded) {
516         ManagerSettings.getDefault().setExpandedType(type, expanded);
517     }
518
519
520     // Consult super for correct javadoc
521
public void register(String JavaDoc type, List add, List remove, Object JavaDoc request) {
522         SPIMonitor.log(" Response on " + request + " " + type + " add: " + ((add != null) ? ""+add.size() : "null") + " remove:" + ((remove != null) ? ""+remove.size() : "null"));
523         //System.out.println("register(" + type + ", " + add +
524
// ", " + remove + ", " + request + ")");
525
SuggestionList target = getList();
526         if (target == null) {
527             // This is a result from a previous request - e.g. a long
528
// running request which was "cancelled" but too late to
529
// stop the provider from computing and providing a result.
530
//System.err.println("[MGR] ignoring request: " + request + " remove:" + remove);
531
return;
532         }
533
534         if ((type == null) && (add != null) && (remove != null)) {
535             // Gotta break up the calls since we cannot handle
536
// both adds and removes with mixed types. Do removes,
537
// then adds.
538
register(type, null, remove, target, !switchingFiles);
539             register(type, add, null, target, !switchingFiles);
540         } else {
541             register(type, add, remove, target, !switchingFiles);
542         }
543     }
544
545     /** When true, we're in the process of switching files, so a register
546      removal looks like an "unknown" sized list */

547     private boolean switchingFiles = false;
548
549
550     /** The given document has been opened
551      * <p>
552      * @param document The document being opened
553      * @param dataobject The Data Object for the file being opened
554      * <p>
555      * This method is called internally by the toolkit and should not be
556      * called directly by programs.
557      */

558 /* Not yet called from anywhere. Does anyone need it?
559     private void docOpened(Document document, DataObject dataobject) {
560         List providers = getDocProviders();
561         ListIterator it = providers.listIterator();
562         while (it.hasNext()) {
563             DocumentSuggestionProvider provider = (DocumentSuggestionProvider)it.next();
564             // if ((unfiltered == null) || (provider == unfiltered))
565             provider.docOpened(document, dataobject);
566         }
567     }
568 */

569
570
571     /** Return true iff the given provider should rescan when a file is shown */
572     private boolean scanOnShow(DocumentSuggestionProvider provider) {
573         // For now, just use "global" flag (shared for all providers)
574
return ManagerSettings.getDefault().isScanOnShow();
575     }
576
577     /** Return true iff the given provider should rescan when a file is saved */
578     private boolean scanOnSave(DocumentSuggestionProvider provider) {
579         // For now, just use "global" flag (shared for all providers)
580
return ManagerSettings.getDefault().isScanOnSave();
581     }
582
583     /** Return true iff the given provider should rescan when a file is edited */
584     private boolean scanOnEdit(DocumentSuggestionProvider provider) {
585         // For now, just use "global" flag (shared for all providers)
586
return ManagerSettings.getDefault().isScanOnEdit();
587     }
588
589     /**
590      * The given document has been saved - and a short time period
591      * has passed.
592      * <p>
593      * @param document The document being saved.
594      * @param dataobject The Data Object for the file being saved
595      * <p>
596      * This method is called internally by the toolkit and should not be
597      * called directly by programs.
598      */

599 /*
600     public void docSavedStable(Document document, DataObject dataobject) {
601         List providers = getDocProviders();
602         ListIterator it = providers.listIterator();
603         while (it.hasNext()) {
604             DocumentSuggestionProvider provider =
605                 (DocumentSuggestionProvider)it.next();
606             if ((unfiltered == null) || (provider == unfiltered)) {
607                 provider.docSaved(document, dataobject);
608             }
609         }
610         rescan(document, dataobject);
611     }
612 */

613
614
615
616
617     /**
618      * The given document has been edited or saved, and a time interval
619      * (by default around 2 seconds I think) has passed without any
620      * further edits or saves.
621      * <p>
622      * Update your Suggestions as necessary. This may mean removing
623      * previously registered Suggestions, or editing existing ones,
624      * or adding new ones, depending on the current contents of the
625      * document.
626      * <p>
627      * @param document The document being edited
628      * @param dataobject The Data Object for the file being opened
629      * @param acceptor narrows set of providers to be quaried
630      */

631     void DELETE_dispatchRescan(Document JavaDoc document, DataObject dataobject, final Object JavaDoc request, ProviderAcceptor acceptor) {
632
633         assert request != null : "Precondition for SuggestionsBroker.getCurrRequest()"; // NOI18N
634

635         if (dataobject.isValid() == false) return;
636         
637         long start = 0, end = 0, total = 0;
638         List providers = getDocProviders();
639         Iterator it = providers.iterator();
640
641         SuggestionContext ctx = SPIHole.createSuggestionContext(dataobject);
642         while (it.hasNext()) {
643             if (SuggestionsBroker.getDefault().getCurrRequest() != request) return;
644
645             DocumentSuggestionProvider provider = (DocumentSuggestionProvider) it.next();
646             if (acceptor.accept(provider) == false) continue;
647             if ((unfiltered == null) || (provider == unfiltered)) { // TODO remove unfiltered and replace by acceptors
648
if (stats) {
649                     start = System.currentTimeMillis();
650                 }
651                 try {
652                     SPIMonitor.log("Enter rescan " + request + " " + provider.getClass());
653                     //provider.rescan(ctx, request);
654
} catch (RuntimeException JavaDoc e) {
655                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
656
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
657                 } catch (ThreadDeath JavaDoc e) {
658                     throw e;
659                 } catch (Error JavaDoc e) {
660                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
661
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
662                 } finally {
663                     SPIMonitor.log("Leave rescan " + request + " " + provider.getClass());
664                 }
665                 if (stats) {
666                     end = System.currentTimeMillis();
667                     System.out.println("Scan time for provider " + provider.getClass().getName() + " = " + (end - start) + " ms");
668                     total += (end - start);
669                 }
670             }
671         }
672         if (stats) {
673             System.out.println("TOTAL SCAN TIME = " + total + "\n");
674         }
675     }
676
677     /** @return never <code>null</code> */
678     List dispatchScan(DataObject dataobject, ProviderAcceptor acceptor) {
679
680         if (dataobject.isValid() == false) return Collections.EMPTY_LIST;
681
682         long start = 0, end = 0, total = 0;
683         List providers = getDocProviders();
684         Iterator it = providers.iterator();
685
686         final List result = new LinkedList();
687
688         SuggestionContext ctx = SPIHole.createSuggestionContext(dataobject);
689         while (it.hasNext()) {
690
691             DocumentSuggestionProvider provider = (DocumentSuggestionProvider) it.next();
692             if (acceptor.accept(provider) == false) continue;
693             if ((unfiltered == null) || (provider == unfiltered)) { // TODO remove unfiltered and replace by acceptors
694
if (stats) {
695                     start = System.currentTimeMillis();
696                 }
697                 try {
698                     SPIMonitor.log("Enter scan " + provider.getClass());
699                     List found = provider.scan(ctx);
700                     if (found != null) {
701                         result.addAll(found);
702                     }
703                 } catch (RuntimeException JavaDoc e) {
704                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
705
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
706                 } catch (ThreadDeath JavaDoc e) {
707                     throw e;
708                 } catch (Error JavaDoc e) {
709                     ErrorManager.getDefault().annotate(e, "Skipping faulty provider (" + provider + ")."); // NOI18N
710
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
711                 } finally {
712                     SPIMonitor.log("Leave rescan " + provider.getClass());
713                 }
714                 if (stats) {
715                     end = System.currentTimeMillis();
716                     System.out.println("Scan time for provider " + provider.getClass().getName() + " = " + (end - start) + " ms");
717                     total += (end - start);
718                 }
719             }
720         }
721         if (stats) {
722             System.out.println("TOTAL SCAN TIME = " + total + "\n");
723         }
724
725         return result;
726     }
727
728     /** Tell the DocumentListener to wait updating itself indefinitely
729      * (until it's told not to wait again). When it's told to stop waiting,
730      * itself, it will call rescan if that was called and cancelled
731      * at some point during the wait
732      * <p>
733      * Typically, you should NOT call this method. It's intended for use
734      * by the Suggestions framework to allow for example the modal fix
735      * dialog which provides confirmations to suspend document updates until
736      * all fix actions have been processed.
737      */

738     void setFixing(boolean wait) {
739         // dispatch to hardcoded listeners
740
SuggestionsBroker.getDefault().setFixing(wait);
741     }
742
743
744     /** FOR DEBUGGING ONLY: Look up the data object for a top
745      component, if possible. Returns the object itself if no DO
746      was found (suitable for printing: DO is best, but component will
747      do.
748      private static Object tcToDO(TopComponent c) {
749      Node[] nodes = c.getActivatedNodes();
750      if (nodes == null) {
751      return c;
752      }
753      Node node = nodes[0];
754      if (node == null) {
755      return c;
756      }
757      DataObject dao = (DataObject)node.getCookie(DataObject.class);
758      if (dao == null) {
759      return c;
760      } else {
761      return dao;
762      }
763      }
764      */

765
766
767
768
769
770
771     /** Enable/disable/confirm the given collections of SuggestionTypes */
772     void editTypes(List enabled, List disabled, List confirmation) {
773         Iterator it = enabled.iterator();
774         while (it.hasNext()) {
775             SuggestionType type = (SuggestionType) it.next();
776             if (!isEnabled(type.getName())) {
777                 setEnabled(type.getName(), true, true);
778             }
779         }
780
781         it = disabled.iterator();
782         while (it.hasNext()) {
783             SuggestionType type = (SuggestionType) it.next();
784             if (isEnabled(type.getName())) {
785                 setEnabled(type.getName(), false, true);
786             }
787         }
788
789         Iterator allIt = SuggestionTypes.getDefault().getAllTypes().iterator();
790         while (allIt.hasNext()) {
791             SuggestionType t = (SuggestionType) allIt.next();
792             it = confirmation.iterator();
793             boolean found = false;
794             while (it.hasNext()) {
795                 SuggestionType type = (SuggestionType) it.next();
796                 if (type == t) {
797                     found = true;
798                     break;
799                 }
800             }
801             setConfirm(t, !found, false);
802         }
803
804         // Flush changes to disk
805
writeTypeRegistry();
806     }
807
808     private void writeTypeRegistry() {
809         ManagerSettings.getDefault().store();
810     }
811
812
813     // delegate to providers registry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
814

815     private List getProviders() {
816         return SuggestionProviders.getDefault().getProviders();
817     }
818
819     private List getDocProviders() {
820         return SuggestionProviders.getDefault().getDocProviders();
821     }
822
823     private SuggestionProvider getProvider(SuggestionType type) {
824         return SuggestionProviders.getDefault().getProvider(type);
825     }
826
827 }
828
Popular Tags