// Copyright � 2002-2005 Canoo Engineering AG, Switzerland. package com.canoo.webtest.steps; import com.gargoylesoftware.htmlunit.html.HTMLParserListener; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Represents a message generated by an html parser. * @author Marc Guillemot */ public class HtmlParserMessage implements Comparable { /** * Safe enum to represent the type of a message. */ public static final class Type implements Comparable { public static final String ERROR_NAME = "error"; public static final String WARNING_NAME = "warning"; public static final Type ERROR = new Type(ERROR_NAME); public static final Type WARNING = new Type(WARNING_NAME); private String fName; /** * Private constructor to prohibit external instantiations * @param str */ private Type(final String str) { fName = str; } /** * Compares with following rule: error > warning * (no need to override equals(): in this case it is equivalent to ==) * * @throws ClassCastException if the argument is not a {@link HtmlParserMessage.Type} */ public int compareTo(final Object o) { final Type other = (Type) o; if (getName().equals(other.getName())) return 0; else return isError() ? 1 : -1; } /** * Gets the name of the type */ public String getName() { return fName; } public boolean isError() { return ERROR_NAME.equals(getName()); } public boolean isWarning() { return WARNING_NAME.equals(getName()); } /** * Gets the name. */ public String toString() { return getName(); } } /** * Listener collecting the messages from parser. */ public static class MessageCollector implements HTMLParserListener { private List<HtmlParserMessage> fMessages = new ArrayList<HtmlParserMessage>(); public void error(final String message, final URL url, final int line, final int column, final String key) { fMessages.add(new HtmlParserMessage(Type.ERROR, url, message, line, column)); } public void warning(final String message, final URL url, final int line, final int column, final String key) { fMessages.add(new HtmlParserMessage(Type.WARNING, url, message, line, column)); } /** * Gets all messages received since last call to this method. * @return a list of {@link HtmlParserMessage} */ public List popAll() { final List l = fMessages; fMessages = new ArrayList<HtmlParserMessage>(); return l; } } private int fColumn; private int fLine; private String fMessage; private Type fType; private URL fUrl; private volatile int fHash; public HtmlParserMessage(final Type type, final URL url, final String strMessage, final int iLine, final int iColumn) { fType = type; fUrl = url; fMessage = strMessage; fLine = iLine; fColumn = iColumn; } /** * Compare to an other HtmlParserMessage according to (url, line, col, type, msg) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(final Object o) { final HtmlParserMessage other = (HtmlParserMessage) o; // first compare urls int iRep = getURL().toString().compareTo(other.getURL().toString()); if (iRep != 0) return iRep; // then line in file iRep = getLine() - other.getLine(); if (iRep != 0) return iRep; // then column in line iRep = getColumn() - other.getColumn(); if (iRep != 0) return iRep; // error or warning iRep = getType().compareTo(other.getType()); if (iRep != 0) return iRep; // and at least the message return getMessage().compareTo(other.getMessage()); } public int hashCode() { if (fHash == 0) fHash = calculateHash(); return fHash; } private int calculateHash() { // aggregate of primes multiplied by hashes of components final int h1 = 3 * new Integer(fColumn).hashCode(); final int h2 = 5 * new Integer(fLine).hashCode(); final int h3 = 7 * fMessage.hashCode(); final int h4 = 11 * fType.hashCode(); final int h5 = 13 * fUrl.hashCode(); return h1 + h2 + h3 + h4 + h5; } /** * Test for equality with an other HtmlParserMessage according to (url, line, col, type, msg) * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(final Object o) { return compareTo(o) == 0; } /** * Gets the column in the source file for which the message has been generated */ public int getColumn() { return fColumn; } /** * Gets the line in the source file for which the message has been generated */ public int getLine() { return fLine; } /** * Gets the description of the message */ public String getMessage() { return fMessage; } /** * Gets the type of the message determining its severity */ public Type getType() { return fType; } /** * Gets the url of the file which parsing caused this message. */ public URL getURL() { return fUrl; } }