package org.autoplot.html;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
/**
* Stream the table into an AsciiTableStreamer.
* @author jbf
*/
public class HtmlParserStreamer extends HTMLEditorKit.ParserCallback {
private static final Logger logger= Logger.getLogger("apdss.html");
int tableCount = -1;
int itable=0;
String stable= null;
boolean inTable = false;
List currentRow;
int fieldCount = -1;
boolean inField = false;
String fieldText = "";
int recordCount= -1;
boolean isHeader= false;
int icolspan;
AsciiTableStreamer ascii= new AsciiTableStreamer();
List tables= new ArrayList();
/**
* set the table to read.
* @param name
*/
void setTable( String name ) {
int i= name.indexOf(":");
if ( i>-1 ) name= name.substring(0,i);
this.stable= name;
try {
itable= Integer.parseInt(name);
} catch ( NumberFormatException ex ) {
itable= -1;
}
}
/**
* set the units for the columns.
* @param units
*/
void setUnits(String units) {
ascii.setUnits( units );
}
@Override
public void handleText(char[] data, int pos) {
if (inField) {
fieldText += new String(data);
if (fieldText.length() > 30) {
fieldText = fieldText.substring(0, 27) + "...";
}
}
}
private List currentTableName= new ArrayList(); // tables can be nested
int nest=0;
@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
logger.fine("startTag "+t + " @"+pos);
if ( t==HTML.Tag.TABLE ) {
logger.fine("startTag table");
tableCount++;
nest++;
recordCount= 0;
String tableName= (String)a.getAttribute("id");
if ( tableName==null ) tableName= ""+tableCount;
currentTableName.add( tableName );
if ( itable>-1 ) {
if ( tableCount==itable ) inTable= true;
} else {
if ( stable.equals( a.getAttribute("id") ) ) inTable= true;
}
} else if ( inTable ) {
if (t == HTML.Tag.TR) {
currentRow = new ArrayList<>();
} else if (t == HTML.Tag.TH) {
String colspan= (String) a.getAttribute(HTML.Attribute.COLSPAN);
icolspan= ( colspan!=null ) ? Integer.parseInt(colspan) : 1;
inField = true;
fieldText = "";
isHeader= true;
} else if (t == HTML.Tag.TD) {
inField = true;
fieldText = "";
isHeader= false;
}
}
}
@Override
public void handleEndTag(HTML.Tag t, int pos) {
logger.log(Level.FINE, "endTag {0} @{1}", new Object[]{t, pos});
if (t == HTML.Tag.TABLE) {
nest--;
String dim;
if ( fieldCount>-1 ) {
dim= recordCount + " rows, "+fieldCount+ " colums";
} else {
dim= recordCount + " rows";
}
//if ( nest==0 ) {
if ( currentTableName.isEmpty() ) throw new IllegalArgumentException("table html syntax");
tables.add( currentTableName.remove(0) + ": "+dim );
//}
if ( inTable ) inTable= false;
} else if ( inTable ) {
if (t == HTML.Tag.TR) {
if (fieldCount == -1) {
fieldCount = currentRow.size();
}
if (currentRow.size() != fieldCount) {
logger.fine("skipping row because of field count");
return;
}
if ( isHeader ) {
ascii.addHeader( currentRow );
} else {
if ( ascii.hasHeader()==false ) {
List values= new ArrayList();
boolean haveNumber= false;
for ( int i=0; i getTables() {
return new ArrayList<>(tables);
}
}