Polishing
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,12 +29,11 @@ import java.util.Set;
|
||||
*/
|
||||
public class CompositePropertySource extends PropertySource<Object> {
|
||||
|
||||
private Set<PropertySource<?>> propertySources = new LinkedHashSet<PropertySource<?>>();
|
||||
private final Set<PropertySource<?>> propertySources = new LinkedHashSet<PropertySource<?>>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code CompositePropertySource}.
|
||||
*
|
||||
* @param name the name of the property source
|
||||
*/
|
||||
public CompositePropertySource(String name) {
|
||||
@@ -60,6 +59,7 @@ public class CompositePropertySource extends PropertySource<Object> {
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s [name='%s', propertySources=%s]",
|
||||
this.getClass().getSimpleName(), this.name, this.propertySources);
|
||||
getClass().getSimpleName(), this.name, this.propertySources);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,15 +66,15 @@ import org.springframework.util.xml.StaxUtils;
|
||||
*/
|
||||
public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
|
||||
/** Logger available to subclasses. */
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private boolean processExternalEntities = false;
|
||||
|
||||
private DocumentBuilderFactory documentBuilderFactory;
|
||||
|
||||
private final Object documentBuilderFactoryMonitor = new Object();
|
||||
|
||||
private boolean processExternalEntities = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether external XML entities are processed when unmarshalling.
|
||||
@@ -89,17 +89,62 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the configured value for whether XML external entities are allowed.
|
||||
* Returns the configured value for whether XML external entities are allowed.
|
||||
* @see #createXmlReader()
|
||||
*/
|
||||
public boolean isProcessExternalEntities() {
|
||||
return this.processExternalEntities;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the default encoding to use for marshalling or unmarshalling from
|
||||
* a byte stream, or {@code null}.
|
||||
* Create a {@code DocumentBuilder} that this marshaller will use for creating
|
||||
* DOM documents when passed an empty {@code DOMSource}.
|
||||
* <p>The resulting {@code DocumentBuilderFactory} is cached, so this method
|
||||
* will only be called once.
|
||||
* @return the DocumentBuilderFactory
|
||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||
*/
|
||||
abstract protected String getDefaultEncoding();
|
||||
protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setNamespaceAware(true);
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code DocumentBuilder} that this marshaller will use for creating
|
||||
* DOM documents when passed an empty {@code DOMSource}.
|
||||
* <p>Can be overridden in subclasses, adding further initialization of the builder.
|
||||
* @param factory the {@code DocumentBuilderFactory} that the DocumentBuilder should be created with
|
||||
* @return the {@code DocumentBuilder}
|
||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||
*/
|
||||
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
|
||||
throws ParserConfigurationException {
|
||||
|
||||
return factory.newDocumentBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@code XMLReader} that this marshaller will when passed an empty {@code SAXSource}.
|
||||
* @return the XMLReader
|
||||
* @throws SAXException if thrown by JAXP methods
|
||||
*/
|
||||
protected XMLReader createXmlReader() throws SAXException {
|
||||
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
||||
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
return xmlReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the default encoding to use for marshalling or unmarshalling from
|
||||
* a byte stream, or {@code null} if none.
|
||||
*/
|
||||
protected abstract String getDefaultEncoding();
|
||||
|
||||
|
||||
// Marshalling
|
||||
|
||||
/**
|
||||
* Marshals the object graph with the given root into the provided {@code javax.xml.transform.Result}.
|
||||
@@ -133,85 +178,10 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals the given provided {@code javax.xml.transform.Source} into an object graph.
|
||||
* <p>This implementation inspects the given result, and calls {@code unmarshalDomSource},
|
||||
* {@code unmarshalSaxSource}, or {@code unmarshalStreamSource}.
|
||||
* @param source the source to marshal from
|
||||
* @return the object graph
|
||||
* @throws IOException if an I/O Exception occurs
|
||||
* @throws XmlMappingException if the given source cannot be mapped to an object
|
||||
* @throws IllegalArgumentException if {@code source} is neither a {@code DOMSource},
|
||||
* a {@code SAXSource}, nor a {@code StreamSource}
|
||||
* @see #unmarshalDomSource(javax.xml.transform.dom.DOMSource)
|
||||
* @see #unmarshalSaxSource(javax.xml.transform.sax.SAXSource)
|
||||
* @see #unmarshalStreamSource(javax.xml.transform.stream.StreamSource)
|
||||
*/
|
||||
public final Object unmarshal(Source source) throws IOException, XmlMappingException {
|
||||
if (source instanceof DOMSource) {
|
||||
return unmarshalDomSource((DOMSource) source);
|
||||
}
|
||||
else if (StaxUtils.isStaxSource(source)) {
|
||||
return unmarshalStaxSource(source);
|
||||
}
|
||||
else if (source instanceof SAXSource) {
|
||||
return unmarshalSaxSource((SAXSource) source);
|
||||
}
|
||||
else if (source instanceof StreamSource) {
|
||||
return unmarshalStreamSourceNoExternalEntitities((StreamSource) source);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code DocumentBuilder} that this marshaller will use for creating
|
||||
* DOM documents when passed an empty {@code DOMSource}.
|
||||
* <p>Can be overridden in subclasses, adding further initialization of the builder.
|
||||
* @param factory the {@code DocumentBuilderFactory} that the DocumentBuilder should be created with
|
||||
* @return the {@code DocumentBuilder}
|
||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||
*/
|
||||
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
|
||||
throws ParserConfigurationException {
|
||||
|
||||
return factory.newDocumentBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code DocumentBuilder} that this marshaller will use for creating
|
||||
* DOM documents when passed an empty {@code DOMSource}.
|
||||
* <p>The resulting {@code DocumentBuilderFactory} is cached, so this method
|
||||
* will only be called once.
|
||||
* @return the DocumentBuilderFactory
|
||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||
*/
|
||||
protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setNamespaceAware(true);
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code XMLReader} that this marshaller will when passed an empty {@code SAXSource}.
|
||||
* @return the XMLReader
|
||||
* @throws SAXException if thrown by JAXP methods
|
||||
*/
|
||||
protected XMLReader createXmlReader() throws SAXException {
|
||||
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
||||
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
return xmlReader;
|
||||
}
|
||||
|
||||
|
||||
// Marshalling
|
||||
|
||||
/**
|
||||
* Template method for handling {@code DOMResult}s.
|
||||
* <p>This implementation delegates to {@code marshalDomNode}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param domResult the {@code DOMResult}
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the result
|
||||
* @throws IllegalArgumentException if the {@code domResult} is empty
|
||||
@@ -241,7 +211,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
* <p>This implementation delegates to {@code marshalXMLSteamWriter} or
|
||||
* {@code marshalXMLEventConsumer}, depending on what is contained in the
|
||||
* {@code StaxResult}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param staxResult a Spring {@link org.springframework.util.xml.StaxSource} or JAXP 1.4 {@link StAXSource}
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the result
|
||||
* @throws IllegalArgumentException if the {@code domResult} is empty
|
||||
@@ -266,7 +236,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
/**
|
||||
* Template method for handling {@code SAXResult}s.
|
||||
* <p>This implementation delegates to {@code marshalSaxHandlers}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param saxResult the {@code SAXResult}
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the result
|
||||
* @see #marshalSaxHandlers(Object, org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler)
|
||||
@@ -306,6 +276,38 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
|
||||
// Unmarshalling
|
||||
|
||||
/**
|
||||
* Unmarshals the given provided {@code javax.xml.transform.Source} into an object graph.
|
||||
* <p>This implementation inspects the given result, and calls {@code unmarshalDomSource},
|
||||
* {@code unmarshalSaxSource}, or {@code unmarshalStreamSource}.
|
||||
* @param source the source to marshal from
|
||||
* @return the object graph
|
||||
* @throws IOException if an I/O Exception occurs
|
||||
* @throws XmlMappingException if the given source cannot be mapped to an object
|
||||
* @throws IllegalArgumentException if {@code source} is neither a {@code DOMSource},
|
||||
* a {@code SAXSource}, nor a {@code StreamSource}
|
||||
* @see #unmarshalDomSource(javax.xml.transform.dom.DOMSource)
|
||||
* @see #unmarshalSaxSource(javax.xml.transform.sax.SAXSource)
|
||||
* @see #unmarshalStreamSource(javax.xml.transform.stream.StreamSource)
|
||||
*/
|
||||
public final Object unmarshal(Source source) throws IOException, XmlMappingException {
|
||||
if (source instanceof DOMSource) {
|
||||
return unmarshalDomSource((DOMSource) source);
|
||||
}
|
||||
else if (StaxUtils.isStaxSource(source)) {
|
||||
return unmarshalStaxSource(source);
|
||||
}
|
||||
else if (source instanceof SAXSource) {
|
||||
return unmarshalSaxSource((SAXSource) source);
|
||||
}
|
||||
else if (source instanceof StreamSource) {
|
||||
return unmarshalStreamSourceNoExternalEntitities((StreamSource) source);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method for handling {@code DOMSource}s.
|
||||
* <p>This implementation delegates to {@code unmarshalDomNode}.
|
||||
@@ -388,15 +390,12 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
* Template method for handling {@code StreamSource}s with protection against
|
||||
* the XML External Entity (XXE) processing vulnerability taking into account
|
||||
* the value of the {@link #setProcessExternalEntities(boolean)} property.
|
||||
* <p>
|
||||
* The default implementation wraps the StreamSource as a SAXSource and delegates
|
||||
* <p>The default implementation wraps the StreamSource as a SAXSource and delegates
|
||||
* to {@link #unmarshalSaxSource(javax.xml.transform.sax.SAXSource)}.
|
||||
*
|
||||
* @param streamSource the {@code StreamSource}
|
||||
* @return the object graph
|
||||
* @throws IOException if an I/O exception occurs
|
||||
* @throws XmlMappingException if the given source cannot be mapped to an object
|
||||
*
|
||||
* @see <a href="https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing">XML_External_Entity_(XXE)_Processing</a>
|
||||
*/
|
||||
protected Object unmarshalStreamSourceNoExternalEntitities(StreamSource streamSource)
|
||||
@@ -418,10 +417,10 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
|
||||
/**
|
||||
* Template method for handling {@code StreamSource}s.
|
||||
* <p>As of 3.2.8 and 4.0.2 this method is no longer invoked from
|
||||
* <p>This implementation defers to {@code unmarshalInputStream} or {@code unmarshalReader}.
|
||||
* <p>As of Spring 3.2.8, this method is no longer invoked from
|
||||
* {@link #unmarshal(javax.xml.transform.Source)}. The method invoked instead is
|
||||
* {@link #unmarshalStreamSourceNoExternalEntitities(javax.xml.transform.stream.StreamSource)}.
|
||||
*
|
||||
* @param streamSource the {@code StreamSource}
|
||||
* @return the object graph
|
||||
* @throws IOException if an I/O exception occurs
|
||||
@@ -458,7 +457,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
|
||||
/**
|
||||
* Abstract template method for marshalling the given object to a StAX {@code XMLEventWriter}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param eventWriter the {@code XMLEventWriter} to write to
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
|
||||
*/
|
||||
@@ -474,16 +473,6 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
protected abstract void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter)
|
||||
throws XmlMappingException;
|
||||
|
||||
/**
|
||||
* Abstract template method for marshalling the given object graph to a {@code OutputStream}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param outputStream the {@code OutputStream} to write to
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the writer
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
protected abstract void marshalOutputStream(Object graph, OutputStream outputStream)
|
||||
throws XmlMappingException, IOException;
|
||||
|
||||
/**
|
||||
* Abstract template method for marshalling the given object graph to a SAX {@code ContentHandler}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
@@ -495,6 +484,16 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
|
||||
throws XmlMappingException;
|
||||
|
||||
/**
|
||||
* Abstract template method for marshalling the given object graph to a {@code OutputStream}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
* @param outputStream the {@code OutputStream} to write to
|
||||
* @throws XmlMappingException if the given object cannot be marshalled to the writer
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
protected abstract void marshalOutputStream(Object graph, OutputStream outputStream)
|
||||
throws XmlMappingException, IOException;
|
||||
|
||||
/**
|
||||
* Abstract template method for marshalling the given object graph to a {@code Writer}.
|
||||
* @param graph the root of the object graph to marshal
|
||||
@@ -531,6 +530,18 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
protected abstract Object unmarshalXmlStreamReader(XMLStreamReader streamReader)
|
||||
throws XmlMappingException;
|
||||
|
||||
/**
|
||||
* Abstract template method for unmarshalling using a given SAX {@code XMLReader}
|
||||
* and {@code InputSource}.
|
||||
* @param xmlReader the SAX {@code XMLReader} to parse with
|
||||
* @param inputSource the input source to parse from
|
||||
* @return the object graph
|
||||
* @throws XmlMappingException if the given reader and input source cannot be converted to an object
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
protected abstract Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
|
||||
throws XmlMappingException, IOException;
|
||||
|
||||
/**
|
||||
* Abstract template method for unmarshalling from a given {@code InputStream}.
|
||||
* @param inputStream the {@code InputStreamStream} to read from
|
||||
@@ -551,16 +562,4 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
protected abstract Object unmarshalReader(Reader reader)
|
||||
throws XmlMappingException, IOException;
|
||||
|
||||
/**
|
||||
* Abstract template method for unmarshalling using a given SAX {@code XMLReader}
|
||||
* and {@code InputSource}.
|
||||
* @param xmlReader the SAX {@code XMLReader} to parse with
|
||||
* @param inputSource the input source to parse from
|
||||
* @return the object graph
|
||||
* @throws XmlMappingException if the given reader and input source cannot be converted to an object
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
protected abstract Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
|
||||
throws XmlMappingException, IOException;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user