枚举在 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/varvalue = /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);
}