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.
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()) {...}
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.
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.
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.
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.
Created attachment 29573 [details] Commit log