1.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/XhtmlFormatter.java Mon Mar 04 17:06:42 2019 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,262 +0,0 @@
1.4 -/**
1.5 - * SQL-DK
1.6 - * Copyright © 2014 František Kučera (frantovo.cz)
1.7 - *
1.8 - * This program is free software: you can redistribute it and/or modify
1.9 - * it under the terms of the GNU General Public License as published by
1.10 - * the Free Software Foundation, either version 3 of the License, or
1.11 - * (at your option) any later version.
1.12 - *
1.13 - * This program is distributed in the hope that it will be useful,
1.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 - * GNU General Public License for more details.
1.17 - *
1.18 - * You should have received a copy of the GNU General Public License
1.19 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.20 - */
1.21 -package info.globalcode.sql.dk.formatting;
1.22 -
1.23 -import info.globalcode.sql.dk.Constants;
1.24 -import info.globalcode.sql.dk.NamedParameter;
1.25 -import info.globalcode.sql.dk.Parameter;
1.26 -import info.globalcode.sql.dk.Xmlns;
1.27 -import info.globalcode.sql.dk.configuration.DatabaseDefinition;
1.28 -import info.globalcode.sql.dk.configuration.Properties;
1.29 -import info.globalcode.sql.dk.configuration.Property;
1.30 -import static info.globalcode.sql.dk.formatting.AbstractXmlFormatter.qname;
1.31 -import java.sql.Array;
1.32 -import java.sql.SQLException;
1.33 -import java.util.Date;
1.34 -import java.util.List;
1.35 -import java.util.Map;
1.36 -import java.util.Scanner;
1.37 -import java.util.logging.Level;
1.38 -import java.util.logging.Logger;
1.39 -import javax.xml.namespace.QName;
1.40 -
1.41 -/**
1.42 - * Prints result sets and parameters as tables, SQL as preformatted and updates counts as
1.43 - * paragraphs. You can pick XHTML fragments (usually tabular data) and use it on your website or use
1.44 - * whole output as preview or report.
1.45 - *
1.46 - * @author Ing. František Kučera (frantovo.cz)
1.47 - */
1.48 -public class XhtmlFormatter extends AbstractXmlFormatter {
1.49 -
1.50 - private static final Logger log = Logger.getLogger(XhtmlFormatter.class.getName());
1.51 - public static final String NAME = "xhtml"; // bash-completion:formatter
1.52 - private static final String DOCTYPE = "html PUBLIC \"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN\" \"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd\"";
1.53 - private static final String CSS_FILE = "info/globalcode/sql/dk/formatter/XhtmlFormatter.css";
1.54 - private int statementCounter = 0;
1.55 - private int resultSetCounter = 0;
1.56 - private int updatesResultCounter = 0;
1.57 -
1.58 - public XhtmlFormatter(FormatterContext formatterContext) {
1.59 - super(addDefaults(formatterContext));
1.60 - }
1.61 -
1.62 - /**
1.63 - * Do not indent text – preserve whitespace for pre elements
1.64 - */
1.65 - private static FormatterContext addDefaults(FormatterContext formatterContext) {
1.66 - Properties defaults = new Properties(1);
1.67 - defaults.add(new Property(PROPERTY_INDENT_TEXT, "false"));
1.68 - formatterContext.getProperties().setLastDefaults(defaults);
1.69 - return formatterContext;
1.70 - }
1.71 -
1.72 - @Override
1.73 - public void writeStartBatch() {
1.74 - super.writeStartBatch();
1.75 - printStartDocument();
1.76 - printDoctype(DOCTYPE);
1.77 - printStartElement(qname("html"), singleAttribute(qname("xmlns"), Xmlns.XHTML));
1.78 -
1.79 - printStartElement(qname("head"));
1.80 - printTextElement(qname("title"), null, Constants.PROGRAM_NAME + ": batch results");
1.81 - printCss();
1.82 - printEndElement();
1.83 -
1.84 - printStartElement(qname("body"));
1.85 - }
1.86 -
1.87 - private void printCss() {
1.88 -
1.89 - try (Scanner css = new Scanner(getClass().getClassLoader().getResourceAsStream(CSS_FILE))) {
1.90 - printStartElement(qname("style"), singleAttribute(qname("type"), "text/css"));
1.91 - while (css.hasNext()) {
1.92 - printText(css.nextLine(), true);
1.93 - }
1.94 - printEndElement();
1.95 - }
1.96 - }
1.97 -
1.98 - @Override
1.99 - public void writeEndBatch() {
1.100 - super.writeEndBatch();
1.101 - printEndElement();
1.102 - printEndElement();
1.103 - printEndDocument();
1.104 - }
1.105 -
1.106 - @Override
1.107 - public void writeStartDatabase(DatabaseDefinition databaseDefinition) {
1.108 - super.writeStartDatabase(databaseDefinition);
1.109 - printTextElement(qname("h1"), null, "Database: " + databaseDefinition.getName());
1.110 -
1.111 - printStartElement(qname("p"));
1.112 - printText("This is XHTML output of batch executed at: ", true);
1.113 - printText(new Date().toString(), true);
1.114 - printEndElement();
1.115 - }
1.116 -
1.117 - @Override
1.118 - public void writeQuery(String sql) {
1.119 - super.writeQuery(sql);
1.120 - printTextElement(qname("pre"), null, sql);
1.121 - }
1.122 -
1.123 - @Override
1.124 - public void writeParameters(List<? extends Parameter> parameters) {
1.125 - super.writeParameters(parameters);
1.126 -
1.127 - if (parameters == null || parameters.isEmpty()) {
1.128 - printTextElement(qname("p"), null, "(this query has no parameters)");
1.129 - } else {
1.130 - printTextElement(qname("h3"), null, "Parameters:");
1.131 -
1.132 - printStartElement(qname("table"));
1.133 -
1.134 - printStartElement(qname("thead"));
1.135 - printStartElement(qname("tr"));
1.136 - printTextElement(qname("td"), null, "id");
1.137 - printTextElement(qname("td"), null, "type");
1.138 - printTextElement(qname("td"), null, "value");
1.139 - printEndElement();
1.140 - printEndElement();
1.141 -
1.142 - printStartElement(qname("tbody"));
1.143 - for (int i = 0; i < parameters.size(); i++) {
1.144 - Parameter p = parameters.get(i);
1.145 - printStartElement(qname("tr"));
1.146 - String numberOrName;
1.147 - if (p instanceof NamedParameter) {
1.148 - numberOrName = ((NamedParameter) p).getName();
1.149 - } else {
1.150 - numberOrName = String.valueOf(i + 1);
1.151 - }
1.152 - printTextElement(qname("td"), null, numberOrName);
1.153 - printTextElement(qname("td"), null, p.getType().name());
1.154 - printTableData(p.getValue());
1.155 - printEndElement();
1.156 - }
1.157 - printEndElement();
1.158 -
1.159 - printEndElement();
1.160 - }
1.161 - }
1.162 -
1.163 - private void printTableData(Object value) {
1.164 -
1.165 - if (value instanceof Array) {
1.166 - Array sqlArray = (Array) value;
1.167 - try {
1.168 - Object[] array = (Object[]) sqlArray.getArray();
1.169 - printStartElement(qname("td"));
1.170 - printArray(array);
1.171 - printEndElement();
1.172 - } catch (SQLException e) {
1.173 - log.log(Level.SEVERE, "Unable to format array", e);
1.174 - printTableData(String.valueOf(value));
1.175 - }
1.176 - } else {
1.177 - Map<QName, String> attributes = null;
1.178 - if (value instanceof Number) {
1.179 - attributes = singleAttribute(qname("class"), "number");
1.180 - } else if (value instanceof Boolean) {
1.181 - attributes = singleAttribute(qname("class"), "boolean");
1.182 - }
1.183 - printTextElement(qname("td"), attributes, String.valueOf(value));
1.184 - }
1.185 - }
1.186 -
1.187 - private void printArray(Object[] array) {
1.188 - printStartElement(qname("ul"));
1.189 - for (Object o : array) {
1.190 - if (o instanceof Object[]) {
1.191 - printStartElement(qname("li"));
1.192 - printTextElement(qname("p"), null, "nested array:");
1.193 - printArray((Object[]) o);
1.194 - printEndElement();
1.195 - } else {
1.196 - printTextElement(qname("li"), null, String.valueOf(o));
1.197 - }
1.198 - }
1.199 - printEndElement();
1.200 - }
1.201 -
1.202 - @Override
1.203 - public void writeStartResultSet(ColumnsHeader header) {
1.204 - super.writeStartResultSet(header);
1.205 - resultSetCounter++;
1.206 - printEmptyElement(qname("hr"), null);
1.207 - printTextElement(qname("h3"), null, "Result set #" + resultSetCounter);
1.208 - printStartElement(qname("table"));
1.209 - printStartElement(qname("thead"));
1.210 - printStartElement(qname("tr"));
1.211 - for (ColumnDescriptor cd : header.getColumnDescriptors()) {
1.212 - // TODO: type
1.213 - printTextElement(qname("td"), null, cd.getLabel());
1.214 - }
1.215 - printEndElement();
1.216 - printEndElement();
1.217 -
1.218 - printStartElement(qname("tbody"));
1.219 - }
1.220 -
1.221 - @Override
1.222 - public void writeEndResultSet() {
1.223 - super.writeEndResultSet();
1.224 - printEndElement();
1.225 - printEndElement();
1.226 - printTextElement(qname("p"), null, "Record count: " + getCurrentRowCount());
1.227 - }
1.228 -
1.229 - @Override
1.230 - public void writeStartRow() {
1.231 - super.writeStartRow();
1.232 - printStartElement(qname("tr"));
1.233 - }
1.234 -
1.235 - @Override
1.236 - public void writeColumnValue(Object value) {
1.237 - super.writeColumnValue(value);
1.238 - printTableData(value);
1.239 - }
1.240 -
1.241 - @Override
1.242 - public void writeEndRow() {
1.243 - super.writeEndRow();
1.244 - printEndElement();
1.245 - }
1.246 -
1.247 - @Override
1.248 - public void writeStartStatement() {
1.249 - super.writeStartStatement();
1.250 - statementCounter++;
1.251 - printEmptyElement(qname("hr"), null);
1.252 - printTextElement(qname("h2"), null, "SQL statement #" + statementCounter);
1.253 - resultSetCounter = 0;
1.254 - updatesResultCounter = 0;
1.255 - }
1.256 -
1.257 - @Override
1.258 - public void writeUpdatesResult(int updatedRowsCount) {
1.259 - super.writeUpdatesResult(updatedRowsCount);
1.260 - updatesResultCounter++;
1.261 - printEmptyElement(qname("hr"), null);
1.262 - printTextElement(qname("h3"), null, "Updates result #" + updatesResultCounter);
1.263 - printTextElement(qname("p"), null, "Updated rows: " + updatedRowsCount);
1.264 - }
1.265 -}