All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.util.file.WebXmlFile Maven / Gradle / Ivy

There is a newer version: 10.1.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.util.file;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.wicket.util.xml.CustomEntityResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * A utility class providing helper methods in dealing with web.xml
 * 
 * @author jcompagner
 * @author Juergen Donnerstag
 */
public class WebXmlFile
{
	private static final Logger log = LoggerFactory.getLogger(WebXmlFile.class);

	/**
	 * Construct.
	 */
	public WebXmlFile()
	{
	}

	/**
	 * Gets unique Wicket filter path via FilterConfig
	 * 
	 * @param isServlet
	 *            true if Servlet, false if Filter
	 * @param filterConfig
	 * @return Filter path retrieved from "url-pattern". Null if not found or error occurred
	 */
	public final String getUniqueFilterPath(final boolean isServlet, final FilterConfig filterConfig)
	{
		String filterName = filterConfig.getFilterName();
		Set paths = getFilterPath(isServlet, filterConfig.getServletContext(), filterName);
		return uniquePath(paths, isServlet, filterName);
	}

	/**
	 * Gets Wicket filter path via ServletContext and the filter name
	 * 
	 * @param isServlet
	 *            true if Servlet, false if Filter
	 * @param servletContext
	 * @param filterName
	 * @return Filter paths retrieved from "url-pattern"
	 */
	public final Set getFilterPath(final boolean isServlet,
		final ServletContext servletContext, final String filterName)
	{
		InputStream is = servletContext.getResourceAsStream("/WEB-INF/web.xml");
		if (is != null)
		{
			try
			{
				return getFilterPath(isServlet, filterName, is);
			}
			catch (ParserConfigurationException | SAXException | IOException ex)
			{
				log.error("Error reading servlet/filter path from web.xml", ex);
			}
			catch (SecurityException e)
			{
				// Swallow this at INFO.
				log.info("Couldn't read web.xml to automatically pick up servlet/filter path: " +
					e.getMessage());
			}
		}
		return Collections.emptySet();
	}

	/**
	 * Gets unique filter path via filter name and InputStream.
	 * 
	 * @param isServlet
	 *            true if Servlet, false if Filter
	 * @param filterName
	 * @param is
	 *            The web.xml file
	 * @return Filter path retrieved from "url-pattern". Null if not found.
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 * 
	 * @see #getFilterPath(boolean, String, java.io.InputStream)
	 */
	public final String getUniqueFilterPath(final boolean isServlet, final String filterName,
		final InputStream is) throws ParserConfigurationException, SAXException, IOException
	{
		return uniquePath(getFilterPath(isServlet, filterName, is), isServlet, filterName);
	}

	/**
	 * return unique path from set of paths
	 * 
	 * @param paths
	 *            null if set was empty, unique path if set was of length == 1
	 * @param isServlet
	 * @param filterName
	 * @return unique path
	 * @throws RuntimeException
	 *             in case length > 1
	 */
	private String uniquePath(final Set paths, final boolean isServlet,
		final String filterName)
	{
		if (paths.size() > 1)
		{
			StringBuilder err = new StringBuilder();
			err.append("web.xml: expected one ");
			err.append(isServlet ? "servlet" : "filter");
			err.append(" path for [");
			err.append(filterName);
			err.append("] but found multiple:");

			for (String path : paths)
			{
				err.append(" [").append(path).append(']');
			}
			throw new RuntimeException(err.toString());
		}

		if (paths.size() == 1)
		{
			return paths.iterator().next();
		}
		return null;
	}

	/**
	 * Gets Wicket filter path via filter name and InputStream. The InputStream is assumed to be an
	 * web.xml file.
	 * 

* A typical Wicket web.xml entry looks like: * *

	 * 
	 * <filter>
	 *   <filter-name>HelloWorldApplication</filter-name>
	 *   <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
	 *   <init-param>
	 *     <param-name>applicationClassName</param-name>
	 *     <param-value>org.apache.wicket.examples.helloworld.HelloWorldApplication</param-value>
	 *   </init-param>
	 * </filter>
	 * 
	 * <filter-mapping>
	 *   <filter-name>HelloWorldApplication</filter-name>
	 *   <url-pattern>/helloworld/*</url-pattern>
	 *   <dispatcher>REQUEST</dispatcher>
	 *   <dispatcher>INCLUDE</dispatcher>
	 * </filter-mapping>
	 * 
	 * 
* * @param isServlet * true if Servlet, false if Filter * @param filterName * @param is * The web.xml file * @return Filter paths retrieved from "url-pattern". * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public final Set getFilterPath(final boolean isServlet, final String filterName, final InputStream is) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // try to pull DTD from local set of entities builder.setEntityResolver(CustomEntityResolver.getPreloaded()); Document document = builder.parse(is); String tag = (isServlet ? "servlet" : "filter"); String mapping = tag + "-mapping"; String name = tag + "-name"; Set urlPatterns = getFilterPaths(filterName, mapping, name, document.getChildNodes()); if (urlPatterns.size() == 0) { log.warn("web.xml: No url-pattern found for '{}' with name '{}'", tag, filterName); } if (log.isInfoEnabled()) { StringBuilder msg = new StringBuilder(); msg.append("web.xml: url mapping found for ") .append(tag) .append(" with name ") .append(filterName) .append(':'); for (String urlPattern : urlPatterns) { msg.append(" ["); msg.append(urlPattern); msg.append(']'); } log.info(msg.toString()); } Set stripped = new HashSet<>(urlPatterns.size()); for (String urlPattern : urlPatterns) { stripped.add(urlPattern.substring(1, urlPattern.length() - 1)); } return stripped; } /** * Iterate through all children of 'node' and search for a node with name "filterName". Return * the value of node "url-pattern" if "filterName" was found. * * @param filterName * @param name * @param node * @return value of node "url-pattern" */ private Set getFilterPaths(final String filterName, final String name, final Node node) { Set paths = new HashSet<>(); String foundUrlPattern = null; String foundFilterName = null; for (int i = 0; i < node.getChildNodes().getLength(); ++i) { Node n = node.getChildNodes().item(i); if (name.equals(n.getNodeName())) { foundFilterName = n.getTextContent(); } else if ("url-pattern".equals(n.getNodeName())) { foundUrlPattern = n.getTextContent(); } if (foundFilterName != null) { foundFilterName = foundFilterName.trim(); } if (filterName.equals(foundFilterName)) { if (foundUrlPattern != null) { paths.add(foundUrlPattern.trim()); } } } return paths; } /** * Find a node with name 'mapping' within 'nodeList' and if found continue to search amongst its * children for a node with 'filterName' and "url-pattern' * * * @param filterName * @param mapping * @param name * @param nodeList * @return The value assigned to node "url-pattern" */ private Set getFilterPaths(final String filterName, final String mapping, final String name, final NodeList nodeList) { Set paths = new HashSet<>(1); for (int i = 0; i < nodeList.getLength(); ++i) { Node node = nodeList.item(i); if (mapping.equals(node.getNodeName())) { paths.addAll(getFilterPaths(filterName, name, node)); } else { paths.addAll(getFilterPaths(filterName, mapping, name, node.getChildNodes())); } } return paths; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy