Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 448721

Summary: Cannot provide a new NLS bundle from a plugin
Product: [ECD] Orion Reporter: Mark Macdonald <mamacdon>
Component: ClientAssignee: Mark Macdonald <mamacdon>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: konradk, maciej.bendkowski
Version: 6.0   
Target Milestone: 8.0   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
Source code of my test plugin none

Description Mark Macdonald CLA 2014-10-24 09:51:36 EDT
I have a 3rd party plugin that tries to contribute a new message bundle. (It's not a language pack, i.e. it does not contribute a translation of one of the predefined bundles that ship with Orion, but rather a brand-new bundle that it needs for its own purposes.)

First the plugin declares an command editor command that should be localized using the 'plugin/nls/messages' bundle:

>	provider.registerService("orion.edit.command", {
>		run: function() {
>			return "I set some text in the editor."
>		}
>	}, {
>		id: "example.nls.command",
>		nameKey: "MyCommandName",
>		tooltipKey: "MyCommandTooltip",
>		nls: "plugin/nls/messages",     // !
>	});

Then it registers an i18n service that returns the 'plugin/nls/messages' bundle:

> 	provider.registerService("orion.i18n.message", {
> 		getMessageBundle: function() {
> 			console.log("#getMessageBundle called")
> 			return {
> 				"MyCommandName": "Aaaaa",
> 				"MyCommandTooltip": "bbbbbbbbbbbbbbbb",
> 			};
> 		}
> 	}, {
> 		name: "plugin/nls/messages"     // !
> 	});

The service's #getMessageBundle() method is never called. When the command is rendered, I see a 404 error as the Orion i18n framework tries to load the bundle from the host Orion server:

> Failed to load resource: the server responded with a status of 404 (ProxyServlet: /plugin/nls/messages.js)
> http://localhost:8080/plugin/nls/messages.js

I traced this into i18nUtil#getMessageBundle(). It seems that the service registry is only consulted to find contributed message bundles if the given bundle path already exists within Orion. If the bundle doesn't ship with Orion, it just returns an error.

This effectively makes it impossible for plugins to leverage the i18n framework that Orion offers to provide their own messages. All they can do is translate ours.
Comment 1 Mark Macdonald CLA 2014-10-24 09:54:07 EDT
Created attachment 248158 [details]
Source code of my test plugin

Attaching the code of the plugin I used. To test, host it on a site somewhere and install knlsplugin.html, then load an editor and open the Tools menu. I expect to see a command named "Aaaaa" but instead it appears as "Unnamed" -- the default name used when a localization could not be loaded.
Comment 2 Maciej Bendkowski CLA 2014-10-24 10:18:34 EDT
I had a similar experience some time ago. I opened bug 428640 to suggest that plugins should ship with their own i18n framework and not put the responsibility of loading the translation bundle onto Orion. I think the two bug are essentially duplicates.
Comment 3 Mark Macdonald CLA 2014-10-24 10:40:26 EDT
(In reply to Maciej Bendkowski from comment #2)
> I had a similar experience some time ago. I opened bug 428640 to suggest
> that plugins should ship with their own i18n framework and not put the
> responsibility of loading the translation bundle onto Orion. I think the two
> bug are essentially duplicates.

Ah right, now I understand what 428640 is asking for.

So you're proposing that Orion would inform plugins of the active locale, and everything else is the plugin's responsibility?

We are very close to that today, if you write a plugin that ignores the existing 'nls' framework and just returns already-translated strings. The only missing piece is having Orion inject the locale into the plugin.
Comment 4 Konrad Kolosowski CLA 2014-10-24 10:42:24 EDT
Bug 428640 seems to suggest different strategy for i18n of a plugin.

The example in this bug uses existing strategy and APIs which are reasonable but do not work as expected.
Comment 5 Maciej Bendkowski CLA 2014-10-24 10:57:12 EDT
(In reply to Mark Macdonald from comment #3)
> So you're proposing that Orion would inform plugins of the active locale,
> and everything else is the plugin's responsibility?

About right.
Comment 6 Mark Macdonald CLA 2014-10-30 13:15:06 EDT
(In reply to Mark Macdonald from comment #0)
> The service's #getMessageBundle() method is never called. When the command is 
> rendered, I see a 404 error as the Orion i18n framework tries to load the 
> bundle from the host Orion server.

http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=a072f06

The fix is to first attempt to load the bundle directly, as if it were a builtin. If that fails, we consult the plugin-provided NLS bundles as a fallback.

This is not perfect because we must wait for a plugin-provided bundle to 404 on first load before we eventually find it in the registry. But, after the first time it gets cached (like all message bundles are) and should be fast.

We could avoid having to eat the 404 if we reserved a special prefix for bundles that we ship with orion (like "orion/") so they can be distinguished from other bundles. That felt like too much of a hack (and would require renaming the js bundle messages, which currently start with "javascript/") but we can investigate it if needed.