/* * $Id: TableElementModel.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $ * Copyright Narushima Hironori. All rights reserved. */ package net.sourceforge.phpeclipse.wizards.html; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * TableElementModel */ public class TableElementModel { final static char[] CHAR_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); StringDivider stringDivider = new StringDivider(); ElementWriter writer; DocumentBuilder docBuilder; Document document; Element tableElement; String[] columnProperties; public TableElementModel(String content, boolean parse) throws FactoryConfigurationError, ParserConfigurationException, SAXException, IOException { docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); if (parse) { initAsParse(content); } else { initModel(content); } columnProperties = createColumnProperties(); // create elementWriter writer = new ElementWriter(0, null); writer.setExpandOption("caption", ElementWriter.END_CHANGELINE); writer.setExpandOption("table", ElementWriter.BEGIN_CHANGELINE | ElementWriter.END_CHANGELINE); writer.setExpandOption("thead", ElementWriter.BEGIN_CHANGELINE | ElementWriter.END_CHANGELINE); writer.setExpandOption("tfoot", ElementWriter.BEGIN_CHANGELINE | ElementWriter.END_CHANGELINE); writer.setExpandOption("tbody", ElementWriter.BEGIN_CHANGELINE | ElementWriter.END_CHANGELINE); writer.setExpandOption("tr", ElementWriter.END_CHANGELINE); } void initModel(String content) throws ParserConfigurationException, SAXException, IOException { StringReader strReader = new StringReader(content); InputSource inputSrc = new InputSource(strReader); document = docBuilder.parse(inputSrc); tableElement = document.getDocumentElement(); Element[] rows = getRows(); for (int i = 0; i < rows.length; i++) { Element[] cells = chooseCellElements(rows[i]); for (int j = 0; j < cells.length; j++) { Element cell = cells[j]; if (!cell.hasChildNodes()) { cell.appendChild(document.createTextNode("")); } } } } public void initAsParse(String content) throws ParserConfigurationException, FactoryConfigurationError { // create new table model. document = docBuilder.newDocument(); tableElement = document.createElement("table"); String[][] cells = stringDivider.divide(content); if (cells.length > 0) { for (int i = 0; i < cells.length; i++) { String[] rows = cells[i]; Element tr = document.createElement("tr"); for (int j = 0; j < rows.length; j++) { Element e = document.createElement("td"); e.appendChild(document.createTextNode(rows[j])); tr.appendChild(e); } tableElement.appendChild(tr); } setColumnCount(cells[0].length); } else { Element tr = document.createElement("tr"); Element td = document.createElement("td"); td.appendChild(document.createTextNode("")); tr.appendChild(td); tableElement.appendChild(tr); setColumnCount(1); } } String[] createColumnProperties() { int len = getColumnCount(); String[] props = new String[len]; for (int i = 0; i < len; i++) { props[i] = toColumnName(i); } return props; } public void setRowCount(int rowCount) { Element[] rows = getRows(); if (rowCount > rows.length) { for (int i = rows.length; i < rowCount; i++) { tableElement.appendChild(createRowElement()); } } else if (rowCount < rows.length) { for (int i = rowCount; i < rows.length; i++) { tableElement.removeChild(rows[i]); } } } public Element[] getRows() { ArrayList rows = new ArrayList(); NodeList nodes = tableElement.getElementsByTagName("tr"); for (int i = 0; i < nodes.getLength(); i++) { rows.add(nodes.item(i)); } return (Element[]) rows.toArray(new Element[rows.size()]); } public int getRowCount() { return getRows().length; } Element createRowElement() { Element tr = document.createElement("tr"); for (int i = 0, columnCount = getColumnCount(); i < columnCount; i++) { Element td = document.createElement("td"); td.appendChild(document.createTextNode("")); tr.appendChild(td); } return tr; } public void setColumnCount(int newLength) { NodeList trs = tableElement.getElementsByTagName("tr"); for (int i = 0; i < trs.getLength(); i++) { Element tr = (Element) trs.item(i); Element[] cells = chooseCellElements(tr); int colLen = cells.length; if (newLength > colLen) { for (int j = 0, len = newLength - colLen; j < len; j++) { Element cell = document.createElement("td"); cell.appendChild(document.createTextNode("")); tr.appendChild(cell); } } else if (newLength < colLen) { for (int j = newLength; j < colLen; j++) { tr.removeChild(cells[j]); } } } columnProperties = createColumnProperties(); } public int getColumnCount() { NodeList trs = tableElement.getElementsByTagName("tr"); if (trs.getLength() > 0) { Element tr = (Element) trs.item(0); return chooseCellElements(tr).length; } else { return 0; } } public static Element[] chooseCellElements(Element tr) { NodeList nodeList = tr.getChildNodes(); ArrayList result = new ArrayList(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node instanceof Element) { String nodeName = node.getNodeName(); if (nodeName.equals("td") || nodeName.equals("th")) { result.add(node); } } } return (Element[]) result.toArray(new Element[result.size()]); } public String expandCodes() { return writer.expandTag(tableElement); } public static String toColumnName(int i) { StringBuffer buff = new StringBuffer(); int u = i / CHAR_TABLE.length; if (u > 0) { buff.append(CHAR_TABLE[u - 1]); } buff.append(CHAR_TABLE[i % CHAR_TABLE.length]); return buff.toString(); } /** * Return index of char map. If can not parse values return -1. */ public static int toNumeric(String code) { int result = -1; for (int i = 0; i < code.length(); i++) { char c = code.charAt(i); int match = Arrays.binarySearch(CHAR_TABLE, c); if (match >= 0) { if (result == -1) { result = 0; } int v = match; int u = code.length() - 1 - i; if (u > 0) { v = CHAR_TABLE.length * u * (v + 1); } result += v; } } return result; } public void move(Element tr, int moveCount) { Element[] rows = getRows(); int index = -1; for (int i = 0; i < rows.length; i++) { if (tr.equals(rows[i])) { index = i; } } if (index == -1) { throw new IllegalArgumentException( "Invalid row node (not countained in this table):" + tr); } if (moveCount > 0) { // move down; for (int i = index; i < moveCount + index && i < rows.length - 1; i++) { tableElement.insertBefore(rows[i + 1], rows[i]); } } else if (moveCount < 0) { // move up for (int i = index; i >= moveCount + index + 1 && i >= 1; i--) { tableElement.insertBefore(rows[index], rows[i - 1]); } } else { return; } } public void insertNewRowBefore(Element tr) { Element newRow = createRowElement(); if (tr == null) { tableElement.appendChild(newRow); } else { tableElement.insertBefore(newRow, tr); } } public void removeRow(Element tr) { tableElement.removeChild(tr); } public String[] getColumnProperties() { return (String[]) columnProperties.clone(); } }