package fitnesse.slim.converters; import org.htmlparser.Node; import org.htmlparser.Parser; import org.htmlparser.filters.TagNameFilter; import org.htmlparser.tags.CompositeTag; import org.htmlparser.util.NodeList; import org.htmlparser.util.ParserException; import java.beans.PropertyEditorSupport; import java.util.HashMap; public class MapEditor extends PropertyEditorSupport { private NodeList nodes; private NodeList tables; public MapEditor() { } public String toString(Object o) { return "TILT"; } @Override public void setAsText(String s) throws IllegalArgumentException { setValue(fromString(s)); } public Object fromString(String possibleTable) { HashMap<String, String> map = new HashMap<String, String>(); if (tableIsValid(possibleTable)) extractRowsIntoMap(map, tables); return map; } private boolean tableIsValid(String possibleTable) { if (isValidHtml(possibleTable)) { return hasOneTable(); } else { return false; } } private boolean hasOneTable() { TagNameFilter tableFilter = new TagNameFilter("table"); tables = nodes.extractAllNodesThatMatch(tableFilter); return tables.size() == 1; } private boolean isValidHtml(String possibleTable) { nodes = parseHtml(possibleTable); return nodes != null; } private void extractRowsIntoMap(HashMap<String, String> map, NodeList tables) { extractRows(map, getRows(tables)); } private void extractRows(HashMap<String, String> map, NodeList rows) { for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) { extractRow(map, rows, rowIndex); } } private void extractRow(HashMap<String, String> map, NodeList rows, int rowIndex) { Node row = rows.elementAt(rowIndex); if (row != null) extractColumns(map, row); } private void extractColumns(HashMap<String, String> map, Node row) { TagNameFilter tdFilter = new TagNameFilter("td"); if (row.getChildren() != null) { NodeList cols = row.getChildren().extractAllNodesThatMatch(tdFilter); if (cols.size() == 2) addColsToMap(map, cols); } } private void addColsToMap(HashMap<String, String> map, NodeList cols) { String key = getText(cols.elementAt(0)); String value = getText(cols.elementAt(1)); map.put(key, value); } private NodeList getRows(NodeList tables) { TagNameFilter trFilter = new TagNameFilter("tr"); Node table = tables.elementAt(0); if (table.getChildren() != null) return table.getChildren().extractAllNodesThatMatch(trFilter); return new NodeList(); } private String getText(Node compositeNode) { return ((CompositeTag) compositeNode).getChildrenHTML(); } private NodeList parseHtml(String possibleTable) { try { Parser parser = new Parser(possibleTable); return parser.parse(null); } catch (ParserException e) { return null; } } }