📄 litexmlelement.java
字号:
/* * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. * * The Sun Project JXTA(TM) Software License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by Sun Microsystems, Inc. for JXTA(TM) technology." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must * not be used to endorse or promote products derived from this software * without prior written permission. For written permission, please contact * Project JXTA at http://www.jxta.org. * * 5. Products derived from this software may not be called "JXTA", nor may * "JXTA" appear in their name, without prior written permission of Sun. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * JXTA is a registered trademark of Sun Microsystems, Inc. in the United * States and other countries. * * Please see the license information page at : * <http://www.jxta.org/project/www/license.html> for instructions on use of * the license in source files. * * ==================================================================== * * This software consists of voluntary contributions made by many individuals * on behalf of Project JXTA. For more information on Project JXTA, please see * http://www.jxta.org. * * This license is based on the BSD license adopted by the Apache Foundation. */package net.jxta.impl.document;import java.io.Writer;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.Iterator;import java.util.List;import java.util.logging.Level;import java.util.logging.Logger;import java.io.IOException;import net.jxta.document.Attribute;import net.jxta.document.XMLElement;import net.jxta.logging.Logging;/** * An element of a <CODE>StructuredDocument</CODE>. <CODE>StructuredDocument</CODE>s * are made up of hierarchies of elements. LiteXMLElement is part of an implementation * while makes use of XML-style document conventions, but without the overhead of a * full parser. */public class LiteXMLElement implements XMLElement<LiteXMLElement> { /** * Defines a range of characters, probably within a string. The range is * deemed to be invalid if 'start' is -1. A zero length range is, by * convention, described by an 'end' value of 'start' - 1. */ protected static class charRange implements Comparable<charRange> { /** * Contains the start position of this range. */ public int start; /** * Contains the end position of this range. one weird thing: if end == start -1, * then the item is of zero length beginning at start. */ public int end; /** * Constructor for a null charRange. */ public charRange() { start = -1; end = -1; } /** * Constructor for which the bounds are specified. */ public charRange(int start, int end) { this.start = start; this.end = end; } /** * {@inheritDoc} */ @Override public boolean equals(Object aRange) { if (this == aRange) { return true; } if (!(aRange instanceof charRange)) { return false; } charRange someRange = (charRange) aRange; return (start == someRange.start) && (end == someRange.end); } /** * {@inheritDoc} */ public int compareTo(charRange someRange) { if (this == someRange) { return 0; } if (start < someRange.start) { return -1; } if (start > someRange.start) { return 1; } if (end < someRange.end) { return -1; } if (end > someRange.end) { return 1; } return 0; } /** * {@inheritDoc} */ @Override public String toString() { return "[" + start + "," + end + "]"; } /** * Returns true if the <CODE>charRange</CODE> specified by someRange is * contained within this range. * * @param someRange The range which must be contained within this range. * @return true if the specified range is contained with this range otherwise false. */ public boolean contains(charRange someRange) { return (isValid() && someRange.isValid() && (start <= someRange.start) && (end >= someRange.end)); } /** * Returns true if the <CODE>tagRange</CODE> specified by someRange is * contained within this range. * * @param someRange The range which must be contained within this range. * @return true if the specified range is contained with this range otherwise false. */ public boolean contains(tagRange someRange) { return (isValid() && someRange.isValid() && (start <= someRange.startTag.start) && (end >= someRange.endTag.end)); } /** * Returns true if the location specified is contained in this range. * * @param someLoc the location which is to be tested. * @return true if the location is in this range, otherwise false. */ public boolean contains(int someLoc) { return (isValid() && (someLoc >= 0) && (start <= someLoc) && (end >= someLoc)); } /** * Returns true if the range is both non-null and has a length of greater * than or equal to zero. * * @return true if the range is a valid one, otherwise false. */ public boolean isValid() { return length() >= 0; } /** * Returns the length of this range. * * @return The length of the range or -1 if the range is null. */ public int length() { if ((-1 == start) || (-1 == end)) { return -1; } return (end - start + 1); } } /** * A tagRange is a collection of char ranges useful for describing XML * structures. * <p/> * <p/><dl> * <dt><code>startTag</code></dt> * <dd>The range of the opening tag, ie. <tag></dd> * <dt><code>body</code></dt> * <dd>Everything between <code>startTag</code> and <code>endTag</code>.</dd> * <dt><code>endTag</code></dt> * <dd>The range of the terminating tag, ie. </tag>.</dd> * </dl> * <p/> * <p/>For empty-element tags the <code>startTag</code>, <code>body</code> * and <code>endTag</code> will be equal. */ protected static class tagRange implements Comparable<tagRange> { public charRange startTag; public charRange body; public charRange endTag; public tagRange() { startTag = new charRange(); body = new charRange(); endTag = new charRange(); } public tagRange(charRange startTag, charRange body, charRange endTag) { this.startTag = startTag; this.body = body; this.endTag = endTag; } /** * {@inheritDoc} */ @Override public boolean equals(Object aRange) { if (this == aRange) { return true; } if (!(aRange instanceof tagRange)) { return false; } tagRange likeMe = (tagRange) aRange; return startTag.equals(likeMe.startTag) && body.equals(likeMe.body) && endTag.equals(likeMe.endTag); } /** * {@inheritDoc} */ public int compareTo(tagRange someRange) { if (this == someRange) { return 0; } int compared = startTag.compareTo(someRange.startTag); if (0 != compared) { return compared; } return endTag.compareTo(someRange.endTag); } /** * {@inheritDoc} */ @Override public String toString() { return startTag + ":" + body + ":" + endTag; } /** * Returns true if the <CODE>tagRange</CODE> specified by someRange is * contained within the body portion of this range. * * @param someRange The range which must be contained within this range. * @return true if the specified range is contained with this range * otherwise false. */ public boolean contains(tagRange someRange) { return (isValid() && someRange.isValid() && (body.start <= someRange.startTag.start) && (body.end >= someRange.endTag.end)); } /** * Returns true if the <CODE>charRange</CODE> specified by someRange is * contained within the body portion of this range. * * @param someRange The range which must be contained within this range. * @return true if the specified range is contained with this range * otherwise false. */ public boolean contains(charRange someRange) { return (isValid() && someRange.isValid() && (body.start <= someRange.start) && (body.end >= someRange.end)); } /** * @return <code>true</code> if this tagRange represents and empty * element. */ public boolean isEmptyElement() { return isValid() && startTag.equals(body) && startTag.equals(endTag); } /** * @return true if valid */ public boolean isValid() { return (null != startTag) && (null != body) && (null != endTag) && startTag.isValid() && body.isValid() && endTag.isValid(); } } /** * Log4J Logger */ private final static transient Logger LOG = Logger.getLogger(LiteXMLElement.class.getName()); /** * If true then every operation which modifies the state of the document will * perform a consistency check. This is a deadly performance killer but * helps a lot in isolating bugs. */ protected final static transient boolean paranoidConsistencyChecking = false; /** * The document associated with this Element. */ protected final transient LiteXMLDocument doc; /** * Identifies the element which is the parent of this element. If <code> * this.parent == this</code> then this element is the root of the document. * If <code>null == parent</code> then this element has not yet been * inserted into the document. */ protected transient LiteXMLElement parent; /** * The portion of the source XML associated with this node */ protected transient tagRange loc; /** * If this node has yet to be inserted into the document then will contain * the String value of this node, otherwise null. */ private transient StringBuilder uninserted = null; /** * The child elements associated with this element */ private transient List<LiteXMLElement> children; /** * Creates new LiteXMLElement * * @param loc The location of the element within the document. * @param doc The {@link LiteXMLDocument} which is the root of the document. */ protected LiteXMLElement(LiteXMLDocument doc, tagRange loc) { this.doc = doc; this.loc = loc; } /** * Creates new LiteElement * * @param doc The {@link LiteXMLDocument} which is the root of the document. * @param name The name of the element being created. * @param val The value of the element being created or null if there is no * content to the element. */ public LiteXMLElement(LiteXMLDocument doc, final String name, final String val) { this(doc, new tagRange()); for (int eachChar = name.length() - 1; eachChar >= 0; eachChar--) { if (Character.isWhitespace(name.charAt(eachChar))) { throw new IllegalArgumentException("Element names may not contain spaces."); } } if ((null == val) || (0 == val.length())) { uninserted = new StringBuilder("<" + name + "/>"); } else { uninserted = new StringBuilder(val); encodeEscaped(uninserted); uninserted.insert(0, "<" + name + ">"); uninserted.append("</").append(name).append(">"); } } /** * {@inheritDoc} */ @Override public boolean equals(Object element) { if (this == element) { return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -