在蚀RCP plugin.properties机构
题
我的项目包括多个插件,每个插件包括plugin.properties近文件到20名的翻译。 MANIFEST.MF文件定义了外部插件字符串存储在属性文件的名称。
Bundle-Localization: plugin
插件我喜欢定义
的名称%plugin.name
Eclipse将搜索在plugin.properties文件中的 “%plugin.name” 在运行时。
哪些类读出的MANIFEST.MF捆定位条目和在该点是与起始“%”后缀字符串中搜索在“plugin.properties”文件?
我想找到并以这种方式修补这些类,我可以先考虑一些其他的目录/文件为“%plugin.name”标识。有了这些新的机制,我可以添加片段到我的产品,并覆盖在“plugin.properties”文件单线路不改变原有的插件。 有了这些机制,我可以通过添加不同的片段创建多个客户构建过程。这些片段包括客户名称和特殊字符串他们想改变。
我想这样做的,因为碎片机制只将文件添加到原来的插件。当“plugin.properties”文件是在现有的插件,该片段“plugin.properties”文件将被忽略。
<强>更新1:强>
方法
class ManifestLocalization{
...
protected ResourceBundle getResourceBundle(String localeString) {
}
...
}
返回的属性的文件的ResourceBundle为给定区域字符串。 当有人NOW的我怎么可以现在先看看片段,以获得资源的路径,请张贴。
<强>更新2:强>
类ManifestLocalization的方法
private URL findInResolved(String filePath, AbstractBundle bundleHost) {
URL result = findInBundle(filePath, bundleHost);
if (result != null)
return result;
return findInFragments(filePath, bundleHost);
}
搜寻SEARCH_TERM_EXAMPLES属性文件,并将它缓存。翻译可以从缓存的文件比得到的。问题是,该完整的文件被缓存,而不是单一的翻译。
一个解决办法是首先读取片段文件,比读取束文件。当这两个文件是现有的将它们合并到一个文件,并写入新的属性文件到磁盘。新的属性的URL文件的回报,以使新的propetries文件可以被高速缓存。
解决方案
虽然我得到的信息错误......我有完全相同的问题。该插件不被激活两次,我不能得到的片段束定位键。
我想在plugin.properties我所有的语言翻译(我知道这是令人难以接受的,但它是非常容易管理单个文件)。
I(一半)通过使用解决了这个问题
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时才被搜索。
如果有人有更好的办法,请大家指正。
所有最好的,
标记。
其他提示
/**
* 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);
}
}
更改片段plugin.properties的名称到别的东西如。 fragment.properties
在您的片段清单改变 束定位:插件 至 捆位置:片段
您的插件将使用plugin.properties,第二使用fragment.properties被激活两次,第一次。
插件激活由OSGi运行春分处理。不过我强烈劝阻试图修补任何文件有创建特定的行为。马克建议的方式似乎更理智的方式,您的问题。
的一个方法是附加一个束听者,并侦听束(或许还看已经安装束)和安装用于每个束生成/提供 - 并安装 - 与想要的属性文件的片段。如果应用程序启动之前做到这一点,这应该有效果。