枚举在 faces-config.xml 中定义的资源包
enumerate resource-bundles defined in faces-config.xml
我正在为此使用特定于 mojarra 的代码:
public static Map<String, ResourceBundle> getBundleMap()
{
Locale locale = Faces.getLocale();
ApplicationAssociate associate = ApplicationAssociate.getCurrentInstance();
Map<String, ApplicationResourceBundle> resourceBundles = associate.getResourceBundles();
Map<String, ResourceBundle> map = new HashMap<>(resourceBundles.size());
for(Entry<String, ApplicationResourceBundle> entry : resourceBundles.entrySet())
{
String name = entry.getKey();
ResourceBundle bundle = entry.getValue().getResourceBundle(locale);
map.put(name, bundle);
}
return map;
}
我想要一种与实现无关的方式来获取这张地图。
我应该解析应用程序和库中定义的每个 faces-config.xml
吗?这不是重新发明轮子吗?
A Map<String, String>
,其中 key = /faces-config/application/resource-bundle/var
和 value = /faces-config/application/resource-bundle/base-name
就足够了。
谢谢。
I'd like to have an implementation-agnostic way to get this map.
可以理解。
Should I parse every faces-config.xml defined in application and libs?
是的。此功能在 JSF API.
中不可用
Isn't this reinventing the wheel?
是的,绝对是。但是,您可以尝试将其放入 OmniFaces, which has already a similar utility class for /WEB-INF/web.xml
and all /META-INF/web-fragment.xml
, the WebXml
.
A Map<String, String>
, where key = /faces-config/application/resource-bundle/var
and value = /faces-config/application/resource-bundle/base-name
would be sufficient.
这是一个使用 JAXP 的启动示例(咳咳):
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
document.appendChild(document.createElement("all-faces-configs"));
List<URL> facesConfigURLs = new ArrayList<>();
facesConfigURLs.add(FacesContext.getCurrentInstance().getExternalContext().getResource("/WEB-INF/faces-config.xml"));
facesConfigURLs.addAll(Collections.list(Thread.currentThread().getContextClassLoader().getResources("META-INF/faces-config.xml")));
for (URL facesConfigURL : facesConfigURLs) {
URLConnection connection = facesConfigURL.openConnection();
connection.setUseCaches(false);
try (InputStream input = connection.getInputStream()) {
NodeList children = builder.parse(input).getDocumentElement().getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
document.getDocumentElement().appendChild(document.importNode(children.item(i), true));
}
}
}
Map<String, String> resourceBundles = new HashMap<>();
Element allFacesConfigs = document.getDocumentElement();
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList resourceBundleNodes = (NodeList) xpath.compile("application/resource-bundle").evaluate(allFacesConfigs, XPathConstants.NODESET);
for (int i = 0; i < resourceBundleNodes.getLength(); i++) {
Node resourceBundleNode = resourceBundleNodes.item(i);
String var = xpath.compile("var").evaluate(resourceBundleNode).trim();
String baseName = xpath.compile("base-name").evaluate(resourceBundleNode).trim();
resourceBundles.put(var, baseName);
}
我正在为此使用特定于 mojarra 的代码:
public static Map<String, ResourceBundle> getBundleMap()
{
Locale locale = Faces.getLocale();
ApplicationAssociate associate = ApplicationAssociate.getCurrentInstance();
Map<String, ApplicationResourceBundle> resourceBundles = associate.getResourceBundles();
Map<String, ResourceBundle> map = new HashMap<>(resourceBundles.size());
for(Entry<String, ApplicationResourceBundle> entry : resourceBundles.entrySet())
{
String name = entry.getKey();
ResourceBundle bundle = entry.getValue().getResourceBundle(locale);
map.put(name, bundle);
}
return map;
}
我想要一种与实现无关的方式来获取这张地图。
我应该解析应用程序和库中定义的每个 faces-config.xml
吗?这不是重新发明轮子吗?
A Map<String, String>
,其中 key = /faces-config/application/resource-bundle/var
和 value = /faces-config/application/resource-bundle/base-name
就足够了。
谢谢。
I'd like to have an implementation-agnostic way to get this map.
可以理解。
Should I parse every faces-config.xml defined in application and libs?
是的。此功能在 JSF API.
中不可用Isn't this reinventing the wheel?
是的,绝对是。但是,您可以尝试将其放入 OmniFaces, which has already a similar utility class for /WEB-INF/web.xml
and all /META-INF/web-fragment.xml
, the WebXml
.
A
Map<String, String>
, where key =/faces-config/application/resource-bundle/var
and value =/faces-config/application/resource-bundle/base-name
would be sufficient.
这是一个使用 JAXP 的启动示例(咳咳):
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
document.appendChild(document.createElement("all-faces-configs"));
List<URL> facesConfigURLs = new ArrayList<>();
facesConfigURLs.add(FacesContext.getCurrentInstance().getExternalContext().getResource("/WEB-INF/faces-config.xml"));
facesConfigURLs.addAll(Collections.list(Thread.currentThread().getContextClassLoader().getResources("META-INF/faces-config.xml")));
for (URL facesConfigURL : facesConfigURLs) {
URLConnection connection = facesConfigURL.openConnection();
connection.setUseCaches(false);
try (InputStream input = connection.getInputStream()) {
NodeList children = builder.parse(input).getDocumentElement().getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
document.getDocumentElement().appendChild(document.importNode(children.item(i), true));
}
}
}
Map<String, String> resourceBundles = new HashMap<>();
Element allFacesConfigs = document.getDocumentElement();
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList resourceBundleNodes = (NodeList) xpath.compile("application/resource-bundle").evaluate(allFacesConfigs, XPathConstants.NODESET);
for (int i = 0; i < resourceBundleNodes.getLength(); i++) {
Node resourceBundleNode = resourceBundleNodes.item(i);
String var = xpath.compile("var").evaluate(resourceBundleNode).trim();
String baseName = xpath.compile("base-name").evaluate(resourceBundleNode).trim();
resourceBundles.put(var, baseName);
}