parser/html/javasrc/StackNode.java

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /*
michael@0 2 * Copyright (c) 2007 Henri Sivonen
michael@0 3 * Copyright (c) 2007-2011 Mozilla Foundation
michael@0 4 *
michael@0 5 * Permission is hereby granted, free of charge, to any person obtaining a
michael@0 6 * copy of this software and associated documentation files (the "Software"),
michael@0 7 * to deal in the Software without restriction, including without limitation
michael@0 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
michael@0 9 * and/or sell copies of the Software, and to permit persons to whom the
michael@0 10 * Software is furnished to do so, subject to the following conditions:
michael@0 11 *
michael@0 12 * The above copyright notice and this permission notice shall be included in
michael@0 13 * all copies or substantial portions of the Software.
michael@0 14 *
michael@0 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
michael@0 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
michael@0 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
michael@0 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
michael@0 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
michael@0 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
michael@0 21 * DEALINGS IN THE SOFTWARE.
michael@0 22 */
michael@0 23
michael@0 24 package nu.validator.htmlparser.impl;
michael@0 25
michael@0 26 import nu.validator.htmlparser.annotation.Inline;
michael@0 27 import nu.validator.htmlparser.annotation.Local;
michael@0 28 import nu.validator.htmlparser.annotation.NsUri;
michael@0 29
michael@0 30 final class StackNode<T> {
michael@0 31 final int flags;
michael@0 32
michael@0 33 final @Local String name;
michael@0 34
michael@0 35 final @Local String popName;
michael@0 36
michael@0 37 final @NsUri String ns;
michael@0 38
michael@0 39 final T node;
michael@0 40
michael@0 41 // Only used on the list of formatting elements
michael@0 42 HtmlAttributes attributes;
michael@0 43
michael@0 44 private int refcount = 1;
michael@0 45
michael@0 46 // [NOCPP[
michael@0 47
michael@0 48 private final TaintableLocatorImpl locator;
michael@0 49
michael@0 50 public TaintableLocatorImpl getLocator() {
michael@0 51 return locator;
michael@0 52 }
michael@0 53
michael@0 54 // ]NOCPP]
michael@0 55
michael@0 56 @Inline public int getFlags() {
michael@0 57 return flags;
michael@0 58 }
michael@0 59
michael@0 60 public int getGroup() {
michael@0 61 return flags & ElementName.GROUP_MASK;
michael@0 62 }
michael@0 63
michael@0 64 public boolean isScoping() {
michael@0 65 return (flags & ElementName.SCOPING) != 0;
michael@0 66 }
michael@0 67
michael@0 68 public boolean isSpecial() {
michael@0 69 return (flags & ElementName.SPECIAL) != 0;
michael@0 70 }
michael@0 71
michael@0 72 public boolean isFosterParenting() {
michael@0 73 return (flags & ElementName.FOSTER_PARENTING) != 0;
michael@0 74 }
michael@0 75
michael@0 76 public boolean isHtmlIntegrationPoint() {
michael@0 77 return (flags & ElementName.HTML_INTEGRATION_POINT) != 0;
michael@0 78 }
michael@0 79
michael@0 80 // [NOCPP[
michael@0 81
michael@0 82 public boolean isOptionalEndTag() {
michael@0 83 return (flags & ElementName.OPTIONAL_END_TAG) != 0;
michael@0 84 }
michael@0 85
michael@0 86 // ]NOCPP]
michael@0 87
michael@0 88 /**
michael@0 89 * Constructor for copying. This doesn't take another <code>StackNode</code>
michael@0 90 * because in C++ the caller is reponsible for reobtaining the local names
michael@0 91 * from another interner.
michael@0 92 *
michael@0 93 * @param flags
michael@0 94 * @param ns
michael@0 95 * @param name
michael@0 96 * @param node
michael@0 97 * @param popName
michael@0 98 * @param attributes
michael@0 99 */
michael@0 100 StackNode(int flags, @NsUri String ns, @Local String name, T node,
michael@0 101 @Local String popName, HtmlAttributes attributes
michael@0 102 // [NOCPP[
michael@0 103 , TaintableLocatorImpl locator
michael@0 104 // ]NOCPP]
michael@0 105 ) {
michael@0 106 this.flags = flags;
michael@0 107 this.name = name;
michael@0 108 this.popName = popName;
michael@0 109 this.ns = ns;
michael@0 110 this.node = node;
michael@0 111 this.attributes = attributes;
michael@0 112 this.refcount = 1;
michael@0 113 // [NOCPP[
michael@0 114 this.locator = locator;
michael@0 115 // ]NOCPP]
michael@0 116 }
michael@0 117
michael@0 118 /**
michael@0 119 * Short hand for well-known HTML elements.
michael@0 120 *
michael@0 121 * @param elementName
michael@0 122 * @param node
michael@0 123 */
michael@0 124 StackNode(ElementName elementName, T node
michael@0 125 // [NOCPP[
michael@0 126 , TaintableLocatorImpl locator
michael@0 127 // ]NOCPP]
michael@0 128 ) {
michael@0 129 this.flags = elementName.getFlags();
michael@0 130 this.name = elementName.name;
michael@0 131 this.popName = elementName.name;
michael@0 132 this.ns = "http://www.w3.org/1999/xhtml";
michael@0 133 this.node = node;
michael@0 134 this.attributes = null;
michael@0 135 this.refcount = 1;
michael@0 136 assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
michael@0 137 // [NOCPP[
michael@0 138 this.locator = locator;
michael@0 139 // ]NOCPP]
michael@0 140 }
michael@0 141
michael@0 142 /**
michael@0 143 * Constructor for HTML formatting elements.
michael@0 144 *
michael@0 145 * @param elementName
michael@0 146 * @param node
michael@0 147 * @param attributes
michael@0 148 */
michael@0 149 StackNode(ElementName elementName, T node, HtmlAttributes attributes
michael@0 150 // [NOCPP[
michael@0 151 , TaintableLocatorImpl locator
michael@0 152 // ]NOCPP]
michael@0 153 ) {
michael@0 154 this.flags = elementName.getFlags();
michael@0 155 this.name = elementName.name;
michael@0 156 this.popName = elementName.name;
michael@0 157 this.ns = "http://www.w3.org/1999/xhtml";
michael@0 158 this.node = node;
michael@0 159 this.attributes = attributes;
michael@0 160 this.refcount = 1;
michael@0 161 assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
michael@0 162 // [NOCPP[
michael@0 163 this.locator = locator;
michael@0 164 // ]NOCPP]
michael@0 165 }
michael@0 166
michael@0 167 /**
michael@0 168 * The common-case HTML constructor.
michael@0 169 *
michael@0 170 * @param elementName
michael@0 171 * @param node
michael@0 172 * @param popName
michael@0 173 */
michael@0 174 StackNode(ElementName elementName, T node, @Local String popName
michael@0 175 // [NOCPP[
michael@0 176 , TaintableLocatorImpl locator
michael@0 177 // ]NOCPP]
michael@0 178 ) {
michael@0 179 this.flags = elementName.getFlags();
michael@0 180 this.name = elementName.name;
michael@0 181 this.popName = popName;
michael@0 182 this.ns = "http://www.w3.org/1999/xhtml";
michael@0 183 this.node = node;
michael@0 184 this.attributes = null;
michael@0 185 this.refcount = 1;
michael@0 186 // [NOCPP[
michael@0 187 this.locator = locator;
michael@0 188 // ]NOCPP]
michael@0 189 }
michael@0 190
michael@0 191 /**
michael@0 192 * Constructor for SVG elements. Note that the order of the arguments is
michael@0 193 * what distinguishes this from the HTML constructor. This is ugly, but
michael@0 194 * AFAICT the least disruptive way to make this work with Java's generics
michael@0 195 * and without unnecessary branches. :-(
michael@0 196 *
michael@0 197 * @param elementName
michael@0 198 * @param popName
michael@0 199 * @param node
michael@0 200 */
michael@0 201 StackNode(ElementName elementName, @Local String popName, T node
michael@0 202 // [NOCPP[
michael@0 203 , TaintableLocatorImpl locator
michael@0 204 // ]NOCPP]
michael@0 205 ) {
michael@0 206 this.flags = prepareSvgFlags(elementName.getFlags());
michael@0 207 this.name = elementName.name;
michael@0 208 this.popName = popName;
michael@0 209 this.ns = "http://www.w3.org/2000/svg";
michael@0 210 this.node = node;
michael@0 211 this.attributes = null;
michael@0 212 this.refcount = 1;
michael@0 213 // [NOCPP[
michael@0 214 this.locator = locator;
michael@0 215 // ]NOCPP]
michael@0 216 }
michael@0 217
michael@0 218 /**
michael@0 219 * Constructor for MathML.
michael@0 220 *
michael@0 221 * @param elementName
michael@0 222 * @param node
michael@0 223 * @param popName
michael@0 224 * @param markAsIntegrationPoint
michael@0 225 */
michael@0 226 StackNode(ElementName elementName, T node, @Local String popName,
michael@0 227 boolean markAsIntegrationPoint
michael@0 228 // [NOCPP[
michael@0 229 , TaintableLocatorImpl locator
michael@0 230 // ]NOCPP]
michael@0 231 ) {
michael@0 232 this.flags = prepareMathFlags(elementName.getFlags(),
michael@0 233 markAsIntegrationPoint);
michael@0 234 this.name = elementName.name;
michael@0 235 this.popName = popName;
michael@0 236 this.ns = "http://www.w3.org/1998/Math/MathML";
michael@0 237 this.node = node;
michael@0 238 this.attributes = null;
michael@0 239 this.refcount = 1;
michael@0 240 // [NOCPP[
michael@0 241 this.locator = locator;
michael@0 242 // ]NOCPP]
michael@0 243 }
michael@0 244
michael@0 245 private static int prepareSvgFlags(int flags) {
michael@0 246 flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
michael@0 247 | ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
michael@0 248 if ((flags & ElementName.SCOPING_AS_SVG) != 0) {
michael@0 249 flags |= (ElementName.SCOPING | ElementName.SPECIAL | ElementName.HTML_INTEGRATION_POINT);
michael@0 250 }
michael@0 251 return flags;
michael@0 252 }
michael@0 253
michael@0 254 private static int prepareMathFlags(int flags,
michael@0 255 boolean markAsIntegrationPoint) {
michael@0 256 flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
michael@0 257 | ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
michael@0 258 if ((flags & ElementName.SCOPING_AS_MATHML) != 0) {
michael@0 259 flags |= (ElementName.SCOPING | ElementName.SPECIAL);
michael@0 260 }
michael@0 261 if (markAsIntegrationPoint) {
michael@0 262 flags |= ElementName.HTML_INTEGRATION_POINT;
michael@0 263 }
michael@0 264 return flags;
michael@0 265 }
michael@0 266
michael@0 267 @SuppressWarnings("unused") private void destructor() {
michael@0 268 Portability.delete(attributes);
michael@0 269 }
michael@0 270
michael@0 271 public void dropAttributes() {
michael@0 272 attributes = null;
michael@0 273 }
michael@0 274
michael@0 275 // [NOCPP[
michael@0 276 /**
michael@0 277 * @see java.lang.Object#toString()
michael@0 278 */
michael@0 279 @Override public @Local String toString() {
michael@0 280 return name;
michael@0 281 }
michael@0 282
michael@0 283 // ]NOCPP]
michael@0 284
michael@0 285 public void retain() {
michael@0 286 refcount++;
michael@0 287 }
michael@0 288
michael@0 289 public void release() {
michael@0 290 refcount--;
michael@0 291 if (refcount == 0) {
michael@0 292 Portability.delete(this);
michael@0 293 }
michael@0 294 }
michael@0 295 }

mercurial