Tasklist API proposal rough draft -- please provide feedback

Tor Norbye <[email protected]>
Newsgroups gmane.comp.java.netbeans.modules.tasklist.devel
Message-ID <1035432447.12064.154.camel__665.887088007544$1054569787@proto>
You may have seen some discussion of the "assistants" proposal
(http://ui.netbeans.org/docs/ui/assistants/assistants_proposal.html)
on the alises; part of it deals with the tasklist. We will have a new
"Suggestions" window where various tools can post suggestions that may
be relevant to the user; The import tool may suggest cleanup when it
discovers files needing work. The CVS module may point out a merge
conflict needing to get resolved. etc.

Here's a link to a proposal dealing with the tasklist specific aspects
of the assistants proposal:

http://tasklist.netbeans.org/proposals/suggestions.html

My goal is to write an API for the tasklist such that other NetBeans
modules can start providing suggestions to the tasklist.

Before putting together a specific API proposal in the form of
javadocs, I'd like to describe it here, to get general agreement.

These are the participants in the API:

- "Suggestion". This represents the actual items shown in the
  suggestions list. This is simply a final class with some attributes,
  such as a description, an icon. (And probably a priority, a
  category, and an optional associated file position or url.)

- "SuggestionType". Each suggestion has an associated suggestion type;
  there may be many suggestions for a particular type.  Users can
  disable suggestions by type. They can also filter the suggestions
  window by type, to for example only show audit-suggestions.

- "SuggestionManager". Manages the list of suggestions.  To add a new
  suggestion, you register it with the suggestion manager. The
  suggestion manager also knows if a SuggestionType is disabled or
  not.

- "SuggestionProvider". A client written to specifically produce
  suggestions (more about this later). This is a SPI; you don't have
  to be a SuggestionProvider to register suggestions.  But
  SuggestionProviders are automatically "awakened" if they are enabled
  and the suggestions window is made visible, for example.

- "ActionPerformer". Each suggestion has an associated action.
  For the Import tool, it may be modifying your document to
  clean up the import statements. For the java-compiler-error
  suggestion, it may be moving your cursor and focus to a particular
  source code line. You register an ActionPerformer on the suggestion
  when you create it. 


There are two types of suggestion window clients:

- Clients which are already doing some work, and as a side effect
  would like to also create a task.

  For example, the Java background parsing task discovers errors.
  These (their compiler error message and source position) could be
  added as tasks as well - so instead of just seeing error glyphs in
  the editor the user can also see the error messages and can double
  click on them to warp to the right source line.


  Code might look something like this:

  String suggestionType = "beepid";
  SuggestionManager mgr =
     (SuggestionManager)l.lookup(SuggestionManager.class);
  if ((mgr != null) && mgr.isEnabled(suggestionType)) {
     Suggestion s = new Suggestion(suggestionType);
     s.setSummary("Ring the system bell to annoy neighbors");
     s.setDetails("Ring the system bell 3 times, then quit. Will echo
\007.");
     s.setPerformer(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            beep(); beep(); beep();
        }
     });
     mgr.addSuggestion(s);
  }

  This should be pretty obvious; we find the manager (if it's null the
  tasklist module is probably not enabled), ask it if the kind of
  suggestion we're about to make is welcome by the user, and if so
  create it and register it. We associate an action to be performed with
  it, and also a details panel which the user will be presented with
  before the action is performed. (If null, there is no confirmation
  step, and even when non-null, the user will be able to say "don't ask
  me in the future", and the SuggestionManager will remember that and
  skip the confirmation step for this type of suggestion).
  
  The idea here is that some users don't want for example the import
  tool to keep checking their source code and make suggestions, if they
  don't like its solutions or if they prefer to do it by hand. Having it
  there adds clutter and takes up some cycles.


- Clients which are written specifically to provide suggestions.

  For example, the Import tool could now get a suggestion provider
  which listens for document activation, and when it sees one, checks
  to see if it has suggestions to make, and if so, provides them.



  It's conceivable that the Audit module could be written in this way
  for example; instead of an explicit "Audit..." action, it's always
  auditing source files in the background.

  This works on a timer, so if you sit idle in the editor for a while,
  the suggestion checkers will kick in. The SuggestionManager will
  probably time the suggestion providers, and do something "smart"; for
  example, a really slow suggestion checker will be run frequently, and
  if after say consulting the first 3 suggestion providers we've used up
  N milliseconds, it may stop working for another couple of seconds, and
  then resume notifying suggestion providers.
  
  SuggestionProviders of this type will simply subclass one of the
  SuggestionProvider SPI classes. I can imagine at least two such
  classes.  DocumentSuggestionProvider which has methods like
  "documentOpened", "documentClosed", "documentShown",
  "documentHidden", "documentEdited". These get called (after a
  timeout - well, documentHidden and documentClosed are called
  immediately) when something happens in the editor. So all the Import
  Tool has to do for example is subclass DocumentSuggestionProvider,
  react to the methods to initiate and abort import statement
  scanning.
  
  Best of all, the DocumentSuggestionProvider is registered in the
  module's layer file. The class is only instantiated if the Suggestions
  Window is opened - and of course if a suggestion type is disabled the
  object doesn't get created.  So the point is that there is no
  performance overhead for adding these providers, other than when the
  Suggestions window is actually made visible - and in that case it's
  likely that the user wants these suggestions.
  
  Other provider classes include NodeSuggestionProvider, which is called
  when the active node changes. For example, a specific
  HelpSuggestionProvider extends NodeSuggestionProvider may check the
  node to see if it has an associated help context, and if so add a
  suggestion to show a particular help topic (and it will also remove
  its previously added help topic in any case such that only help topics
  for the current node are shown).


Note that I've glossed over SuggestionTypes. I don't want to force
clients to actually create classes for this.  A suggestion type, as
far as client code is concerned, really just has an id (so it can be
referred to), and a description (so it can be shown in filters,
options, etc.) and this can be registered in a layer file. The id is
the layer file name.

I haven't quite decided what to do with the "ActionPerformer".  I
could use standard interfaces like Runnable or ActionListener, or
invent something new.

For now I'm thinking suggestions expire when you exit the IDE; if we
want to make them longer-lived we have to come up with something more
clever for the action performers (some kind of encoded URL's?).

My intent is for the above classes to be rolled into a
tasklist-api.jar autoload module, which modules can depend on.

So.... that's the rough overview of what I'd been planning.  Does this
sound acceptable? If so, I'll add specific javadoc skeletons so you
can start nitpicking classnames, classes vs interfaces
^H^H^H^H^H^H^H^H^H no no not that flamewar again...)

Warning - while criticism is welcome I want productive criticism, in
other words counter proposals or specific suggestions for how to
change it.

-- Tor
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.