1 // This file is part of TagSoup and is Copyright 2002-2008 by John Cowan. 2 // 3 // TagSoup is licensed under the Apache License, 4 // Version 2.0. You may obtain a copy of this license at 5 // http://www.apache.org/licenses/LICENSE-2.0 . You may also have 6 // additional legal rights not granted by this license. 7 // 8 // TagSoup is distributed in the hope that it will be useful, but 9 // unless required by applicable law or agreed to in writing, TagSoup 10 // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 11 // OF ANY KIND, either express or implied; not even the implied warranty 12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 package org.ccil.cowan.tagsoup; 15 16 /** 17 The internal representation of an actual element (not an element type). 18 An Element has an element type, attributes, and a successor Element 19 for use in constructing stacks and queues of Elements. 20 @see ElementType 21 @see AttributesImpl 22 */ 23 public class Element { 24 25 26 private ElementType theType; // type of element 27 private AttributesImpl theAtts; // attributes of element 28 private Element theNext; // successor of element 29 private boolean preclosed; // this element has been preclosed 30 31 /** 32 Return an Element from a specified ElementType. 33 @param type The element type of the newly constructed element 34 @param defaultAttributes True if default attributes are wanted 35 */ 36 Element(ElementType type, boolean defaultAttributes)37 public Element(ElementType type, boolean defaultAttributes) { 38 theType = type; 39 if (defaultAttributes) theAtts = new AttributesImpl(type.atts()); 40 else theAtts = new AttributesImpl(); 41 theNext = null; 42 preclosed = false; 43 } 44 45 /** 46 Return the element type. 47 @return The element type. 48 */ 49 type()50 public ElementType type() { return theType; } 51 52 /** 53 Return the attributes as an AttributesImpl object. 54 Returning an AttributesImpl makes the attributes mutable. 55 @return The attributes 56 @see AttributesImpl 57 */ atts()58 public AttributesImpl atts() { return theAtts; } 59 60 /** 61 Return the next element in an element stack or queue. 62 @return The next element 63 */ 64 next()65 public Element next() { return theNext; } 66 67 /** 68 Change the next element in an element stack or queue. 69 @param next The new next element 70 */ 71 setNext(Element next)72 public void setNext(Element next) { theNext = next; } 73 74 /** 75 Return the name of the element's type. 76 Convenience method. 77 @return The element type name 78 */ 79 name()80 public String name() { return theType.name(); } 81 82 /** 83 Return the namespace name of the element's type. 84 Convenience method. 85 @return The element type namespace name 86 */ 87 namespace()88 public String namespace() { return theType.namespace(); } 89 90 /** 91 Return the local name of the element's type. 92 Convenience method. 93 @return The element type local name 94 */ 95 localName()96 public String localName() { return theType.localName(); } 97 98 /** 99 Return the content model vector of the element's type. 100 Convenience method. 101 @return The content model vector 102 */ 103 model()104 public int model() { return theType.model(); } 105 106 /** 107 Return the member-of vector of the element's type. 108 Convenience method. 109 @return The member-of vector 110 */ 111 memberOf()112 public int memberOf() { return theType.memberOf(); } 113 114 /** 115 Return the flags vector of the element's type. 116 Convenience method. 117 @return The flags vector 118 */ 119 flags()120 public int flags() { return theType.flags(); } 121 122 /** 123 Return the parent element type of the element's type. 124 Convenience method. 125 @return The parent element type 126 */ 127 parent()128 public ElementType parent() { return theType.parent(); } 129 130 /** 131 Return true if the type of this element can contain the type of 132 another element. 133 Convenience method. 134 @param other The other element 135 */ 136 canContain(Element other)137 public boolean canContain(Element other) { 138 return theType.canContain(other.theType); 139 } 140 141 142 /** 143 Set an attribute and its value into this element. 144 @param name The attribute name (Qname) 145 @param type The attribute type 146 @param value The attribute value 147 */ 148 setAttribute(String name, String type, String value)149 public void setAttribute(String name, String type, String value) { 150 theType.setAttribute(theAtts, name, type, value); 151 } 152 153 /** 154 Make this element anonymous. 155 Remove any <tt>id</tt> or <tt>name</tt> attribute present 156 in the element's attributes. 157 */ 158 anonymize()159 public void anonymize() { 160 for (int i = theAtts.getLength() - 1; i >= 0; i--) { 161 if (theAtts.getType(i).equals("ID") || 162 theAtts.getQName(i).equals("name")) { 163 theAtts.removeAttribute(i); 164 } 165 } 166 } 167 168 /** 169 Clean the attributes of this element. 170 Attributes with null name (the name was ill-formed) 171 or null value (the attribute was present in the element type but 172 not in this actual element) are removed. 173 */ 174 clean()175 public void clean() { 176 for (int i = theAtts.getLength() - 1; i >= 0; i--) { 177 String name = theAtts.getLocalName(i); 178 if (theAtts.getValue(i) == null || name == null || 179 name.length() == 0) { 180 theAtts.removeAttribute(i); 181 continue; 182 } 183 } 184 } 185 186 /** 187 Force this element to preclosed status, meaning that an end-tag has 188 been seen but the element cannot yet be closed for structural reasons. 189 */ 190 preclose()191 public void preclose() { 192 preclosed = true; 193 } 194 195 /** 196 Return true if this element has been preclosed. 197 */ 198 isPreclosed()199 public boolean isPreclosed() { 200 return preclosed; 201 } 202 203 } 204