StirEnergyResultSet.java [tools/WepsReportData/src/usda/weru/weps/reports/query] Revision: c98511c63ebd28d7fde8e7ece29a41d0f3642520  Date: Mon May 08 13:38:30 MDT 2017
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package usda.weru.weps.reports.query;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Types;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import usda.weru.util.ConfigData;
import usda.weru.util.ConversionCalculator;
import usda.weru.util.ConversionCalculator.ConversionNotFoundException;
import usda.weru.util.ConversionCalculator.UnitNotFoundException;
import usda.weru.util.Util;

/**
 *
 * @author joelevin
 */
public class StirEnergyResultSet extends WepsResultSet {

    private static final Logger LOGGER = Logger.getLogger(StirEnergyResultSet.class);

    // Names of the table and columns in the SQL data model.
    public static final String NAME = "stir_energy";
    public static final String OUTPUT_FILE = "stir_energy.out";
    public static final String COLUMN_PREFIX = NAME + ".";
    public static final String COLUMN_LINE = COLUMN_PREFIX + "line";
    public static final String COLUMN_STIR = COLUMN_PREFIX + "stir";
    public static final String COLUMN_ENERGY = COLUMN_PREFIX + "energy";    
    public static final String COLUMN_DATE = COLUMN_PREFIX + "date";
    public static final String COLUMN_OPERATION = COLUMN_PREFIX + "operation";
    public static final String COLUMN_CROP = COLUMN_PREFIX + "crop";
    public static final String COLUMN_FUEL = COLUMN_PREFIX + "fuel";
    public static final String COLUMN_FUELDEFAULT = COLUMN_PREFIX + "fueldefault";
    public static final String COLUMN_CROPNUMBER = COLUMN_PREFIX + "cropnumber";
    public static final String COLUMN_LASTHARVEST = COLUMN_PREFIX + "lastharvest";
    private static final String FORMAT_DATE = "dd/MM/yyyy";
//    private final WepsConnection c_con;
//    private boolean c_filled;

    // New member variables
    public String m_sDirectory;
    public String m_sUnits;
    private double conversionFactor;

    public StirEnergyResultSet(WepsConnection con, String sDirectory, String sUnits,double conversionFactor) {
        super(con);
        m_sDirectory = sDirectory;
        m_sUnits     = sUnits;
        this.conversionFactor = conversionFactor;
        
//        c_con = con;
//        addColumn(RunsResultSet.COLUMN_RUNID, Types.INTEGER, 10, 0);

        //stir file specific 
        addColumn(COLUMN_LINE, Types.INTEGER, 10, 0);
        
        //Columns expected in the file
        addColumn(COLUMN_DATE, Types.DATE, 0, 0);
        addColumn(COLUMN_OPERATION, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_CROP, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_FUEL, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_STIR, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_ENERGY, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_CROPNUMBER, Types.INTEGER, 10, 0);
        addColumn(COLUMN_LASTHARVEST, Types.BOOLEAN, 0, 0);
        addColumn(COLUMN_FUELDEFAULT, Types.BOOLEAN, 0, 0);
                
    }

    @Override
    public String getName() {
        return NAME;
    }
    
    protected boolean isUSUnits(){
        return Util.USUnits.equals(m_sUnits);
    }

    @Override
    public synchronized void fill() {
//        if (c_filled) {
//            return;
//        }
//        File[] files = c_con.getRunFiles();

        int i = 0;
//        for (int i = 0; i < files.length; i++) {
            File runDir = new File(m_sDirectory);
            File output = new File(runDir, OUTPUT_FILE);
            if (!output.exists()) {
                //no stir_energy file, might be an old run
                assert(false): "error: missing file" + OUTPUT_FILE ;
//                continue;
            }



            //Stir energy file specific
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new FileReader(output));

                //first line, flexible header
                String header = reader.readLine();
                header = header.replaceFirst("#", "");
                String[] columns = header.split("\\|", -1);     //-1 so we grab blank columns, just in case


                String line = getLine(reader); //skip the first non-comment line.
                int lineIndex = -1;
                while ((line = getLine(reader)) != null) {
                   //increment the line index for the next use.
                    lineIndex++;                    
                    
                    Object[] row = createNewRow(false);
                    //Always add the run id so that joins will work
//                    setRowValue(row, RunsResultSet.COLUMN_RUNID, i);
                    
                    //Add the lineIndex so things can be sorted if need be specific to this file
                    setRowValue(row, COLUMN_LINE, lineIndex);
                    
                    // Use -1 as the limit to allow String.split to return all 5 values regardless of whether they are
                    // blank or not.
                    String[] values = line.split("\\|", -1);
                    if (values.length != columns.length) {
                        //something changed in the file output format that is unexpected
                        LOGGER.warn("Unexpected number of columns on line " + lineIndex +  "; found " + values.length + ", expected " + columns.length + ". File: " + output.getAbsolutePath());
                        //go to the next line
                        continue;
                    }
                    
                    try{
                        String dateText = values[column(columns, "dd/mm/yyyy")].trim();
                        DateFormat format = new SimpleDateFormat(FORMAT_DATE);
                        Date date = format.parse(dateText);                        
                        setRowValue(row, COLUMN_DATE, new java.sql.Date(date.getTime()));
                    }
                    catch(NumberFormatException nfe){
                        LOGGER.warn("Unable to parse date in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    catch(ParseException pe){
                        LOGGER.warn("Unable to parse date in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    
                    
                    String operationText = values[column(columns, "operation")].trim();
                    setRowValue(row, COLUMN_OPERATION, operationText);
                    
                    String cropText = values[column(columns, "crop name")].trim();
                    setRowValue(row, COLUMN_CROP, cropText);

                    if(column(columns, "fuel") >= 0){
                        String fuelText = values[column(columns, "fuel")].trim();

                        //pull in default fuel if required
                        if(fuelText == null || fuelText.length() == 0){
                            fuelText = ConfigData.getDefault().getData(ConfigData.FuelDefault);
                            setRowValue(row, COLUMN_FUELDEFAULT, true);
                        }
                        else{
                            setRowValue(row, COLUMN_FUELDEFAULT, false);
                        }

                        setRowValue(row, COLUMN_FUEL,fuelText);
                    }
                    else{
                        String fuelText = ConfigData.getDefault().getData(ConfigData.FuelDefault);
                        setRowValue(row, COLUMN_FUEL, fuelText);
                        setRowValue(row, COLUMN_FUELDEFAULT, true);
                    }
                    
                    try{
                        String stirText = values[column(columns, "stir")].trim();
                        Double stir = Double.valueOf(stirText);
                       setRowValue(row, COLUMN_STIR, stir);
                    }                    
                    catch(NumberFormatException nfe){
                        LOGGER.warn("Unable to parse stir value in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    
                    try{
                        String energyText = values[column(columns, "energy")].trim();
                        Double energy = Double.valueOf(energyText);
                        if (isUSUnits()){
                            energy = ConversionCalculator.convert(energy, "L/ha", "gal/ac") * conversionFactor;;                            
                        }                        
                        setRowValue(row, COLUMN_ENERGY, energy);
                    }
                    catch(UnitNotFoundException unf){
                        LOGGER.warn("Unable to convert energy value in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    catch(ConversionNotFoundException cnf){
                        LOGGER.warn("Unable to convert energy value in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    catch(NumberFormatException nfe){
                        LOGGER.warn("Unable to parse energy value in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    
                    try{
                        String cropSequenceText = values[column(columns, "crop sequence")].trim();
                        Integer cropSequence = Integer.valueOf(cropSequenceText);
                        setRowValue(row, COLUMN_CROPNUMBER, cropSequence);                        
                    }
                    catch(NumberFormatException nfe){
                        LOGGER.warn("Unable to parse crop sequence value in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                    
                    try{
                        String lastHarvestText = values[column(columns, "1 if last")].trim();
                        Boolean lastHarvest = "1".equals(lastHarvestText);
                        setRowValue(row, COLUMN_LASTHARVEST, lastHarvest);                        
                    }
                    catch(NumberFormatException nfe){
                        LOGGER.warn("Unable to parse last harvest flag in file: " + output.getAbsolutePath() + " on line: " + lineIndex);
                    }
                addRow(row);

                }
            } catch (IOException ioe) {
                LOGGER.error("Error reading file: " + output.getAbsolutePath(), ioe);
//                throw new SQLException("Error reading file: " + output.getAbsolutePath(), ioe);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (Exception e) {
                        LOGGER.error("Error closing file: " + output.getAbsolutePath(), e);
                    }
                }
            }


//        }

//        c_filled = true;
    }

    private int column(String[] columns, String startsWith){
        for(int i = 0; i < columns.length; i++){
            if(columns[i].toLowerCase().trim().startsWith(startsWith.toLowerCase().trim())){
                return i;
            }
        }

        return -1;
    }

    //Skip comments and blank lines
    private String getLine(BufferedReader in) throws IOException {
        String temp;
        while ((temp = in.readLine()) != null) {
            temp = temp.trim();
            if (temp.length() == 0) {
                //blank line
                continue;
            }
            if (temp.charAt(0) != '#') {
                //not a comment
                return temp;
            }
        }
        return null;
    }
    
    public static String getDisplayUnits(String columnName, Boolean us){
        if (COLUMN_ENERGY.equals(columnName)){
            if (us){
                return "gal diesel/ac";
            }
            else{
                return "L diesel/ha";
            }
        }                
        return null;
    }
}