Java eclipse RCP中的plugin.properties机制
我的项目包括多个插件,每个插件都包含plugin.properties文件,其中包含近20个翻译。 MANIFEST.MF文件定义存储外部插件字符串的属性文件的名称Java eclipse RCP中的plugin.properties机制,java,plugins,rcp,fragment,Java,Plugins,Rcp,Fragment,我的项目包括多个插件,每个插件都包含plugin.properties文件,其中包含近20个翻译。 MANIFEST.MF文件定义存储外部插件字符串的属性文件的名称 Bundle-Localization: plugin 我定义的插件的名称 %plugin.name Eclipse将在运行时搜索plugin.properties文件中的“%plugin.name” 在“plugin.properties”文件中,哪个类读取了MANIFEST.MF Bundle本地化条目,在哪个点搜索带有起始
Bundle-Localization: plugin
我定义的插件的名称
%plugin.name
Eclipse将在运行时搜索plugin.properties文件中的“%plugin.name”
在“plugin.properties”文件中,哪个类读取了MANIFEST.MF Bundle本地化条目,在哪个点搜索带有起始“%”后缀的字符串
我想以这种方式找到并修补这些类,这样我就可以首先查找其他一些目录/文件中的“%plugin.name”标识符。有了这些新机制,我可以向我的产品中添加片段,并覆盖“plugin.properties”文件中的单行,而无需更改原始插件。
通过这些机制,我可以通过添加不同的片段为多个客户创建一个构建过程。这些片段包括客户名称和他们想要更改的特殊字符串
我想这样做,因为片段机制只向原始插件添加文件。当插件中存在“plugin.properties”文件时,将忽略片段“plugin.properties”文件
更新1:
方法
class ManifestLocalization{
...
protected ResourceBundle getResourceBundle(String localeString) {
}
...
}
返回给定区域设置字符串的属性文件的ResourceBundle。
当有人知道我现在如何首先查看片段以获得资源路径时,请发布它
更新2:
类中的方法
private URL findInResolved(String filePath, AbstractBundle bundleHost) {
URL result = findInBundle(filePath, bundleHost);
if (result != null)
return result;
return findInFragments(filePath, bundleHost);
}
搜索属性文件并将其缓存。翻译无法从缓存文件中获取。问题是,整个文件是缓存的,而不是单个翻译
解决方案是首先读取片段文件,而不是读取捆绑文件。当两个文件都存在时,将它们合并到一个文件中,并将新的属性文件写入磁盘。返回新属性文件的URL,以便缓存新属性文件。将片段plugin.properties的名称更改为其他名称,例如fragment.properties 在片段清单中更改 捆绑本地化:插件 到 束定位:片段
您的插件将被激活两次,第一次使用plugin.properties,第二次使用fragment.properties。插件激活由OSGi运行时Equinox处理。但是,我强烈反对尝试修补任何文件以创建特定行为。马克建议的方法似乎是解决你问题的更明智的方法。尽管我得到的信息是错误的。。。我也有同样的问题。插件没有激活两次,我无法获得碎片包本地化密钥 我希望我所有的语言翻译都在plugin.properties中(我知道这是不受欢迎的,但管理单个文件要容易得多) 我(一半)用计算机解决了这个问题
public void populate(Bundle bundle) {
String localisation = (String) bundle.getHeaders().get("Bundle-Localization");
Locale locale = Locale.getDefault();
populate(bundle.getEntry(getFileName(localisation)));
populate(bundle.getEntry(getFileName(localisation, locale.getLanguage())));
populate(bundle.getEntry(getFileName(localisation, locale.getLanguage(), locale.getCountry())));
populate(bundle.getResource(getFileName("fragment")));
populate(bundle.getResource(getFileName("fragment", locale.getLanguage())));
populate(bundle.getResource(getFileName("fragment", locale.getLanguage(), locale.getCountry())));
}
只需将我的片段本地化文件名命名为“fragment.properties”
这不是特别优雅,但它很有效
顺便说一下,要从片段中获取文件,您需要getResource,片段文件似乎位于类路径上,或者仅在使用getResource时才被搜索
如果有人有更好的方法,请纠正我
祝你一切顺利
标记。/**
*被黑客入侵的NLS(国家语言支持)系统。
*
*辛格尔顿。
*
*@作者mima
*/
公开期末班{
私有静态最终HackedNLS实例=新HackedNLS();
私人最终地图翻译;
私有最终集知识缺失;
/**
*创建NLS单例。
*/
私人电脑{
translations=新HashMap();
knownMissing=newhashset();
}
/**
*填充当前区域设置的NLS键/值对。
*
*插件本地化文件可以有任何名称,只要它在下面的清单中声明
*包定位键。
*
*片段必须使用基名称“fragment”定义其本地化。
*这是因为我无法访问
*碎片。
*这可能会改变。
*
*@param bundle用于填充的bundle。
*/
公共空白填充(包){
String baseName=(String)bundle.getHeaders().get(“bundle本地化”);
填充(getLocalizedEntry(baseName,bundle));
填充(getLocalizedEntry(“片段”,bundle));
}
私有URL getLocalizedEntry(字符串baseName,Bundle){
Locale=Locale.getDefault();
URL entry=bundle.getEntry(getFileName(baseName,locale.getLanguage(),locale.getCountry());
if(条目==null){
entry=bundle.getResource(getFileName(baseName,locale.getLanguage(),locale.getCountry());
}
if(条目==null){
entry=bundle.getEntry(getFileName(baseName,locale.getLanguage());
}
if(条目==null){
entry=bundle.getResource(getFileName(baseName,locale.getLanguage());
}
if(条目==null){
entry=bundle.getEntry(getFileName(baseName));
}
if(条目==null){
entry=bundle.getResource(getFileName(baseName));
}
返回条目;
}
私有字符串getFileName(字符串基名称、字符串…参数){
字符串名称=基本名称;
for(int index=0;index/**
* The Hacked NLS (National Language Support) system.
* <p>
* Singleton.
*
* @author mima
*/
public final class HackedNLS {
private static final HackedNLS instance = new HackedNLS();
private final Map<String, String> translations;
private final Set<String> knownMissing;
/**
* Create the NLS singleton.
*/
private HackedNLS() {
translations = new HashMap<String, String>();
knownMissing = new HashSet<String>();
}
/**
* Populates the NLS key/value pairs for the current locale.
* <p>
* Plugin localization files may have any name as long as it is declared in the Manifest under
* the Bundle-Localization key.
* <p>
* Fragments <b>MUST</b> define their localization using the base name 'fragment'.
* This is due to the fact that I have no access to the Bundle-Localization key for the
* fragment.
* This may change.
*
* @param bundle The bundle to use for population.
*/
public void populate(Bundle bundle) {
String baseName = (String) bundle.getHeaders().get("Bundle-Localization");
populate(getLocalizedEntry(baseName, bundle));
populate(getLocalizedEntry("fragment", bundle));
}
private URL getLocalizedEntry(String baseName, Bundle bundle) {
Locale locale = Locale.getDefault();
URL entry = bundle.getEntry(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
if (entry == null) {
entry = bundle.getResource(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
}
if (entry == null) {
entry = bundle.getEntry(getFileName(baseName, locale.getLanguage()));
}
if (entry == null) {
entry = bundle.getResource(getFileName(baseName, locale.getLanguage()));
}
if (entry == null) {
entry = bundle.getEntry(getFileName(baseName));
}
if (entry == null) {
entry = bundle.getResource(getFileName(baseName));
}
return entry;
}
private String getFileName(String baseName, String...arguments) {
String name = baseName;
for (int index = 0; index < arguments.length; index++) {
name += "_" + arguments[index];
}
return name + ".properties";
}
private void populate(URL resourceUrl) {
if (resourceUrl != null) {
Properties props = new Properties();
InputStream stream = null;
try {
stream = resourceUrl.openStream();
props.load(stream);
} catch (IOException e) {
warn("Could not open the resource file " + resourceUrl, e);
} finally {
try {
stream.close();
} catch (IOException e) {
warn("Could not close stream for resource file " + resourceUrl, e);
}
}
for (Object key : props.keySet()) {
translations.put((String) key, (String) props.get(key));
}
}
}
/**
* @param key The key to translate.
* @param arguments Array of arguments to format into the translated text. May be empty.
* @return The formatted translated string.
*/
public String getTranslated(String key, Object...arguments) {
String translation = translations.get(key);
if (translation != null) {
if (arguments != null) {
translation = MessageFormat.format(translation, arguments);
}
} else {
translation = "!! " + key;
if (!knownMissing.contains(key)) {
warn("Could not find any translation text for " + key, null);
knownMissing.add(key);
}
}
return translation;
}
private void warn(String string, Throwable cause) {
Status status;
if (cause == null) {
status = new Status(
IStatus.ERROR,
MiddlewareActivator.PLUGIN_ID,
string);
} else {
status = new Status(
IStatus.ERROR,
MiddlewareActivator.PLUGIN_ID,
string,
cause);
}
MiddlewareActivator.getDefault().getLog().log(status);
}
/**
* @return The NLS instance.
*/
public static HackedNLS getInstance() {
return instance;
}
/**
* @param key The key to translate.
* @param arguments Array of arguments to format into the translated text. May be empty.
* @return The formatted translated string.
*/
public static String getText(String key, Object...arguments) {
return getInstance().getTranslated(key, arguments);
}
}