Patch/Merge plugin.properties file in plugin by using fragment
Question
In my plugin de.support.help are the plugin.properties files. These properties files include the strings for the preference page.
I want to use this plugin for different customers, but the customer name is inside the properties files.
I want to patch the properties files by using the eclipse fragment mechanism. As far as i now the fragment plugin can patch the coresponding plugin at runtime.
I do have the file plugin.properties in plugin de.support.help which includes the line
plugin.name = Copyright XYZ
And i do have the fragemt de.support.help.fragment which includes the file plugin.properties with line
plugin.name = Copyright ABC
I expect that at runtime the string "Copyright ABC" is shown, but it is not. I had tested the same with java classes a long time ago and i remember that t his was working. The java code from the fragment was placed to the original plugin.
Do you have any idea to handle this? Or do i misunderstand the fragment mechanism?
Thanks
EDIT:
When i remove the plugin.properties file from the de.support.help plugin it works as expected. The fragment file is copied into the plugin directory and is used at runtime.
Or do i have to patch the somce eclipse class Can_fragments_be_used_to_patch_a_plug
Solution 2
The solution i have implemented is like
First look for special fragment property file and than look for the default property file.
The code is (Bundle names were changed)
public final class FrameworkMessages {
private static final String BUNDLE_NAME = "de.rts.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private static final String BUNDLE_FRAGMENT_NAME = "de.rts.fragment"; //$NON-NLS-1$
private FrameworkMessages() {
}
public static String getString(String key) {
try {
return ResourceBundle.getBundle(BUNDLE_FRAGMENT_NAME).getString(key);
} catch (MissingResourceException e) {
// Use messages in this plugin when no external fragment files can found
}
try {
return RESOURCE_BUNDLE.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}
public static String getString(String pKey, Object[] pArgument) {
try {
return MessageFormat.format(RESOURCE_BUNDLE.getString(pKey), pArgument);
} catch (MissingResourceException e) {
return '!' + pKey + '!';
}
}
}
OTHER TIPS
According to How to Internationalize your Eclipse Plug-In article
A plug-in fragment provides additional functionality to its target plug-in.
At runtime, these plug-in contributions are merged along with all dependent fragments.These contributions can include code contributions and contributions of resources associated with a plug-in, like property and HTML files.
In other words, the plug-in has access to the fragment's contents via the plug-in's classloader.
The Eclipse Platform merges plug-in fragments in a way that the runtime elements in the fragment augment the original targeted plug-in.
The target plug-in is not moved, removed, or modified in any way.Since the fragment's resources are located by the classloader, the plug-in developer has no need to know whether resources are loaded from the plug-in's JAR file or one of its fragments' JAR files.
I suspect the classLoader detect plugin.name
in the de.support.help
plugin first before the de.support.help.fragment
fragment.
At this point, I am not sure it can be done, since it has been attempted before (for the Eclipse CheckStyle plugin), without much success.
You cannot replace the content of a file with a fragment - only add additional files. This is true both for classes, properties files, images, ...
There are several standard methods for solving this problem:
- you can add an extension point with this and other customer specific information.
- you can first look for a special file and this fall back to the general one - as done by Markus.
- you can have an optional dependency on a plugin with the relevant information.
I prefer the last solution as this also allows be to choose between alternative algorithms and other things that does not belong in .properties files...