diff options
Diffstat (limited to 'parser/html/javasrc/HtmlAttributes.java')
-rw-r--r-- | parser/html/javasrc/HtmlAttributes.java | 618 |
1 files changed, 0 insertions, 618 deletions
diff --git a/parser/html/javasrc/HtmlAttributes.java b/parser/html/javasrc/HtmlAttributes.java deleted file mode 100644 index 0ec25f96f..000000000 --- a/parser/html/javasrc/HtmlAttributes.java +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (c) 2007 Henri Sivonen - * Copyright (c) 2008-2011 Mozilla Foundation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package nu.validator.htmlparser.impl; - -import nu.validator.htmlparser.annotation.Auto; -import nu.validator.htmlparser.annotation.IdType; -import nu.validator.htmlparser.annotation.Local; -import nu.validator.htmlparser.annotation.NsUri; -import nu.validator.htmlparser.annotation.Prefix; -import nu.validator.htmlparser.annotation.QName; -import nu.validator.htmlparser.common.Interner; -import nu.validator.htmlparser.common.XmlViolationPolicy; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; - -/** - * Be careful with this class. QName is the name in from HTML tokenization. - * Otherwise, please refer to the interface doc. - * - * @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $ - * @author hsivonen - */ -public final class HtmlAttributes implements Attributes { - - // [NOCPP[ - - private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0]; - - private static final String[] EMPTY_STRINGS = new String[0]; - - // ]NOCPP] - - public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes( - AttributeName.HTML); - - private int mode; - - private int length; - - private @Auto AttributeName[] names; - - private @Auto String[] values; // XXX perhaps make this @NoLength? - - // CPPONLY: private @Auto int[] lines; // XXX perhaps make this @NoLength? - - // [NOCPP[ - - private String idValue; - - private int xmlnsLength; - - private AttributeName[] xmlnsNames; - - private String[] xmlnsValues; - - // ]NOCPP] - - public HtmlAttributes(int mode) { - this.mode = mode; - this.length = 0; - /* - * The length of 5 covers covers 98.3% of elements - * according to Hixie, but lets round to the next power of two for - * jemalloc. - */ - this.names = new AttributeName[8]; - this.values = new String[8]; - // CPPONLY: this.lines = new int[8]; - - // [NOCPP[ - - this.idValue = null; - - this.xmlnsLength = 0; - - this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES; - - this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS; - - // ]NOCPP] - } - /* - public HtmlAttributes(HtmlAttributes other) { - this.mode = other.mode; - this.length = other.length; - this.names = new AttributeName[other.length]; - this.values = new String[other.length]; - // [NOCPP[ - this.idValue = other.idValue; - this.xmlnsLength = other.xmlnsLength; - this.xmlnsNames = new AttributeName[other.xmlnsLength]; - this.xmlnsValues = new String[other.xmlnsLength]; - // ]NOCPP] - } - */ - - void destructor() { - clear(0); - } - - /** - * Only use with a static argument - * - * @param name - * @return - */ - public int getIndex(AttributeName name) { - for (int i = 0; i < length; i++) { - if (names[i] == name) { - return i; - } - } - return -1; - } - - /** - * Only use with static argument. - * - * @see org.xml.sax.Attributes#getValue(java.lang.String) - */ - public String getValue(AttributeName name) { - int index = getIndex(name); - if (index == -1) { - return null; - } else { - return getValueNoBoundsCheck(index); - } - } - - public int getLength() { - return length; - } - - /** - * Variant of <code>getLocalName(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the local name at index - */ - public @Local String getLocalNameNoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - return names[index].getLocal(mode); - } - - /** - * Variant of <code>getURI(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the namespace URI at index - */ - public @NsUri String getURINoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - return names[index].getUri(mode); - } - - /** - * Variant of <code>getPrefix(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the namespace prefix at index - */ - public @Prefix String getPrefixNoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - return names[index].getPrefix(mode); - } - - /** - * Variant of <code>getValue(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the attribute value at index - */ - public String getValueNoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - return values[index]; - } - - /** - * Variant of <code>getAttributeName(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the attribute name at index - */ - public AttributeName getAttributeNameNoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - return names[index]; - } - - // CPPONLY: /** - // CPPONLY: * Obtains a line number without bounds check. - // CPPONLY: * @param index a valid attribute index - // CPPONLY: * @return the line number at index or -1 if unknown - // CPPONLY: */ - // CPPONLY: public int getLineNoBoundsCheck(int index) { - // CPPONLY: assert index < length && index >= 0: "Index out of bounds"; - // CPPONLY: return lines[index]; - // CPPONLY: } - - // [NOCPP[ - - /** - * Variant of <code>getQName(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the QName at index - */ - public @QName String getQNameNoBoundsCheck(int index) { - return names[index].getQName(mode); - } - - /** - * Variant of <code>getType(int index)</code> without bounds check. - * @param index a valid attribute index - * @return the attribute type at index - */ - public @IdType String getTypeNoBoundsCheck(int index) { - return (names[index] == AttributeName.ID) ? "ID" : "CDATA"; - } - - public int getIndex(String qName) { - for (int i = 0; i < length; i++) { - if (names[i].getQName(mode).equals(qName)) { - return i; - } - } - return -1; - } - - public int getIndex(String uri, String localName) { - for (int i = 0; i < length; i++) { - if (names[i].getLocal(mode).equals(localName) - && names[i].getUri(mode).equals(uri)) { - return i; - } - } - return -1; - } - - public @IdType String getType(String qName) { - int index = getIndex(qName); - if (index == -1) { - return null; - } else { - return getType(index); - } - } - - public @IdType String getType(String uri, String localName) { - int index = getIndex(uri, localName); - if (index == -1) { - return null; - } else { - return getType(index); - } - } - - public String getValue(String qName) { - int index = getIndex(qName); - if (index == -1) { - return null; - } else { - return getValue(index); - } - } - - public String getValue(String uri, String localName) { - int index = getIndex(uri, localName); - if (index == -1) { - return null; - } else { - return getValue(index); - } - } - - public @Local String getLocalName(int index) { - if (index < length && index >= 0) { - return names[index].getLocal(mode); - } else { - return null; - } - } - - public @QName String getQName(int index) { - if (index < length && index >= 0) { - return names[index].getQName(mode); - } else { - return null; - } - } - - public @IdType String getType(int index) { - if (index < length && index >= 0) { - return (names[index] == AttributeName.ID) ? "ID" : "CDATA"; - } else { - return null; - } - } - - public AttributeName getAttributeName(int index) { - if (index < length && index >= 0) { - return names[index]; - } else { - return null; - } - } - - public @NsUri String getURI(int index) { - if (index < length && index >= 0) { - return names[index].getUri(mode); - } else { - return null; - } - } - - public @Prefix String getPrefix(int index) { - if (index < length && index >= 0) { - return names[index].getPrefix(mode); - } else { - return null; - } - } - - public String getValue(int index) { - if (index < length && index >= 0) { - return values[index]; - } else { - return null; - } - } - - public String getId() { - return idValue; - } - - public int getXmlnsLength() { - return xmlnsLength; - } - - public @Local String getXmlnsLocalName(int index) { - if (index < xmlnsLength && index >= 0) { - return xmlnsNames[index].getLocal(mode); - } else { - return null; - } - } - - public @NsUri String getXmlnsURI(int index) { - if (index < xmlnsLength && index >= 0) { - return xmlnsNames[index].getUri(mode); - } else { - return null; - } - } - - public String getXmlnsValue(int index) { - if (index < xmlnsLength && index >= 0) { - return xmlnsValues[index]; - } else { - return null; - } - } - - public int getXmlnsIndex(AttributeName name) { - for (int i = 0; i < xmlnsLength; i++) { - if (xmlnsNames[i] == name) { - return i; - } - } - return -1; - } - - public String getXmlnsValue(AttributeName name) { - int index = getXmlnsIndex(name); - if (index == -1) { - return null; - } else { - return getXmlnsValue(index); - } - } - - public AttributeName getXmlnsAttributeName(int index) { - if (index < xmlnsLength && index >= 0) { - return xmlnsNames[index]; - } else { - return null; - } - } - - // ]NOCPP] - - void addAttribute(AttributeName name, String value - // [NOCPP[ - , XmlViolationPolicy xmlnsPolicy - // ]NOCPP] - // CPPONLY: , int line - ) throws SAXException { - // [NOCPP[ - if (name == AttributeName.ID) { - idValue = value; - } - - if (name.isXmlns()) { - if (xmlnsNames.length == xmlnsLength) { - int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1; - AttributeName[] newNames = new AttributeName[newLen]; - System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length); - xmlnsNames = newNames; - String[] newValues = new String[newLen]; - System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length); - xmlnsValues = newValues; - } - xmlnsNames[xmlnsLength] = name; - xmlnsValues[xmlnsLength] = value; - xmlnsLength++; - switch (xmlnsPolicy) { - case FATAL: - // this is ugly - throw new SAXException("Saw an xmlns attribute."); - case ALTER_INFOSET: - return; - case ALLOW: - // fall through - } - } - - // ]NOCPP] - - if (names.length == length) { - int newLen = length << 1; // The first growth covers virtually - // 100% of elements according to - // Hixie - AttributeName[] newNames = new AttributeName[newLen]; - System.arraycopy(names, 0, newNames, 0, names.length); - names = newNames; - String[] newValues = new String[newLen]; - System.arraycopy(values, 0, newValues, 0, values.length); - values = newValues; - // CPPONLY: int[] newLines = new int[newLen]; - // CPPONLY: System.arraycopy(lines, 0, newLines, 0, lines.length); - // CPPONLY: lines = newLines; - } - names[length] = name; - values[length] = value; - // CPPONLY: lines[length] = line; - length++; - } - - void clear(int m) { - for (int i = 0; i < length; i++) { - names[i].release(); - names[i] = null; - Portability.releaseString(values[i]); - values[i] = null; - } - length = 0; - mode = m; - // [NOCPP[ - idValue = null; - for (int i = 0; i < xmlnsLength; i++) { - xmlnsNames[i] = null; - xmlnsValues[i] = null; - } - xmlnsLength = 0; - // ]NOCPP] - } - - /** - * This is used in C++ to release special <code>isindex</code> - * attribute values whose ownership is not transferred. - */ - void releaseValue(int i) { - Portability.releaseString(values[i]); - } - - /** - * This is only used for <code>AttributeName</code> ownership transfer - * in the isindex case to avoid freeing custom names twice in C++. - */ - void clearWithoutReleasingContents() { - for (int i = 0; i < length; i++) { - names[i] = null; - values[i] = null; - } - length = 0; - } - - boolean contains(AttributeName name) { - for (int i = 0; i < length; i++) { - if (name.equalsAnother(names[i])) { - return true; - } - } - // [NOCPP[ - for (int i = 0; i < xmlnsLength; i++) { - if (name.equalsAnother(xmlnsNames[i])) { - return true; - } - } - // ]NOCPP] - return false; - } - - public void adjustForMath() { - mode = AttributeName.MATHML; - } - - public void adjustForSvg() { - mode = AttributeName.SVG; - } - - public HtmlAttributes cloneAttributes(Interner interner) - throws SAXException { - assert (length == 0 - // [NOCPP[ - && xmlnsLength == 0 - // ]NOCPP] - ) - || mode == 0 || mode == 3; - HtmlAttributes clone = new HtmlAttributes(0); - for (int i = 0; i < length; i++) { - clone.addAttribute(names[i].cloneAttributeName(interner), - Portability.newStringFromString(values[i]) - // [NOCPP[ - , XmlViolationPolicy.ALLOW - // ]NOCPP] - // CPPONLY: , lines[i] - ); - } - // [NOCPP[ - for (int i = 0; i < xmlnsLength; i++) { - clone.addAttribute(xmlnsNames[i], xmlnsValues[i], - XmlViolationPolicy.ALLOW); - } - // ]NOCPP] - return clone; // XXX!!! - } - - public boolean equalsAnother(HtmlAttributes other) { - assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content."; - int otherLength = other.getLength(); - if (length != otherLength) { - return false; - } - for (int i = 0; i < length; i++) { - // Work around the limitations of C++ - boolean found = false; - // The comparing just the local names is OK, since these attribute - // holders are both supposed to belong to HTML formatting elements - @Local String ownLocal = names[i].getLocal(AttributeName.HTML); - for (int j = 0; j < otherLength; j++) { - if (ownLocal == other.names[j].getLocal(AttributeName.HTML)) { - found = true; - if (!Portability.stringEqualsString(values[i], other.values[j])) { - return false; - } - } - } - if (!found) { - return false; - } - } - return true; - } - - // [NOCPP[ - - void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException { - for (int i = 0; i < length; i++) { - AttributeName attName = names[i]; - if (!attName.isNcName(mode)) { - String name = attName.getLocal(mode); - switch (namePolicy) { - case ALTER_INFOSET: - names[i] = AttributeName.create(NCName.escapeName(name)); - // fall through - case ALLOW: - if (attName != AttributeName.XML_LANG) { - treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0."); - } - break; - case FATAL: - treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0."); - break; - } - } - } - } - - public void merge(HtmlAttributes attributes) throws SAXException { - int len = attributes.getLength(); - for (int i = 0; i < len; i++) { - AttributeName name = attributes.getAttributeNameNoBoundsCheck(i); - if (!contains(name)) { - addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW); - } - } - } - - - // ]NOCPP] - -} |