Home | History | Annotate | Download | only in tagsoup
      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 
     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 
     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 	*/
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    191 	public void preclose() {
    192 		preclosed = true;
    193 		}
    194 
    195 	/**
    196 	Return true if this element has been preclosed.
    197 	*/
    198 
    199 	public boolean isPreclosed() {
    200 		return preclosed;
    201 		}
    202 
    203 	}
    204