keycloakjar.org.springframework.util.xml.StaxStreamXMLReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of camunda-bpm-identity-keycloak-all Show documentation
Show all versions of camunda-bpm-identity-keycloak-all Show documentation
Camunda Keycloak Identity Provider Plugin including all transitive dependencies
The newest version!
/*
* Copyright 2002-2020 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.
* You may obtain a copy of the License at
*
* https://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.springframework.util.xml;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Locator2;
import org.xml.sax.helpers.AttributesImpl;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* SAX {@code XMLReader} that reads from a StAX {@code XMLStreamReader}. Reads from an
* {@code XMLStreamReader}, and calls the corresponding methods on the SAX callback interfaces.
*
* @author Arjen Poutsma
* @since 3.0
* @see XMLStreamReader
* @see #setContentHandler(org.xml.sax.ContentHandler)
* @see #setDTDHandler(org.xml.sax.DTDHandler)
* @see #setEntityResolver(org.xml.sax.EntityResolver)
* @see #setErrorHandler(org.xml.sax.ErrorHandler)
*/
class StaxStreamXMLReader extends AbstractStaxXMLReader {
private static final String DEFAULT_XML_VERSION = "1.0";
private final XMLStreamReader reader;
private String xmlVersion = DEFAULT_XML_VERSION;
@Nullable
private String encoding;
/**
* Construct a new instance of the {@code StaxStreamXmlReader} that reads from the given
* {@code XMLStreamReader}. The supplied stream reader must be in {@code XMLStreamConstants.START_DOCUMENT}
* or {@code XMLStreamConstants.START_ELEMENT} state.
* @param reader the {@code XMLEventReader} to read from
* @throws IllegalStateException if the reader is not at the start of a document or element
*/
StaxStreamXMLReader(XMLStreamReader reader) {
int event = reader.getEventType();
if (!(event == XMLStreamConstants.START_DOCUMENT || event == XMLStreamConstants.START_ELEMENT)) {
throw new IllegalStateException("XMLEventReader not at start of document or element");
}
this.reader = reader;
}
@Override
protected void parseInternal() throws SAXException, XMLStreamException {
boolean documentStarted = false;
boolean documentEnded = false;
int elementDepth = 0;
int eventType = this.reader.getEventType();
while (true) {
if (eventType != XMLStreamConstants.START_DOCUMENT && eventType != XMLStreamConstants.END_DOCUMENT &&
!documentStarted) {
handleStartDocument();
documentStarted = true;
}
switch (eventType) {
case XMLStreamConstants.START_ELEMENT:
elementDepth++;
handleStartElement();
break;
case XMLStreamConstants.END_ELEMENT:
elementDepth--;
if (elementDepth >= 0) {
handleEndElement();
}
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION:
handleProcessingInstruction();
break;
case XMLStreamConstants.CHARACTERS:
case XMLStreamConstants.SPACE:
case XMLStreamConstants.CDATA:
handleCharacters();
break;
case XMLStreamConstants.START_DOCUMENT:
handleStartDocument();
documentStarted = true;
break;
case XMLStreamConstants.END_DOCUMENT:
handleEndDocument();
documentEnded = true;
break;
case XMLStreamConstants.COMMENT:
handleComment();
break;
case XMLStreamConstants.DTD:
handleDtd();
break;
case XMLStreamConstants.ENTITY_REFERENCE:
handleEntityReference();
break;
}
if (this.reader.hasNext() && elementDepth >= 0) {
eventType = this.reader.next();
}
else {
break;
}
}
if (!documentEnded) {
handleEndDocument();
}
}
private void handleStartDocument() throws SAXException {
if (XMLStreamConstants.START_DOCUMENT == this.reader.getEventType()) {
String xmlVersion = this.reader.getVersion();
if (StringUtils.hasLength(xmlVersion)) {
this.xmlVersion = xmlVersion;
}
this.encoding = this.reader.getCharacterEncodingScheme();
}
ContentHandler contentHandler = getContentHandler();
if (contentHandler != null) {
final Location location = this.reader.getLocation();
contentHandler.setDocumentLocator(new Locator2() {
@Override
public int getColumnNumber() {
return (location != null ? location.getColumnNumber() : -1);
}
@Override
public int getLineNumber() {
return (location != null ? location.getLineNumber() : -1);
}
@Override
@Nullable
public String getPublicId() {
return (location != null ? location.getPublicId() : null);
}
@Override
@Nullable
public String getSystemId() {
return (location != null ? location.getSystemId() : null);
}
@Override
public String getXMLVersion() {
return xmlVersion;
}
@Override
@Nullable
public String getEncoding() {
return encoding;
}
});
contentHandler.startDocument();
if (this.reader.standaloneSet()) {
setStandalone(this.reader.isStandalone());
}
}
}
private void handleStartElement() throws SAXException {
if (getContentHandler() != null) {
QName qName = this.reader.getName();
if (hasNamespacesFeature()) {
for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
startPrefixMapping(this.reader.getNamespacePrefix(i), this.reader.getNamespaceURI(i));
}
for (int i = 0; i < this.reader.getAttributeCount(); i++) {
String prefix = this.reader.getAttributePrefix(i);
String namespace = this.reader.getAttributeNamespace(i);
if (StringUtils.hasLength(namespace)) {
startPrefixMapping(prefix, namespace);
}
}
getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(),
toQualifiedName(qName), getAttributes());
}
else {
getContentHandler().startElement("", "", toQualifiedName(qName), getAttributes());
}
}
}
private void handleEndElement() throws SAXException {
if (getContentHandler() != null) {
QName qName = this.reader.getName();
if (hasNamespacesFeature()) {
getContentHandler().endElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName));
for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
String prefix = this.reader.getNamespacePrefix(i);
if (prefix == null) {
prefix = "";
}
endPrefixMapping(prefix);
}
}
else {
getContentHandler().endElement("", "", toQualifiedName(qName));
}
}
}
private void handleCharacters() throws SAXException {
if (XMLStreamConstants.CDATA == this.reader.getEventType() && getLexicalHandler() != null) {
getLexicalHandler().startCDATA();
}
if (getContentHandler() != null) {
getContentHandler().characters(this.reader.getTextCharacters(),
this.reader.getTextStart(), this.reader.getTextLength());
}
if (XMLStreamConstants.CDATA == this.reader.getEventType() && getLexicalHandler() != null) {
getLexicalHandler().endCDATA();
}
}
private void handleComment() throws SAXException {
if (getLexicalHandler() != null) {
getLexicalHandler().comment(this.reader.getTextCharacters(),
this.reader.getTextStart(), this.reader.getTextLength());
}
}
private void handleDtd() throws SAXException {
if (getLexicalHandler() != null) {
Location location = this.reader.getLocation();
getLexicalHandler().startDTD(null, location.getPublicId(), location.getSystemId());
}
if (getLexicalHandler() != null) {
getLexicalHandler().endDTD();
}
}
private void handleEntityReference() throws SAXException {
if (getLexicalHandler() != null) {
getLexicalHandler().startEntity(this.reader.getLocalName());
}
if (getLexicalHandler() != null) {
getLexicalHandler().endEntity(this.reader.getLocalName());
}
}
private void handleEndDocument() throws SAXException {
if (getContentHandler() != null) {
getContentHandler().endDocument();
}
}
private void handleProcessingInstruction() throws SAXException {
if (getContentHandler() != null) {
getContentHandler().processingInstruction(this.reader.getPITarget(), this.reader.getPIData());
}
}
private Attributes getAttributes() {
AttributesImpl attributes = new AttributesImpl();
for (int i = 0; i < this.reader.getAttributeCount(); i++) {
String namespace = this.reader.getAttributeNamespace(i);
if (namespace == null || !hasNamespacesFeature()) {
namespace = "";
}
String type = this.reader.getAttributeType(i);
if (type == null) {
type = "CDATA";
}
attributes.addAttribute(namespace, this.reader.getAttributeLocalName(i),
toQualifiedName(this.reader.getAttributeName(i)), type, this.reader.getAttributeValue(i));
}
if (hasNamespacePrefixesFeature()) {
for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
String prefix = this.reader.getNamespacePrefix(i);
String namespaceUri = this.reader.getNamespaceURI(i);
String qName;
if (StringUtils.hasLength(prefix)) {
qName = "xmlns:" + prefix;
}
else {
qName = "xmlns";
}
attributes.addAttribute("", "", qName, "CDATA", namespaceUri);
}
}
return attributes;
}
}