All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.primefaces.config.WebXmlParser Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright (c) 2009-2023 PrimeTek Informatics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.primefaces.config;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.primefaces.util.LangUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class WebXmlParser {
private static final Logger LOGGER = Logger.getLogger(WebXmlParser.class.getName());
private static final String ERROR_PAGE_EXCEPTION_TYPE_EXPRESSION = "*[local-name() = 'error-page']/*[local-name() = 'exception-type']";
private static final String LOCATION_EXPRESSION = "*[local-name() = 'location']";
private static final String ERROR_CODE_500_LOCATION_EXPRESSION =
"*[local-name() = 'error-page'][*[local-name() = 'error-code'] = '500'] / *[local-name() = 'location']";
private static final String ERROR_PAGE_NO_CODE_AND_TYPE_EXPRESSION = "*[local-name() = 'error-page'][not(*[local-name() = 'error-code']) and not" +
"(*[local-name() = 'exception-type'])]/*[local-name() = 'location']";
private WebXmlParser() {
}
public static Map getErrorPages(FacesContext context) {
Map webXmlErrorPages = getWebXmlErrorPages(context);
Map webFragmentXmlsErrorPages = getWebFragmentXmlsErrorPages(context);
Map errorPages = webXmlErrorPages;
if (errorPages == null) {
errorPages = webFragmentXmlsErrorPages;
}
else if (webFragmentXmlsErrorPages != null) {
for (Map.Entry entry : webFragmentXmlsErrorPages.entrySet()) {
if (!errorPages.containsKey(entry.getKey())) {
errorPages.put(entry.getKey(), entry.getValue());
}
}
}
if (errorPages == null) {
errorPages = new HashMap<>();
}
return errorPages;
}
private static Map getWebXmlErrorPages(FacesContext context) {
try {
Document webXml = toDocument(context.getExternalContext().getResource("/WEB-INF/web.xml"));
if (webXml == null) {
// Quarkus
webXml = toDocument(LangUtils.getCurrentClassLoader(WebXmlParser.class).getResource("META-INF/web.xml"));
}
if (webXml != null) {
return parseErrorPages(webXml.getDocumentElement());
}
}
catch (Exception e) {
LOGGER.log(Level.SEVERE, "Could not load or parse web.xml", e);
}
return null;
}
private static Map getWebFragmentXmlsErrorPages(FacesContext context) {
Map webFragmentXmlsErrorPages = null;
try {
Enumeration webFragments = LangUtils.getContextClassLoader().getResources("META-INF/web-fragment.xml");
while (webFragments.hasMoreElements()) {
try {
URL url = webFragments.nextElement();
Document webFragmentXml = toDocument(url);
if (webFragmentXml != null) {
if (webFragmentXmlsErrorPages == null) {
webFragmentXmlsErrorPages = parseErrorPages(webFragmentXml.getDocumentElement());
}
else {
Map temp = parseErrorPages(webFragmentXml.getDocumentElement());
for (Map.Entry entry : temp.entrySet()) {
if (!webFragmentXmlsErrorPages.containsKey(entry.getKey())) {
webFragmentXmlsErrorPages.put(entry.getKey(), entry.getValue());
}
}
}
}
}
catch (Exception e) {
LOGGER.log(Level.SEVERE, "Could not load or parse web-fragment.xml", e);
}
}
}
catch (IOException e) {
LOGGER.log(Level.SEVERE, "Could not get web-fragment.xml from ClassLoader", e);
}
return webFragmentXmlsErrorPages;
}
private static Document toDocument(URL url) throws IOException, SAXException, ParserConfigurationException {
// web.xml is optional
if (url == null) {
return null;
}
try (InputStream is = url.openStream()) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
factory.setExpandEntityReferences(false);
try {
factory.setFeature("http://xml.org/sax/features/namespaces", false);
factory.setFeature("http://xml.org/sax/features/validation", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
}
catch (Throwable e) {
LOGGER.warning("DocumentBuilderFactory#setFeature not implemented. Skipping...");
}
boolean absolute = false;
try {
absolute = url.toURI().isAbsolute();
}
catch (URISyntaxException e) {
// noop
}
DocumentBuilder builder = factory.newDocumentBuilder();
Document document;
if (absolute) {
InputSource source = new InputSource(url.toExternalForm());
source.setByteStream(is);
document = builder.parse(source);
}
else {
document = builder.parse(is);
}
return document;
}
}
private static Map parseErrorPages(Element webXml) throws XPathExpressionException {
Map errorPages = new HashMap<>();
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList exceptionTypes = (NodeList) xpath.compile(ERROR_PAGE_EXCEPTION_TYPE_EXPRESSION).evaluate(webXml, XPathConstants.NODESET);
for (int i = 0; i < exceptionTypes.getLength(); i++) {
Node node = exceptionTypes.item(i);
String exceptionType = node.getTextContent().trim();
String key = Throwable.class.getName().equals(exceptionType) ? null : exceptionType;
String location = xpath.compile(LOCATION_EXPRESSION).evaluate(node.getParentNode()).trim();
if (!errorPages.containsKey(key)) {
errorPages.put(key, location);
}
}
if (!errorPages.containsKey(null)) {
String defaultLocation = xpath.compile(ERROR_CODE_500_LOCATION_EXPRESSION).evaluate(webXml).trim();
if (LangUtils.isBlank(defaultLocation)) {
defaultLocation = xpath.compile(ERROR_PAGE_NO_CODE_AND_TYPE_EXPRESSION).evaluate(webXml).trim();
}
if (LangUtils.isNotBlank(defaultLocation)) {
errorPages.put(null, defaultLocation);
}
}
return errorPages;
}
}