// CSE 143, Winter 2010, Marty Stepp
// An HtmlTag object represents an HTML tag, such as or .
// In this version of HtmlTag we added a compareTo method and made the
// class implement Comparable.
import java.util.*;
public class HtmlTag implements Comparable {
// fields
private final String element;
private final boolean isOpenTag;
public int compareTo(HtmlTag other) {
// compare alphabetically
// if ABC is tied, put opening before closing
// first compare element strings
int comp = element.compareTo(other.getElement());
if (comp != 0) {
return comp;
} else {
// break ties by comparing open/closed (open comes first)
if (isOpenTag == other.isOpenTag()) {
return 0;
} else if (isOpenTag) {
return -1;
} else {
return 1;
}
}
}
/**
* Constructs an HTML "opening" tag with the given element (e.g. "table").
* Throws a NullPointerException if element is null.
*/
public HtmlTag(String element) {
this(element, true);
}
/**
* Constructs an HTML tag with the given element (e.g. "table") and type.
* Self-closing tags like
are considered to be "opening" tags,
* but return false from the requiresClosingTag method.
* Throws a NullPointerException if element is null.
*/
public HtmlTag(String element, boolean isOpenTag) {
this.element = element.toLowerCase();
this.isOpenTag = isOpenTag;
}
/**
* Returns true if this tag has the same element and type as the
* given other tag.
*/
public boolean equals(Object o) {
if (o instanceof HtmlTag) {
HtmlTag other = (HtmlTag) o;
return element.equals(other.element) && isOpenTag == other.isOpenTag;
} else {
return false;
}
}
/** Returns this HTML tag's element. */
public String getElement() {
return element;
}
/**
* Returns true if this HTML tag is an "opening" (starting) tag and false
* if it is a closing tag.
* Self-closing tags like
are considered to be "opening" tags,
* but they return false from the requiresClosingTag method.
*/
public boolean isOpenTag() {
return isOpenTag;
}
/**
* Returns true if the given other tag is non-null and matches this tag;
* that is, if they have the same element but opposite types,
* such as and .
*/
public boolean matches(HtmlTag other) {
return other != null && element.equals(other.element) && isOpenTag != other.isOpenTag;
}
/**
* Returns true if this tag requires a matching closing tag; usually this
* is true, except for certain elements such as br and img.
*/
public boolean isSelfClosing() {
return SELF_CLOSING_TAGS.contains(element);
}
/** Returns a string representation of this HTML tag, such as "". */
public String toString() {
return "<" + (isOpenTag ? "" : "/") + (element.equals("!--") ? "!-- --" : element) + ">";
}
// a set of tags that don't need to be matched (self-closing)
private static final Set SELF_CLOSING_TAGS = new HashSet(
Arrays.asList("!doctype", "!--", "area", "base", "basefont",
"br", "col", "frame", "hr", "img", "input",
"link", "meta", "param"));
}