This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 73848 - Convenience method: lookupAll
Summary: Convenience method: lookupAll
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Lookup (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: apireviews
URL:
Keywords: API, API_REVIEW_FAST
Depends on:
Blocks:
 
Reported: 2006-03-21 22:27 UTC by Jesse Glick
Modified: 2008-12-22 19:39 UTC (History)
1 user (show)

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
Commit log (21.20 KB, text/plain)
2006-04-04 05:06 UTC, Jesse Glick
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Glick 2006-03-21 22:27:33 UTC
I suggest adding some convenience methods to Lookup:

public final <T> Lookup.Result<T> lookupResult(Class<T> clazz) {
  return lookup(new Lookup.Template<T>(clazz);
}
public final <T> Collection<? extends T> lookupAll(Class<T> clazz) {
  return lookupResult(clazz).allInstances();
}

I find in the Ant module that it is pretty cumbersome to type e.g.

for (DataObject d : context.lookup(new
Lookup.Template<DataObject>(DataObject.class)).allInstances()) {...}

Note that if you omit the <DataObject> in the middle there, you get a rather
cryptic error message. Would much prefer to write e.g.:

for (DataObject d : context.lookupAll(DataObject.class)) {...}

For most purposes the class Lookup.Template is purely conceptual overhead. The
three common use cases do not require it at all:

1. SINGLE, STATIC

T x = l.lookup(T.class);
if (x != null) {...}

2. MULTIPLE, STATIC

for (T x : l.lookupAll(T.class)) {...}

3. MULTIPLE, DYNAMIC

Lookup.Result<T> r = l.lookupResult(T.class);
r.addLookupListener(...);
// ...
for (T x : r.allInstances()) {...}
Comment 1 Jaroslav Tulach 2006-03-22 05:30:24 UTC
Why not?

Is there any impact on compatibility? I can see only one problem and that is 
addition of final method into subclassable class. I would slightly prefer to 
make the methods non-final. In addition to be binary compatible it would also 
allow to override it in AbstractLookup and save the creation of 
Lookup.Template completely.

I'd like to point out related but separate issue of 
Lookup.addLookupListener(LookupListener, Class<?> c> which would be a nice 
simplification for

Class<T> c = ...;
Lookup l = ..;
LookupListener listener = ...;
Lookup.Result<T> r = l.lookup(new Template<T>(c));
r.addLookupListener(listener);
r.allItems(); 

which would then be written as

l.addLookupListener(listener, c);

however I know this is a separate issue and moreover it can have bigger 
compatibility effects (the intermediate result should not garbage collect). 
But if we want to tweak the lookup interface, then maybe it is the right time 
to do both simplifications at once.
Comment 2 Jesse Glick 2006-03-22 16:48:43 UTC
Fine with me for the methods to be nonfinal, if that will help compatibility,
and especially if we can optimize some subclasses to never make a Template at
all. I guess I thought it was more conservative to make the methods final
initially but it's true that this could be a problem for subclasses already
containing such methods. (If we make it nonfinal, there is a hypothetical
problem with a subclass which has an existing method with the same signature and
quite different semantics, but I think that is unlikely.)

Re. Lookup.addLookupListener - not sure I see the purpose of this? In all the
cases I know about, if you are attaching a listener you are also keeping a
long-term ref to the Result and using it to get instances. Do you mean that you
would call Lookup.lookupAll instead? If so, how would the memory management
work? This seems trickier so it might be better left to a separate issue if you
want to pursue it.
Comment 3 Jaroslav Tulach 2006-03-23 07:59:32 UTC
Ok, non-final methods. Make sure they are correctly overridden in 
AbstractLookup to not create the template at all - should be just a matter of 
calling storage.search(clazz), at least in case of lookupAll(Class). 

Ok, listener is separate issue, I'll address it if I get into the right mood. 

Comment 4 Jesse Glick 2006-04-04 05:04:42 UTC
Implemented. I did not however see a good way to override the method to avoid
the Template object in important subclasses, namely AbstractLookup; Template is
used internally for other purposes, incl. in the beforeLookup method. If you
know of a way to optimize it, feel free to apply, but Template is a flyweight
class so I doubt it really matters.
Comment 5 Jesse Glick 2006-04-04 05:06:23 UTC
Created attachment 29573 [details]
Commit log