📄 plutowebxmlrewriter.java
字号:
/*
* 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.pluto.util.descriptors.web;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* @version $Id: PlutoWebXmlRewriter.java 704743 2008-10-15 00:01:07Z ate $
*/
public class PlutoWebXmlRewriter
{
private static final String NAMESPACE_PREFIX = "xp";
private static final String[] ELEMENTS_BEFORE_SERVLET_23 = new String[] { "icon", "display-name", "description",
"distributable", "context-param",
"filter", "filter-mapping", "listener",
"servlet" };
private static final String[] ELEMENTS_BEFORE_SERVLET_MAPPING_23 = new String[] { "icon", "display-name",
"description", "distributable",
"context-param", "filter",
"filter-mapping", "listener",
"servlet", "servlet-mapping" };
private static final String[] ELEMENTS_BEFORE_SERVLET = new String[] { "description", "display-name", "icon",
"distributable", "context-param", "filter",
"filter-mapping", "listener", "servlet" };
private static final String[] ELEMENTS_BEFORE_SERVLET_MAPPING = new String[] { "description", "display-name",
"icon", "distributable",
"context-param", "filter",
"filter-mapping", "listener",
"servlet", "servlet-mapping" };
private static class XPathNamespaceContext implements NamespaceContext
{
private String namespaceURI;
private String prefix;
public XPathNamespaceContext(String prefix)
{
this(prefix,XMLConstants.XML_NS_URI);
}
public XPathNamespaceContext(String prefix, String namespaceURI)
{
this.prefix = prefix;
this.namespaceURI = namespaceURI;
}
public String getNamespaceURI(String prefix)
{
if (prefix == null)
{
throw new NullPointerException("Null prefix");
}
else if (this.prefix.equals(prefix))
{
return namespaceURI;
}
else if ("xml".equals(prefix))
{
return XMLConstants.XML_NS_URI;
}
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespaceURI)
{
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
public Iterator getPrefixes(String namespaceURI)
{
throw new UnsupportedOperationException();
}
}
private Document descriptor;
private String namespace;
private String prefix;
private Element root;
private XPath xpath;
private boolean descriptor23;
public PlutoWebXmlRewriter(Document descriptor)
{
this.descriptor = descriptor;
this.root = descriptor.getDocumentElement();
this.namespace = root.getNamespaceURI();
String version = root.getAttribute("version");
if (version.equals(""))
{
version = "2.3";
}
try
{
// Check version is a valid number
Double.parseDouble(version);
}
catch(NumberFormatException e)
{
throw new RuntimeException("Unable to create Determine wew.xml version: " + version, e);
}
descriptor23 = version.equals("2.3");
if (!descriptor23 && version.compareTo("2.3") < 0)
{
throw new RuntimeException("Unsupported (too old?) web.xml version: "+version);
}
xpath = XPathFactory.newInstance().newXPath();
if(namespace!= null && namespace.length() > 0)
{
prefix = NAMESPACE_PREFIX+":";
xpath.setNamespaceContext(new XPathNamespaceContext(NAMESPACE_PREFIX, namespace));
}
else
{
prefix = XMLConstants.DEFAULT_NS_PREFIX;
xpath.setNamespaceContext(new XPathNamespaceContext(XMLConstants.DEFAULT_NS_PREFIX));
}
}
public PlutoWebXmlRewriter(InputStream source) throws Exception
{
this(parseXml(source));
}
protected static Document parseXml(InputStream source) throws Exception
{
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
builder.setEntityResolver(new EntityResolver()
{
public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId) throws SAXException,
java.io.IOException
{
if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd"))
{
return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd"));
}
return null;
}
});
Document document = builder.parse(source);
return document;
}
/**
*
* <p>
* insertElementCorrectly
* </p>
*
* @param root
* element representing the < web-app >
* @param toInsert
* element to insert into the web.xml hierarchy.
* @param elementsBefore
* an array of web.xml elements that should be defined before the
* element we want to insert. This order should be the order
* defined by the web.xml's DTD or XSD type definition.
*/
protected static void insertElementCorrectly( Element root, Element toInsert, String[] elementsBefore )
{
NodeList allChildren = root.getChildNodes();
List<String> elementsBeforeList = Arrays.asList(elementsBefore);
Node insertBefore = null;
for (int i = 0; i < allChildren.getLength(); i++)
{
Node node = allChildren.item(i);
if (insertBefore == null)
{
insertBefore = node;
}
if (node.getNodeType() == Node.ELEMENT_NODE)
{
if (elementsBeforeList.contains(node.getNodeName()))
{
insertBefore = null;
}
else
{
break;
}
}
}
if (insertBefore == null)
{
root.appendChild(toInsert);
}
else
{
root.insertBefore(toInsert, insertBefore);
}
}
public boolean is23Descriptor()
{
return descriptor23;
}
public boolean hasServlets()
{
Object result = null;
try
{
result = xpath.evaluate("/"+prefix+"web-app/"+prefix+"servlet", descriptor, XPathConstants.NODESET);
}
catch (XPathExpressionException e)
{
throw new RuntimeException(e);
}
return result != null ? ((NodeList)result).getLength() > 0 : false;
}
public boolean hasServletMappings()
{
Object result = null;
try
{
result = xpath.evaluate("/"+prefix+"web-app/"+prefix+"servlet-mapping", descriptor, XPathConstants.NODESET);
}
catch (XPathExpressionException e)
{
throw new RuntimeException(e);
}
return result != null ? ((NodeList)result).getLength() > 0 : false;
}
public String getServletClass(String servletName)
{
Object result = null;
try
{
result = xpath.evaluate("/"+prefix+"web-app/"+prefix+"servlet["+prefix+"servlet-name='"+servletName+"']/"+prefix+"servlet-class/text()", descriptor, XPathConstants.STRING);
}
catch (XPathExpressionException e)
{
throw new RuntimeException(e);
}
return result != null ? (String)result : null;
}
public void injectPortletServlet(String className, String name)
{
Element servlet = descriptor.createElementNS(namespace, "servlet");
Element servletName = descriptor.createElementNS(namespace, "servlet-name");
servletName.setTextContent(name);
Element servletClass = descriptor.createElementNS(namespace, "servlet-class");
servletClass.setTextContent(className);
servlet.appendChild(servletName);
servlet.appendChild(servletClass);
Element init2Param = descriptor.createElementNS(namespace, "init-param");
Element param2Name = descriptor.createElementNS(namespace, "param-name");
param2Name.setTextContent("portlet-name");
Element param2Value = descriptor.createElementNS(namespace, "param-value");
param2Value.setTextContent(name);
init2Param.appendChild(param2Name);
init2Param.appendChild(param2Value);
servlet.appendChild(init2Param);
Element loadOnStartup = descriptor.createElementNS(namespace, "load-on-startup");
loadOnStartup.setTextContent("1");
servlet.appendChild(loadOnStartup);
insertElementCorrectly(root, servlet, descriptor23 ? ELEMENTS_BEFORE_SERVLET_23 : ELEMENTS_BEFORE_SERVLET);
Element servletMappingElement = descriptor.createElementNS(namespace, "servlet-mapping");
Element servletMapName = descriptor.createElementNS(namespace, "servlet-name");
servletMapName.setTextContent(name);
Element servletUrlPattern = descriptor.createElementNS(namespace, "url-pattern");
servletUrlPattern.setTextContent("/PlutoInvoker/"+name);
servletMappingElement.appendChild(servletMapName);
servletMappingElement.appendChild(servletUrlPattern);
insertElementCorrectly(root, servletMappingElement, descriptor23 ? ELEMENTS_BEFORE_SERVLET_MAPPING_23 : ELEMENTS_BEFORE_SERVLET_MAPPING);
}
public void write(OutputStream dest) throws IOException
{
try
{
DOMSource domSource = new DOMSource(descriptor);
StreamResult streamResult = new StreamResult(dest);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
if (descriptor.getDoctype() != null)
{
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, descriptor.getDoctype().getPublicId());
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, descriptor.getDoctype().getSystemId());
}
transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(domSource, streamResult);
}
catch (TransformerConfigurationException e)
{
throw new IOException(e.getMessage());
}
catch (TransformerException e)
{
throw new IOException(e.getMessage());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -