LoaderTabXmlHandler.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ostrichemulators.semtool.poi.main.xlsxml;
import com.ostrichemulators.semtool.poi.main.ImportValidationException;
import com.ostrichemulators.semtool.poi.main.ImportValidationException.ErrorType;
import com.ostrichemulators.semtool.poi.main.SheetType;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* An XML parser that handles the Loading Sheet's "Loader" tab
*
* @author ryan
*/
public class LoaderTabXmlHandler extends XlsXmlBase {
private static final Logger log = Logger.getLogger( LoaderTabXmlHandler.class );
private final Map<String, SheetType> sheettypes = new HashMap<>();
private final Map<String, String> rawdata = new LinkedHashMap<>();
private int rownum;
private int colnum;
private String colA;
private boolean isstring = false;
public LoaderTabXmlHandler( List<String> sst ) {
super( sst );
}
public Map<String, SheetType> getSheetTypes() {
return new HashMap<>( sheettypes );
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
rawdata.clear();
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
rownum = 0;
boolean mustHaveType = true;
for ( Map.Entry<String, String> en : rawdata.entrySet() ) {
String rawA = en.getKey();
String rawB = en.getValue();
if ( 0 == rownum ) {
mustHaveType = verifyHeaders( rawA, rawB );
}
else {
boolean stopnow = !fillInRow( rawA, rawB, mustHaveType );
if ( stopnow ) {
break;
}
}
rownum++;
}
}
@Override
public void startElement( String uri, String localName, String name,
Attributes attributes ) throws SAXException {
switch ( name ) {
case "row":
rownum = Integer.parseInt( attributes.getValue( "r" ) ) - 1;
colA = "";
break;
case "c": // c is a new cell
String celltypestr = attributes.getValue( "t" );
isstring = ( "s".equals( celltypestr ) );
String colname = attributes.getValue( "r" );
colnum = LoadingSheetXmlHandler.getColNum( colname.substring( 0,
colname.lastIndexOf( Integer.toString( rownum + 1 ) ) ) );
break;
case "v": // new value for a cell
setReading( isstring );
resetContents();
break;
}
}
@Override
public void endElement( String uri, String localName, String name )
throws SAXException {
if ( isReading() ) {
String val = getStringFromContentsInt();
if ( 0 == colnum ) {
colA = val;
rawdata.put( val, null );
}
else if ( 1 == colnum ) {
rawdata.put( colA, val );
}
else if ( !decomment( val ).isEmpty() ) {
throw new ImportValidationException( ErrorType.TOO_MUCH_DATA,
"Too much data in row " + rownum );
}
setReading( false );
}
}
private static String decomment( String str ) {
if( null == str ){
return "";
}
return str.replaceAll( "#.*", "" );
}
private boolean verifyHeaders( String rawA, String rawB ) {
boolean mustHaveType = false;
if ( !"Sheet Name".equalsIgnoreCase( rawA ) ) {
throw new ImportValidationException( ErrorType.MISSING_DATA,
"Cell A1 must be \"Sheet Name\"" );
}
String bcol = decomment( rawB );
if ( !( bcol.isEmpty() || "Type".equalsIgnoreCase( bcol ) ) ) {
throw new ImportValidationException( ErrorType.MISSING_DATA,
"Cell B1 must be \"Type\" if not omitted" );
}
else {
mustHaveType = !bcol.isEmpty();
}
return mustHaveType;
}
/**
* Fills in a new sheet type
*
* @param rawA
* @param rawB
* @param mustHaveB
* @return true if processing should continue to the next row. false ends the
* data processing loop
*/
private boolean fillInRow( String rawA, String rawB, boolean mustHaveType ) {
if ( rawA.startsWith( "#" ) ) {
return true;
}
if ( rawA.isEmpty() && rawB.isEmpty() ) {
log.debug( "empty row at " + ( rownum + 1 ) + "...skipping rest of tab" );
return false;
}
String acol = decomment( rawA );
String bcol = decomment( rawB );
if ( bcol.isEmpty() ) {
if ( mustHaveType ) {
throw new ImportValidationException( ErrorType.MISSING_DATA,
"No type specified for sheet " + colA );
}
else {
sheettypes.put( acol, SheetType.UNSPECIFIED );
}
}
else {
if ( "usual".equalsIgnoreCase( bcol ) ) {
sheettypes.put( acol, SheetType.USUAL );
}
else if ( "metadata".equalsIgnoreCase( bcol ) ) {
sheettypes.put( acol, SheetType.METADATA );
}
else {
throw new ImportValidationException( ErrorType.INVALID_TYPE,
"Column B" + ( rownum + 1 )
+ " must be either \"Usual\", or \"Metadata\"" );
}
}
return true;
}
}