From 397763bfe954d35c302811223e42d74981f2dd4b Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Tue, 26 May 2026 15:46:14 +0200 Subject: [PATCH] Allow platform:/plugin/ URIs in templates extension include element The 'file' and 'translations' attributes of the element in the org.eclipse.ui.editors.templates extension point previously only accepted plug-in local file paths, resolved relative to the contributing bundle via FileLocator.find(Bundle, IPath, Map). This change extends ContributionTemplateStore.readIncludedTemplates to also accept platform:/ URIs (e.g. platform:/plugin//), allowing a contributor to reference template files that live in another plug-in. Bundle-relative paths continue to work unchanged; platform:/ URIs are resolved via FileLocator.find(URL). --- .../templates/ContributionTemplateStore.java | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/templates/ContributionTemplateStore.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/templates/ContributionTemplateStore.java index 1d9167b0126..eec6ebf5d91 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/templates/ContributionTemplateStore.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/templates/ContributionTemplateStore.java @@ -17,6 +17,9 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; @@ -128,12 +131,12 @@ private void readIncludedTemplates(Collection templates String file= element.getAttribute(FILE); if (file != null) { Bundle plugin = Platform.getBundle(element.getContributor().getName()); - URL url= FileLocator.find(plugin, IPath.fromOSString(file), null); + URL url= resolveResource(plugin, file); if (url != null) { ResourceBundle bundle= null; String translations= element.getAttribute(TRANSLATIONS); if (translations != null) { - URL bundleURL= FileLocator.find(plugin, IPath.fromOSString(translations), null); + URL bundleURL= resolveResource(plugin, translations); if (bundleURL != null) { try (InputStream bundleStream= bundleURL.openStream()) { bundle= new PropertyResourceBundle(bundleStream); @@ -160,6 +163,30 @@ private void readIncludedTemplates(Collection templates } } + /** + * Resolves a resource location to a URL. Supports plain bundle-relative paths + * as well as platform:/plugin/ URIs, which allow referencing files + * contributed by other plug-ins. Other platform:/ schemes (e.g. + * platform:/resource/, platform:/fragment/) are not + * handled here and are treated as bundle-relative paths. + * + * @param plugin the contributing bundle, used for bundle-relative lookups + * @param location the resource location (a bundle-relative path or a + * platform:/plugin/ URI) + * @return the resolved URL, or null if it could not be found + */ + private static URL resolveResource(Bundle plugin, String location) { + if (location.startsWith("platform:/plugin/")) { //$NON-NLS-1$ + try { + return FileLocator.find(new URI(location).toURL()); + } catch (URISyntaxException | MalformedURLException e) { + EditorsPlugin.log(e); + return null; + } + } + return FileLocator.find(plugin, IPath.fromOSString(location), null); + } + /** * Validates a template against the context type registered in the context * type registry. Returns always true if no registry is