Bug 567402 - Consider adding FileLocator#find(Class<?> clazz, url) method
Summary: Consider adding FileLocator#find(Class<?> clazz, url) method
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 4.17   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-09-28 04:10 EDT by Lars Vogel CLA
Modified: 2020-09-28 09:59 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lars Vogel CLA 2020-09-28 04:10:59 EDT
Pattern I see in client code:

Bundle bundle = Platform.getBundle(imageBundle);
image = ImageDescriptor.createFromURL(FileLocator.find(bundle, newPath(imagePath)));

Same for ImageDescriptor.createFromURLSupplier

Maybe we should add a method similar to Platform#getLog

	public static ILog getLog(Class<?> clazz) {
		Bundle bundle = FrameworkUtil.getBundle(clazz);
		return InternalPlatform.getDefault().getLog(bundle);
	}
Comment 1 Lars Vogel CLA 2020-09-28 04:11:30 EDT
Alexander / Alex, WDYT?
Comment 2 Alexander Fedorov CLA 2020-09-28 05:04:51 EDT
How about

```
public final class BundleUrl implements Function<String, URL> {
   private final Bundle bundle;

   public BundleUrl(Bundle bundle) {
      this.bundle = bundle;
   }

   public BundleUrl(Class<?> clazz) {
      this(FrameworkUtil.getBundle(clazz));
   }

//resolve String to URL


}
```

just to not increase the number of global functions :)
Comment 3 Alex Blewitt CLA 2020-09-28 09:59:49 EDT
The 'createFromURL' is a potentially expensive operation, because it involves starting the bundle and walking through all its resources to find something, especially if you have the NL/OS interpolation going on. I'd prefer to see an inversion of control, like we do with the createFromURLSupplier, that defers the creation of the URL until it's needed for the first time.

If you've got something like the Log pattern below, it would be better to use the ServiceCaller to get a service a single time, and then pass into it the thing that you want to do with the log.

https://alblue.bandlem.com/2020/07/why-servicecaller-is-better.html

Class callerClass = getClass();
ServiceCaller.callOnce(callerClass, ILog.class, (log) -> log.something());

That way, if the ILog isn't found, you don't do any work, and if the log goes away afterwards you don't need to worry about holding on to a stale reference.

There's also a mode which you can use to cache the ServiceCaller for subsequent use.

Would that be better?