CarrotChat v2.8.60.240131版本的 MD5 值为:2baf8b9f31830b86b5c5a85ae6b47e05

以下内容为反编译后的 XMLWriter.java 源代码,内容仅作参考


package org.dom4j.io;

import com.huawei.hms.framework.common.ContainerUtils;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringTokenizer;
import org.dom4j.Attribute;
import org.dom4j.CDATA;
import org.dom4j.Comment;
import org.dom4j.Document;
import org.dom4j.DocumentType;
import org.dom4j.Element;
import org.dom4j.Entity;
import org.dom4j.Namespace;
import org.dom4j.Node;
import org.dom4j.ProcessingInstruction;
import org.dom4j.Text;
import org.dom4j.tree.NamespaceStack;
import org.jivesoftware.smack.util.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLFilterImpl;
public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
    private static final String PAD_TEXT = " ";
    private boolean autoFlush;
    private StringBuffer buffer;
    private boolean charsAdded;
    private boolean escapeText;
    private OutputFormat format;
    private boolean inDTD;
    private int indentLevel;
    private char lastChar;
    private boolean lastElementClosed;
    protected int lastOutputNodeType;
    private LexicalHandler lexicalHandler;
    private int maximumAllowedCharacter;
    private NamespaceStack namespaceStack;
    private Map namespacesMap;
    protected boolean preserve;
    private boolean resolveEntityRefs;
    private boolean showCommentsInDTDs;
    protected Writer writer;
    protected static final String[] LEXICAL_HANDLER_NAMES = {"http://xml.org/sax/properties/lexical-handler", "http://xml.org/sax/handlers/LexicalHandler"};
    protected static final OutputFormat DEFAULT_FORMAT = new OutputFormat();

    public XMLWriter(Writer writer) {
        this(writer, DEFAULT_FORMAT);
    }

    @Override
    public void characters(char[] cArr, int i, int i2) throws SAXException {
        if (cArr == null || cArr.length == 0 || i2 <= 0) {
            return;
        }
        try {
            String valueOf = String.valueOf(cArr, i, i2);
            if (this.escapeText) {
                valueOf = escapeElementEntities(valueOf);
            }
            if (this.format.isTrimText()) {
                if (this.lastOutputNodeType == 3 && !this.charsAdded) {
                    this.writer.write(32);
                } else if (this.charsAdded && Character.isWhitespace(this.lastChar)) {
                    this.writer.write(32);
                } else if (this.lastOutputNodeType == 1 && this.format.isPadText() && this.lastElementClosed && Character.isWhitespace(cArr[0])) {
                    this.writer.write(PAD_TEXT);
                }
                String str = "";
                StringTokenizer stringTokenizer = new StringTokenizer(valueOf);
                while (stringTokenizer.hasMoreTokens()) {
                    this.writer.write(str);
                    this.writer.write(stringTokenizer.nextToken());
                    str = PAD_TEXT;
                }
            } else {
                this.writer.write(valueOf);
            }
            this.charsAdded = true;
            this.lastChar = cArr[(i + i2) - 1];
            this.lastOutputNodeType = 3;
            super.characters(cArr, i, i2);
        } catch (IOException e2) {
            handleException(e2);
        }
    }

    public void close() throws IOException {
        this.writer.close();
    }

    @Override
    public void comment(char[] cArr, int i, int i2) throws SAXException {
        if (this.showCommentsInDTDs || !this.inDTD) {
            try {
                this.charsAdded = false;
                writeComment(new String(cArr, i, i2));
            } catch (IOException e2) {
                handleException(e2);
            }
        }
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.comment(cArr, i, i2);
        }
    }

    protected Writer createWriter(OutputStream outputStream, String str) throws UnsupportedEncodingException {
        return new BufferedWriter(new OutputStreamWriter(outputStream, str));
    }

    protected int defaultMaximumAllowedCharacter() {
        String encoding = this.format.getEncoding();
        return (encoding == null || !encoding.equals("US-ASCII")) ? -1 : 127;
    }

    public void endCDATA() throws SAXException {
        try {
            this.writer.write("]]>");
        } catch (IOException e2) {
            handleException(e2);
        }
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.endCDATA();
        }
    }

    @Override
    public void endDTD() throws SAXException {
        this.inDTD = false;
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.endDTD();
        }
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        if (this.autoFlush) {
            try {
                flush();
            } catch (IOException unused) {
            }
        }
    }

    @Override
    public void endElement(String str, String str2, String str3) throws SAXException {
        try {
            this.charsAdded = false;
            this.indentLevel--;
            if (this.lastElementClosed) {
                writePrintln();
                indent();
            }
            writeClose(str3);
            this.lastOutputNodeType = 1;
            this.lastElementClosed = true;
            super.endElement(str, str2, str3);
        } catch (IOException e2) {
            handleException(e2);
        }
    }

    @Override
    public void endEntity(String str) throws SAXException {
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.endEntity(str);
        }
    }

    @Override
    public void endPrefixMapping(String str) throws SAXException {
        super.endPrefixMapping(str);
    }

    protected String escapeAttributeEntities(String str) {
        String str2;
        char attributeQuoteCharacter = this.format.getAttributeQuoteCharacter();
        int length = str.length();
        char[] cArr = null;
        int i = 0;
        int i2 = 0;
        while (i < length) {
            char charAt = str.charAt(i);
            if (charAt != '\t' && charAt != '\n' && charAt != '\r') {
                if (charAt != '\"') {
                    if (charAt == '<') {
                        str2 = StringUtils.LT_ENCODE;
                    } else if (charAt == '>') {
                        str2 = StringUtils.GT_ENCODE;
                    } else if (charAt == '&') {
                        str2 = StringUtils.AMP_ENCODE;
                    } else if (charAt != '\'') {
                        if (charAt < ' ' || shouldEncodeChar(charAt)) {
                            StringBuffer stringBuffer = new StringBuffer();
                            stringBuffer.append("&#");
                            stringBuffer.append((int) charAt);
                            stringBuffer.append(";");
                            str2 = stringBuffer.toString();
                        }
                    } else if (attributeQuoteCharacter == '\'') {
                        str2 = StringUtils.APOS_ENCODE;
                    }
                } else if (attributeQuoteCharacter == '\"') {
                    str2 = StringUtils.QUOTE_ENCODE;
                }
                if (str2 != null) {
                    if (cArr == null) {
                        cArr = str.toCharArray();
                    }
                    this.buffer.append(cArr, i2, i - i2);
                    this.buffer.append(str2);
                    i2 = i + 1;
                }
                i++;
            }
            str2 = null;
            if (str2 != null) {
            }
            i++;
        }
        if (i2 == 0) {
            return str;
        }
        if (i2 < length) {
            if (cArr == null) {
                cArr = str.toCharArray();
            }
            this.buffer.append(cArr, i2, i - i2);
        }
        String stringBuffer2 = this.buffer.toString();
        this.buffer.setLength(0);
        return stringBuffer2;
    }

    protected String escapeElementEntities(String str) {
        String valueOf;
        int length = str.length();
        char[] cArr = null;
        int i = 0;
        int i2 = 0;
        while (i < length) {
            char charAt = str.charAt(i);
            if (charAt == '\t' || charAt == '\n' || charAt == '\r') {
                if (this.preserve) {
                    valueOf = String.valueOf(charAt);
                    if (valueOf != null) {
                        if (cArr == null) {
                            cArr = str.toCharArray();
                        }
                        this.buffer.append(cArr, i2, i - i2);
                        this.buffer.append(valueOf);
                        i2 = i + 1;
                    }
                    i++;
                }
                valueOf = null;
                if (valueOf != null) {
                }
                i++;
            } else {
                if (charAt == '&') {
                    valueOf = StringUtils.AMP_ENCODE;
                } else if (charAt == '<') {
                    valueOf = StringUtils.LT_ENCODE;
                } else if (charAt != '>') {
                    if (charAt < ' ' || shouldEncodeChar(charAt)) {
                        StringBuffer stringBuffer = new StringBuffer();
                        stringBuffer.append("&#");
                        stringBuffer.append((int) charAt);
                        stringBuffer.append(";");
                        valueOf = stringBuffer.toString();
                    }
                    valueOf = null;
                } else {
                    valueOf = StringUtils.GT_ENCODE;
                }
                if (valueOf != null) {
                }
                i++;
            }
        }
        if (i2 == 0) {
            return str;
        }
        if (i2 < length) {
            if (cArr == null) {
                cArr = str.toCharArray();
            }
            this.buffer.append(cArr, i2, i - i2);
        }
        String stringBuffer2 = this.buffer.toString();
        this.buffer.setLength(0);
        return stringBuffer2;
    }

    public void flush() throws IOException {
        this.writer.flush();
    }

    public LexicalHandler getLexicalHandler() {
        return this.lexicalHandler;
    }

    public int getMaximumAllowedCharacter() {
        if (this.maximumAllowedCharacter == 0) {
            this.maximumAllowedCharacter = defaultMaximumAllowedCharacter();
        }
        return this.maximumAllowedCharacter;
    }

    public OutputFormat getOutputFormat() {
        return this.format;
    }

    @Override
    public Object getProperty(String str) throws SAXNotRecognizedException, SAXNotSupportedException {
        int i = 0;
        while (true) {
            String[] strArr = LEXICAL_HANDLER_NAMES;
            if (i < strArr.length) {
                if (strArr[i].equals(str)) {
                    return getLexicalHandler();
                }
                i++;
            } else {
                return super.getProperty(str);
            }
        }
    }

    protected void handleException(IOException iOException) throws SAXException {
        throw new SAXException(iOException);
    }

    @Override
    public void ignorableWhitespace(char[] cArr, int i, int i2) throws SAXException {
        super.ignorableWhitespace(cArr, i, i2);
    }

    protected void indent() throws IOException {
        String indent = this.format.getIndent();
        if (indent == null || indent.length() <= 0) {
            return;
        }
        for (int i = 0; i < this.indentLevel; i++) {
            this.writer.write(indent);
        }
    }

    protected void installLexicalHandler() {
        XMLReader parent = getParent();
        Objects.requireNonNull(parent, "No parent for filter");
        int i = 0;
        while (true) {
            String[] strArr = LEXICAL_HANDLER_NAMES;
            if (i >= strArr.length) {
                return;
            }
            try {
                parent.setProperty(strArr[i], this);
                return;
            } catch (SAXNotRecognizedException | SAXNotSupportedException unused) {
                i++;
            }
        }
    }

    protected final boolean isElementSpacePreserved(Element element) {
        Attribute attribute = element.attribute("space");
        return attribute != null ? "xml".equals(attribute.getNamespacePrefix()) && "preserve".equals(attribute.getText()) : this.preserve;
    }

    public boolean isEscapeText() {
        return this.escapeText;
    }

    protected boolean isExpandEmptyElements() {
        return this.format.isExpandEmptyElements();
    }

    protected boolean isNamespaceDeclaration(Namespace namespace) {
        return (namespace == null || namespace == Namespace.XML_NAMESPACE || namespace.getURI() == null || this.namespaceStack.contains(namespace)) ? false : true;
    }

    @Override
    public void notationDecl(String str, String str2, String str3) throws SAXException {
        super.notationDecl(str, str2, str3);
    }

    @Override
    public void parse(InputSource inputSource) throws IOException, SAXException {
        installLexicalHandler();
        super.parse(inputSource);
    }

    public void println() throws IOException {
        this.writer.write(this.format.getLineSeparator());
    }

    @Override
    public void processingInstruction(String str, String str2) throws SAXException {
        try {
            indent();
            this.writer.write("<?");
            this.writer.write(str);
            this.writer.write(PAD_TEXT);
            this.writer.write(str2);
            this.writer.write("?>");
            writePrintln();
            this.lastOutputNodeType = 7;
            super.processingInstruction(str, str2);
        } catch (IOException e2) {
            handleException(e2);
        }
    }

    public boolean resolveEntityRefs() {
        return this.resolveEntityRefs;
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        super.setDocumentLocator(locator);
    }

    public void setEscapeText(boolean z) {
        this.escapeText = z;
    }

    public void setIndentLevel(int i) {
        this.indentLevel = i;
    }

    public void setLexicalHandler(LexicalHandler lexicalHandler) {
        Objects.requireNonNull(lexicalHandler, "Null lexical handler");
        this.lexicalHandler = lexicalHandler;
    }

    public void setMaximumAllowedCharacter(int i) {
        this.maximumAllowedCharacter = i;
    }

    public void setOutputStream(OutputStream outputStream) throws UnsupportedEncodingException {
        this.writer = createWriter(outputStream, this.format.getEncoding());
        this.autoFlush = true;
    }

    @Override
    public void setProperty(String str, Object obj) throws SAXNotRecognizedException, SAXNotSupportedException {
        int i = 0;
        while (true) {
            String[] strArr = LEXICAL_HANDLER_NAMES;
            if (i < strArr.length) {
                if (strArr[i].equals(str)) {
                    setLexicalHandler((LexicalHandler) obj);
                    return;
                }
                i++;
            } else {
                super.setProperty(str, obj);
                return;
            }
        }
    }

    public void setResolveEntityRefs(boolean z) {
        this.resolveEntityRefs = z;
    }

    public void setWriter(Writer writer) {
        this.writer = writer;
        this.autoFlush = false;
    }

    protected boolean shouldEncodeChar(char c2) {
        int maximumAllowedCharacter = getMaximumAllowedCharacter();
        return maximumAllowedCharacter > 0 && c2 > maximumAllowedCharacter;
    }

    public void startCDATA() throws SAXException {
        try {
            this.writer.write("<![CDATA[");
        } catch (IOException e2) {
            handleException(e2);
        }
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.startCDATA();
        }
    }

    @Override
    public void startDTD(String str, String str2, String str3) throws SAXException {
        this.inDTD = true;
        try {
            writeDocType(str, str2, str3);
        } catch (IOException e2) {
            handleException(e2);
        }
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.startDTD(str, str2, str3);
        }
    }

    @Override
    public void startDocument() throws SAXException {
        try {
            writeDeclaration();
            super.startDocument();
        } catch (IOException e2) {
            handleException(e2);
        }
    }

    @Override
    public void startElement(String str, String str2, String str3, Attributes attributes) throws SAXException {
        try {
            this.charsAdded = false;
            writePrintln();
            indent();
            this.writer.write("<");
            this.writer.write(str3);
            writeNamespaces();
            writeAttributes(attributes);
            this.writer.write(">");
            this.indentLevel++;
            this.lastOutputNodeType = 1;
            this.lastElementClosed = false;
            super.startElement(str, str2, str3, attributes);
        } catch (IOException e2) {
            handleException(e2);
        }
    }

    @Override
    public void startEntity(String str) throws SAXException {
        try {
            writeEntityRef(str);
        } catch (IOException e2) {
            handleException(e2);
        }
        LexicalHandler lexicalHandler = this.lexicalHandler;
        if (lexicalHandler != null) {
            lexicalHandler.startEntity(str);
        }
    }

    @Override
    public void startPrefixMapping(String str, String str2) throws SAXException {
        if (this.namespacesMap == null) {
            this.namespacesMap = new HashMap();
        }
        this.namespacesMap.put(str, str2);
        super.startPrefixMapping(str, str2);
    }

    @Override
    public void unparsedEntityDecl(String str, String str2, String str3, String str4) throws SAXException {
        super.unparsedEntityDecl(str, str2, str3, str4);
    }

    public void write(Attribute attribute) throws IOException {
        writeAttribute(attribute);
        if (this.autoFlush) {
            flush();
        }
    }

    protected void writeAttribute(Attribute attribute) throws IOException {
        this.writer.write(PAD_TEXT);
        this.writer.write(attribute.getQualifiedName());
        this.writer.write(ContainerUtils.KEY_VALUE_DELIMITER);
        char attributeQuoteCharacter = this.format.getAttributeQuoteCharacter();
        this.writer.write(attributeQuoteCharacter);
        writeEscapeAttributeEntities(attribute.getValue());
        this.writer.write(attributeQuoteCharacter);
        this.lastOutputNodeType = 2;
    }

    protected void writeAttributes(Element element) throws IOException {
        int attributeCount = element.attributeCount();
        for (int i = 0; i < attributeCount; i++) {
            Attribute attribute = element.attribute(i);
            Namespace namespace = attribute.getNamespace();
            if (namespace != null && namespace != Namespace.NO_NAMESPACE && namespace != Namespace.XML_NAMESPACE) {
                if (!namespace.getURI().equals(this.namespaceStack.getURI(namespace.getPrefix()))) {
                    writeNamespace(namespace);
                    this.namespaceStack.push(namespace);
                }
            }
            String name = attribute.getName();
            if (name.startsWith("xmlns:")) {
                String substring = name.substring(6);
                if (this.namespaceStack.getNamespaceForPrefix(substring) == null) {
                    String value = attribute.getValue();
                    this.namespaceStack.push(substring, value);
                    writeNamespace(substring, value);
                }
            } else if (name.equals("xmlns")) {
                if (this.namespaceStack.getDefaultNamespace() == null) {
                    String value2 = attribute.getValue();
                    this.namespaceStack.push(null, value2);
                    writeNamespace(null, value2);
                }
            } else {
                char attributeQuoteCharacter = this.format.getAttributeQuoteCharacter();
                this.writer.write(PAD_TEXT);
                this.writer.write(attribute.getQualifiedName());
                this.writer.write(ContainerUtils.KEY_VALUE_DELIMITER);
                this.writer.write(attributeQuoteCharacter);
                writeEscapeAttributeEntities(attribute.getValue());
                this.writer.write(attributeQuoteCharacter);
            }
        }
    }

    public void writeCDATA(String str) throws IOException {
        this.writer.write("<![CDATA[");
        if (str != null) {
            this.writer.write(str);
        }
        this.writer.write("]]>");
        this.lastOutputNodeType = 4;
    }

    public void writeClose(Element element) throws IOException {
        writeClose(element.getQualifiedName());
    }

    protected void writeComment(String str) throws IOException {
        if (this.format.isNewlines()) {
            println();
            indent();
        }
        this.writer.write("<!--");
        this.writer.write(str);
        this.writer.write("-->");
        this.lastOutputNodeType = 8;
    }

    protected void writeDeclaration() throws IOException {
        String encoding = this.format.getEncoding();
        if (this.format.isSuppressDeclaration()) {
            return;
        }
        if (encoding.equals("UTF8")) {
            this.writer.write("<?xml version=\"1.0\"");
            if (!this.format.isOmitEncoding()) {
                this.writer.write(" encoding=\"UTF-8\"");
            }
            this.writer.write("?>");
        } else {
            this.writer.write("<?xml version=\"1.0\"");
            if (!this.format.isOmitEncoding()) {
                Writer writer = this.writer;
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(" encoding=\"");
                stringBuffer.append(encoding);
                stringBuffer.append("\"");
                writer.write(stringBuffer.toString());
            }
            this.writer.write("?>");
        }
        if (this.format.isNewLineAfterDeclaration()) {
            println();
        }
    }

    protected void writeDocType(DocumentType documentType) throws IOException {
        if (documentType != null) {
            documentType.write(this.writer);
            writePrintln();
        }
    }

    public void writeElement(Element element) throws IOException {
        int nodeCount = element.nodeCount();
        String qualifiedName = element.getQualifiedName();
        writePrintln();
        indent();
        this.writer.write("<");
        this.writer.write(qualifiedName);
        int size = this.namespaceStack.size();
        Namespace namespace = element.getNamespace();
        if (isNamespaceDeclaration(namespace)) {
            this.namespaceStack.push(namespace);
            writeNamespace(namespace);
        }
        boolean z = true;
        for (int i = 0; i < nodeCount; i++) {
            Node node = element.node(i);
            if (node instanceof Namespace) {
                Namespace namespace2 = (Namespace) node;
                if (isNamespaceDeclaration(namespace2)) {
                    this.namespaceStack.push(namespace2);
                    writeNamespace(namespace2);
                }
            } else if ((node instanceof Element) || (node instanceof Comment)) {
                z = false;
            }
        }
        writeAttributes(element);
        this.lastOutputNodeType = 1;
        if (nodeCount <= 0) {
            writeEmptyElementClose(qualifiedName);
        } else {
            this.writer.write(">");
            if (z) {
                writeElementContent(element);
            } else {
                this.indentLevel++;
                writeElementContent(element);
                this.indentLevel--;
                writePrintln();
                indent();
            }
            this.writer.write("</");
            this.writer.write(qualifiedName);
            this.writer.write(">");
        }
        while (this.namespaceStack.size() > size) {
            this.namespaceStack.pop();
        }
        this.lastOutputNodeType = 1;
    }

    protected void writeElementContent(Element element) throws IOException {
        char charAt;
        char charAt2;
        boolean isTrimText = this.format.isTrimText();
        boolean z = this.preserve;
        if (isTrimText) {
            boolean isElementSpacePreserved = isElementSpacePreserved(element);
            this.preserve = isElementSpacePreserved;
            isTrimText = !isElementSpacePreserved;
        }
        if (isTrimText) {
            int nodeCount = element.nodeCount();
            Text text = null;
            StringBuffer stringBuffer = null;
            boolean z2 = true;
            for (int i = 0; i < nodeCount; i++) {
                Node node = element.node(i);
                if (!(node instanceof Text)) {
                    if (!z2 && this.format.isPadText()) {
                        char c2 = 'a';
                        if (stringBuffer != null) {
                            c2 = stringBuffer.charAt(0);
                        } else if (text != null) {
                            c2 = text.getText().charAt(0);
                        }
                        if (Character.isWhitespace(c2)) {
                            this.writer.write(PAD_TEXT);
                        }
                    }
                    if (text != null) {
                        if (stringBuffer != null) {
                            writeString(stringBuffer.toString());
                            stringBuffer = null;
                        } else {
                            writeString(text.getText());
                        }
                        if (this.format.isPadText()) {
                            if (stringBuffer != null) {
                                charAt2 = stringBuffer.charAt(stringBuffer.length() - 1);
                            } else {
                                String text2 = text.getText();
                                charAt2 = text2.charAt(text2.length() - 1);
                            }
                            if (Character.isWhitespace(charAt2)) {
                                this.writer.write(PAD_TEXT);
                            }
                        }
                        text = null;
                    }
                    writeNode(node);
                    z2 = false;
                } else if (text == null) {
                    text = (Text) node;
                } else {
                    if (stringBuffer == null) {
                        stringBuffer = new StringBuffer(text.getText());
                    }
                    stringBuffer.append(((Text) node).getText());
                }
            }
            if (text != null) {
                if (!z2 && this.format.isPadText()) {
                    if (stringBuffer != null) {
                        charAt = stringBuffer.charAt(0);
                    } else {
                        charAt = text.getText().charAt(0);
                    }
                    if (Character.isWhitespace(charAt)) {
                        this.writer.write(PAD_TEXT);
                    }
                }
                if (stringBuffer != null) {
                    writeString(stringBuffer.toString());
                } else {
                    writeString(text.getText());
                }
            }
        } else {
            int nodeCount2 = element.nodeCount();
            Node node2 = null;
            for (int i2 = 0; i2 < nodeCount2; i2++) {
                Node node3 = element.node(i2);
                if (node3 instanceof Text) {
                    writeNode(node3);
                    node2 = node3;
                } else {
                    if (node2 != null && this.format.isPadText()) {
                        String text3 = node2.getText();
                        if (Character.isWhitespace(text3.charAt(text3.length() - 1))) {
                            this.writer.write(PAD_TEXT);
                        }
                    }
                    writeNode(node3);
                    node2 = null;
                }
            }
        }
        this.preserve = z;
    }

    public void writeEmptyElementClose(String str) throws IOException {
        if (!this.format.isExpandEmptyElements()) {
            this.writer.write("/>");
            return;
        }
        this.writer.write("></");
        this.writer.write(str);
        this.writer.write(">");
    }

    protected void writeEntity(Entity entity) throws IOException {
        if (!resolveEntityRefs()) {
            writeEntityRef(entity.getName());
        } else {
            this.writer.write(entity.getText());
        }
    }

    protected void writeEntityRef(String str) throws IOException {
        this.writer.write(ContainerUtils.FIELD_DELIMITER);
        this.writer.write(str);
        this.writer.write(";");
        this.lastOutputNodeType = 5;
    }

    protected void writeEscapeAttributeEntities(String str) throws IOException {
        if (str != null) {
            this.writer.write(escapeAttributeEntities(str));
        }
    }

    protected void writeNamespace(Namespace namespace) throws IOException {
        if (namespace != null) {
            writeNamespace(namespace.getPrefix(), namespace.getURI());
        }
    }

    protected void writeNamespaces() throws IOException {
        Map map = this.namespacesMap;
        if (map != null) {
            for (Map.Entry entry : map.entrySet()) {
                writeNamespace((String) entry.getKey(), (String) entry.getValue());
            }
            this.namespacesMap = null;
        }
    }

    protected void writeNode(Node node) throws IOException {
        switch (node.getNodeType()) {
            case 1:
                writeElement((Element) node);
                return;
            case 2:
                writeAttribute((Attribute) node);
                return;
            case 3:
                writeNodeText(node);
                return;
            case 4:
                writeCDATA(node.getText());
                return;
            case 5:
                writeEntity((Entity) node);
                return;
            case 6:
            case 11:
            case 12:
            default:
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append("Invalid node type: ");
                stringBuffer.append(node);
                throw new IOException(stringBuffer.toString());
            case 7:
                writeProcessingInstruction((ProcessingInstruction) node);
                return;
            case 8:
                writeComment(node.getText());
                return;
            case 9:
                write((Document) node);
                return;
            case 10:
                writeDocType((DocumentType) node);
                return;
            case 13:
                return;
        }
    }

    protected void writeNodeText(Node node) throws IOException {
        String text = node.getText();
        if (text == null || text.length() <= 0) {
            return;
        }
        if (this.escapeText) {
            text = escapeElementEntities(text);
        }
        this.lastOutputNodeType = 3;
        this.writer.write(text);
        this.lastChar = text.charAt(text.length() - 1);
    }

    public void writeOpen(Element element) throws IOException {
        this.writer.write("<");
        this.writer.write(element.getQualifiedName());
        writeAttributes(element);
        this.writer.write(">");
    }

    public void writePrintln() throws IOException {
        if (this.format.isNewlines()) {
            String lineSeparator = this.format.getLineSeparator();
            if (this.lastChar != lineSeparator.charAt(lineSeparator.length() - 1)) {
                this.writer.write(this.format.getLineSeparator());
            }
        }
    }

    protected void writeProcessingInstruction(ProcessingInstruction processingInstruction) throws IOException {
        this.writer.write("<?");
        this.writer.write(processingInstruction.getName());
        this.writer.write(PAD_TEXT);
        this.writer.write(processingInstruction.getText());
        this.writer.write("?>");
        writePrintln();
        this.lastOutputNodeType = 7;
    }

    public void writeString(String str) throws IOException {
        if (str == null || str.length() <= 0) {
            return;
        }
        if (this.escapeText) {
            str = escapeElementEntities(str);
        }
        if (this.format.isTrimText()) {
            StringTokenizer stringTokenizer = new StringTokenizer(str);
            boolean z = true;
            while (stringTokenizer.hasMoreTokens()) {
                String nextToken = stringTokenizer.nextToken();
                if (z) {
                    z = false;
                    if (this.lastOutputNodeType == 3) {
                        this.writer.write(PAD_TEXT);
                    }
                } else {
                    this.writer.write(PAD_TEXT);
                }
                this.writer.write(nextToken);
                this.lastOutputNodeType = 3;
                this.lastChar = nextToken.charAt(nextToken.length() - 1);
            }
            return;
        }
        this.lastOutputNodeType = 3;
        this.writer.write(str);
        this.lastChar = str.charAt(str.length() - 1);
    }

    public XMLWriter(Writer writer, OutputFormat outputFormat) {
        this.resolveEntityRefs = true;
        this.lastElementClosed = false;
        this.preserve = false;
        this.namespaceStack = new NamespaceStack();
        this.escapeText = true;
        this.indentLevel = 0;
        this.buffer = new StringBuffer();
        this.charsAdded = false;
        this.writer = writer;
        this.format = outputFormat;
        this.namespaceStack.push(Namespace.NO_NAMESPACE);
    }

    public void writeClose(String str) throws IOException {
        this.writer.write("</");
        this.writer.write(str);
        this.writer.write(">");
    }

    protected void writeNamespace(String str, String str2) throws IOException {
        if (str != null && str.length() > 0) {
            this.writer.write(" xmlns:");
            this.writer.write(str);
            this.writer.write("=\"");
        } else {
            this.writer.write(" xmlns=\"");
        }
        this.writer.write(str2);
        this.writer.write("\"");
    }

    protected void writeDocType(String str, String str2, String str3) throws IOException {
        boolean z;
        this.writer.write("<!DOCTYPE ");
        this.writer.write(str);
        if (str2 == null || str2.equals("")) {
            z = false;
        } else {
            this.writer.write(" PUBLIC \"");
            this.writer.write(str2);
            this.writer.write("\"");
            z = true;
        }
        if (str3 != null && !str3.equals("")) {
            if (!z) {
                this.writer.write(" SYSTEM");
            }
            this.writer.write(" \"");
            this.writer.write(str3);
            this.writer.write("\"");
        }
        this.writer.write(">");
        writePrintln();
    }

    public void write(Document document) throws IOException {
        writeDeclaration();
        if (document.getDocType() != null) {
            indent();
            writeDocType(document.getDocType());
        }
        int nodeCount = document.nodeCount();
        for (int i = 0; i < nodeCount; i++) {
            writeNode(document.node(i));
        }
        writePrintln();
        if (this.autoFlush) {
            flush();
        }
    }

    protected void writeAttribute(Attributes attributes, int i) throws IOException {
        char attributeQuoteCharacter = this.format.getAttributeQuoteCharacter();
        this.writer.write(PAD_TEXT);
        this.writer.write(attributes.getQName(i));
        this.writer.write(ContainerUtils.KEY_VALUE_DELIMITER);
        this.writer.write(attributeQuoteCharacter);
        writeEscapeAttributeEntities(attributes.getValue(i));
        this.writer.write(attributeQuoteCharacter);
    }

    public XMLWriter() {
        this.resolveEntityRefs = true;
        this.lastElementClosed = false;
        this.preserve = false;
        this.namespaceStack = new NamespaceStack();
        this.escapeText = true;
        this.indentLevel = 0;
        this.buffer = new StringBuffer();
        this.charsAdded = false;
        this.format = DEFAULT_FORMAT;
        this.writer = new BufferedWriter(new OutputStreamWriter(System.out));
        this.autoFlush = true;
        this.namespaceStack.push(Namespace.NO_NAMESPACE);
    }

    public void write(Element element) throws IOException {
        writeElement(element);
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(CDATA cdata) throws IOException {
        writeCDATA(cdata.getText());
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(Comment comment) throws IOException {
        writeComment(comment.getText());
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(DocumentType documentType) throws IOException {
        writeDocType(documentType);
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(Entity entity) throws IOException {
        writeEntity(entity);
        if (this.autoFlush) {
            flush();
        }
    }

    public XMLWriter(OutputStream outputStream) throws UnsupportedEncodingException {
        this.resolveEntityRefs = true;
        this.lastElementClosed = false;
        this.preserve = false;
        this.namespaceStack = new NamespaceStack();
        this.escapeText = true;
        this.indentLevel = 0;
        this.buffer = new StringBuffer();
        this.charsAdded = false;
        OutputFormat outputFormat = DEFAULT_FORMAT;
        this.format = outputFormat;
        this.writer = createWriter(outputStream, outputFormat.getEncoding());
        this.autoFlush = true;
        this.namespaceStack.push(Namespace.NO_NAMESPACE);
    }

    public void write(Namespace namespace) throws IOException {
        writeNamespace(namespace);
        if (this.autoFlush) {
            flush();
        }
    }

    protected void writeAttributes(Attributes attributes) throws IOException {
        int length = attributes.getLength();
        for (int i = 0; i < length; i++) {
            writeAttribute(attributes, i);
        }
    }

    public void write(ProcessingInstruction processingInstruction) throws IOException {
        writeProcessingInstruction(processingInstruction);
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(String str) throws IOException {
        writeString(str);
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(Text text) throws IOException {
        writeString(text.getText());
        if (this.autoFlush) {
            flush();
        }
    }

    public XMLWriter(OutputStream outputStream, OutputFormat outputFormat) throws UnsupportedEncodingException {
        this.resolveEntityRefs = true;
        this.lastElementClosed = false;
        this.preserve = false;
        this.namespaceStack = new NamespaceStack();
        this.escapeText = true;
        this.indentLevel = 0;
        this.buffer = new StringBuffer();
        this.charsAdded = false;
        this.format = outputFormat;
        this.writer = createWriter(outputStream, outputFormat.getEncoding());
        this.autoFlush = true;
        this.namespaceStack.push(Namespace.NO_NAMESPACE);
    }

    public void write(Node node) throws IOException {
        writeNode(node);
        if (this.autoFlush) {
            flush();
        }
    }

    public void write(Object obj) throws IOException {
        if (obj instanceof Node) {
            write((Node) obj);
        } else if (obj instanceof String) {
            write((String) obj);
        } else if (obj instanceof List) {
            List list = (List) obj;
            int size = list.size();
            for (int i = 0; i < size; i++) {
                write(list.get(i));
            }
        } else {
            if (obj == null) {
                return;
            }
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("Invalid object: ");
            stringBuffer.append(obj);
            throw new IOException(stringBuffer.toString());
        }
    }

    public XMLWriter(OutputFormat outputFormat) throws UnsupportedEncodingException {
        this.resolveEntityRefs = true;
        this.lastElementClosed = false;
        this.preserve = false;
        this.namespaceStack = new NamespaceStack();
        this.escapeText = true;
        this.indentLevel = 0;
        this.buffer = new StringBuffer();
        this.charsAdded = false;
        this.format = outputFormat;
        this.writer = createWriter(System.out, outputFormat.getEncoding());
        this.autoFlush = true;
        this.namespaceStack.push(Namespace.NO_NAMESPACE);
    }
}