edu.sharif.ce.dml.mobisim.diagram.control.EvaluationDiagramUsingHandler.java Source code

Java tutorial

Introduction

Here is the source code for edu.sharif.ce.dml.mobisim.diagram.control.EvaluationDiagramUsingHandler.java

Source

/*
 * Copyright (c) 2005-2008 by Masoud Moshref Javadi <moshref@ce.sharif.edu>, http://ce.sharif.edu/~moshref
 * The license.txt file describes the conditions under which this software may be distributed.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

package edu.sharif.ce.dml.mobisim.diagram.control;

import edu.sharif.ce.dml.common.data.EvaluationLoadingHandler;
import edu.sharif.ce.dml.common.data.configfilter.ConfigFileFilter;
import edu.sharif.ce.dml.common.logic.entity.evaluation.EvaluationRecord;
import edu.sharif.ce.dml.common.util.DevelopmentLogger;
import edu.sharif.ce.dml.common.util.FileManager;
import edu.sharif.ce.dml.common.util.InvalidRequiredInputFileException;
import edu.sharif.ce.dml.common.util.io.loader.User;
import edu.sharif.ce.dml.common.util.io.loader.bulk.BulkUser;
import edu.sharif.ce.dml.common.util.io.loader.bulk.BulkUsingHandler;
import edu.sharif.ce.dml.mobisim.diagram.model.EvaluationTable;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.io.*;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Masoud
 * Date: Nov 6, 2007
 * Time: 6:54:43 PM<br>
 * The using Handler class that is responsible to use evaluation datas and create a diagram
 */
public class EvaluationDiagramUsingHandler implements BulkUsingHandler<EvaluationRecord> {
    /**
     * list of evaluation labels. The position of labels in the list is important
     */
    private List<String> labels;
    /**
     * map which keeps track of a label and its position in {@link #labels} list.
     */
    private Map<String, Integer> labelNumber;

    /**
     * the key for loading template file.
     */
    public static final String TEMPLATE_FILE_KEY = "digaramtemplate";

    /**
     * excel template file
     */
    private final File templateFile;

    /**
     * excel output file
     */
    private final File outputFile;

    /**
     * the value of column that should used to draw diagram
     */
    private final String evaluationColumn;
    /**
     * series name column = first column.
     */
    private final String rowNameColumn;

    /**
     * list of labels that will be used to create columns
     */
    private final List<String> variableColumns;

    /**
     * variables to create sheets
     */
    private final List<String> importantColumns;

    /**
     * These parameters will be validated in {@link #validate()} method.
     * @param templateFile
     * @param outputFile it should be writable.
     * @param evaluationColumn should be not null, should be among labels
     * @param rowNameColumn should be not null, should be among labels.
     * @param variableColumns should be not null, its size should be greater than 0, values should be among labels
     * @param importantColumns should be not null, values should be among labels
     */
    public EvaluationDiagramUsingHandler(File templateFile, File outputFile, String evaluationColumn,
            String rowNameColumn, List<String> variableColumns, List<String> importantColumns) {
        this.templateFile = templateFile;
        this.outputFile = outputFile;
        this.evaluationColumn = evaluationColumn;
        this.rowNameColumn = rowNameColumn;
        this.variableColumns = variableColumns;
        this.importantColumns = importantColumns;

    }

    /**
     * validates input configurations.
     * @throws DiagramCreationException
     */
    public void validate() throws DiagramCreationException {
        //validate datas
        {
            //variableColumns Size >0
            if (rowNameColumn == null || evaluationColumn == null || importantColumns == null
                    || variableColumns == null) {
                throw new DiagramCreationException("Some data is null");
            }
            if (variableColumns.size() == 0) {
                throw new DiagramCreationException("No variable column has been selected");
            }

            //labels should contains evaluationColumn & rowNameColumn & variableColumns & importantColumns
            if (!(labels.contains(rowNameColumn) && labels.contains(evaluationColumn)
                    && labels.containsAll(importantColumns) && labels.containsAll(variableColumns))) {
                throw new DiagramCreationException("One of selected labels not exist in the file labels");
            }
            //evaluation column data should be double data

            try {
                new FileOutputStream(outputFile);
            } catch (FileNotFoundException e) {
                throw new DiagramCreationException(
                        "Can not open the file: " + outputFile.getPath() + ". Please close it in other programs.");
            }
        }
    }

    public void use(EvaluationRecord[] data) {
        double[] evalDatas = new double[data.length];
        try {
            Integer evaluationIndex = labelNumber.get(evaluationColumn);
            for (int i = 0; i < data.length; i++) {
                evalDatas[i] = Double.parseDouble(data[i].getValueAt(evaluationIndex));
            }
        } catch (NumberFormatException e) {
            DevelopmentLogger.logger
                    .debug("Evaluation data parse error. Evaluation column values should be \"Double Parsable\"");
        }

        List<ExtractedEvaluationData> extractedEvaluationDataList = new ArrayList<ExtractedEvaluationData>(
                data.length);
        //average evaluationColumns Data datas that important+variable+rowName are equals
        {
            int rowNameIndex = labelNumber.get(rowNameColumn);
            List<Integer> variablesIndex = new ArrayList<Integer>(variableColumns.size());
            for (String variableColumn : variableColumns) {
                variablesIndex.add(labelNumber.get(variableColumn));
            }
            List<Integer> importantIndexes = new ArrayList<Integer>(importantColumns.size());
            for (String importantColumn : importantColumns) {
                importantIndexes.add(labelNumber.get(importantColumn));
            }
            for (int i = 0; i < data.length; i++) {
                EvaluationRecord evaluationRecord = data[i];
                List<String> variablesData = new ArrayList<String>(variablesIndex.size());
                for (Integer index : variablesIndex) {
                    variablesData.add(evaluationRecord.getValueAt(index));
                }
                List<String> importantData = new ArrayList<String>(importantIndexes.size());
                for (Integer index : importantIndexes) {
                    importantData.add(evaluationRecord.getValueAt(index));
                }
                ExtractedEvaluationData eData = new ExtractedEvaluationData(
                        evaluationRecord.getValueAt(rowNameIndex), evalDatas[i], variablesData, importantData);
                int eIndex = extractedEvaluationDataList.indexOf(eData);
                if (eIndex < 0) {
                    extractedEvaluationDataList.add(eData);
                } else {
                    extractedEvaluationDataList.get(eIndex).addValue(eData);
                }
            }
        }

        //create model objects
        TreeSet<List<String>> importantVariablesData = new TreeSet<List<String>>(new VariableDataComparator());
        List<EvaluationTable> tables = new ArrayList<EvaluationTable>(importantVariablesData.size());
        {
            //create table columns Strings, so should find existed variable columns combinations
            EvaluationTable.setRowNameColumn(rowNameColumn);
            EvaluationTable.setImportantVariables(new TreeSet<String>(importantColumns));
            TreeSet<List<String>> columns = new TreeSet<List<String>>(new VariableDataComparator());
            for (ExtractedEvaluationData evaluationData : extractedEvaluationDataList) {
                columns.add(evaluationData.variablesData);
                importantVariablesData.add(evaluationData.importantDatas);
            }
            List<List<String>> sortedColumns = new ArrayList<List<String>>(columns.size());
            for (List<String> column : columns) {
                sortedColumns.add(column);
            }

            StringBuffer sb = new StringBuffer();
            for (String variableName : variableColumns) {
                sb.append(variableName).append(EvaluationTable.SEPARATOR);
            }
            if (variableColumns.size() > 0) {
                sb.delete(sb.lastIndexOf(EvaluationTable.SEPARATOR), sb.length());
            }
            String variableNames = sb.toString();

            for (List<String> importantStrings : importantVariablesData) {
                //each should be a Evaluation Table
                EvaluationTable evaluationTable = new EvaluationTable();
                evaluationTable.setColumns(sortedColumns);
                evaluationTable.setOtherVariablesValue(importantStrings);
                evaluationTable.setVariableNames(variableNames);
                evaluationTable.setEvaluationColumn(evaluationColumn);
                tables.add(evaluationTable);
            }
            //fill tables rows
            for (ExtractedEvaluationData extractedEvaluationData : extractedEvaluationDataList) {
                EvaluationTable tempTable = new EvaluationTable();
                tempTable.setOtherVariablesValue(extractedEvaluationData.importantDatas);
                EvaluationTable table = tables.get(tables.indexOf(tempTable));
                table.setData(extractedEvaluationData.rowName,
                        sortedColumns.indexOf(extractedEvaluationData.variablesData),
                        extractedEvaluationData.evaluationData);
            }
        }

        //write to excel files
        {
            try {
                InputStream is = new BufferedInputStream(new FileInputStream(templateFile));
                XLSTransformer transformer = new XLSTransformer();
                List sheetNames = new ArrayList();
                int i = 1;
                for (EvaluationTable table : tables) {
                    /*StringBuffer sb = new StringBuffer();
                    List<String> otherValues = table.getOtherVariablesValue();
                    for (int i1 = 0; i1 < importantColumns.size(); i1++) {
                    sb.append(importantColumns.get(i1)).append("=").append(otherValues.get(i1)).append(EvaluationTable.SEPARATOR);
                    }
                    if (importantColumns.size() > 0) {
                    sb.delete(sb.lastIndexOf(EvaluationTable.SEPARATOR), sb.length());
                    } else {
                    sb.append("untitled");
                    }
                    sheetNames.add(sb.toString());*/
                    sheetNames.add("sheet" + i++);
                }
                HSSFWorkbook resultWorkbook = transformer.transformMultipleSheetsList(is, tables, sheetNames,
                        "table", new HashMap(), 0);
                BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
                resultWorkbook.write(outputStream);
                outputStream.flush();
                outputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * manages to compare two list of doubles item by item.
     * If a value was not double parsable it will be compared as a String value.
     */
    private class VariableDataComparator implements Comparator<List<String>> {

        public int compare(List<String> o1, List<String> o2) {
            assert o1.size() == o2.size();
            Iterator<String> iterator2 = o2.iterator();
            for (String s1 : o1) {
                String s2 = iterator2.next();
                try {
                    double d1 = Double.parseDouble(s1);
                    double d2 = Double.parseDouble(s2);
                    if (d1 > d2) {
                        return (int) (Math.ceil(d1 - d2));
                    }
                    if (d1 < d2) {
                        return (int) (Math.floor(d1 - d2));
                    }
                } catch (NumberFormatException e) {
                    int sc = s1.compareToIgnoreCase(s2);
                    if (sc != 0) {
                        return sc;
                    }
                }
            }
            return 0;
        }
    }

    /**
     * entity object for extracted data from file, used for averaging evaluationDatas that <tt>rowname</tt>,
     * <tt>variableData</tt> and <tt>importantDatas</tt> are equals.
     */
    public class ExtractedEvaluationData {
        String rowName;
        double evaluationData;
        List<String> variablesData;
        List<String> importantDatas;
        int weight;

        private ExtractedEvaluationData(String rowName, double evaluationData, List<String> variablesData,
                List<String> importantDatas) {
            this.rowName = rowName;
            this.evaluationData = evaluationData;
            this.variablesData = variablesData;
            this.importantDatas = importantDatas;
            weight = 1;
        }

        @Override
        public boolean equals(Object obj) {
            assert obj instanceof ExtractedEvaluationData;
            ExtractedEvaluationData e = (ExtractedEvaluationData) obj;
            assert e.variablesData.size() == variablesData.size() : "variables data sizes varies";
            assert e.importantDatas.size() == importantDatas.size() : "important data sizes varies";
            if (!e.rowName.equals(rowName)) {
                return false;
            }
            for (int i = 0; i < variablesData.size(); i++) {
                if (!variablesData.get(i).equals(e.variablesData.get(i))) {
                    return false;
                }
            }
            for (int i = 0; i < importantDatas.size(); i++) {
                if (!importantDatas.get(i).equals(e.importantDatas.get(i))) {
                    return false;
                }
            }
            return true;
        }

        public void addValue(ExtractedEvaluationData eData) {
            evaluationData = (evaluationData * weight + eData.evaluationData * eData.weight)
                    / (weight + eData.weight);
        }
    }

    public void setConfiguration(Map<String, String> conf) {
        String[] labels = new String[conf.size()];
        labelNumber = new HashMap<String, Integer>();
        for (String s : conf.keySet()) {
            String label = conf.get(s);
            Integer number = new Integer(s);
            labels[number] = label;
            labelNumber.put(label, number);
        }
        this.labels = Arrays.asList(labels);
    }

    public void stopLoading() {

    }

    public void endLoading() {

    }

    public void startLoading() {

    }

    public static void main(String[] args) throws InvalidRequiredInputFileException, DiagramCreationException {
        EvaluationDiagramUsingHandler diagramUsingHandler = new EvaluationDiagramUsingHandler(
                FileManager.getInstance().getFile(TEMPLATE_FILE_KEY + ".xls", TEMPLATE_FILE_KEY, true,
                        new javax.swing.filechooser.FileFilter[] { ConfigFileFilter.getXMLInstance() }, true),
                new File("outputTest.xls"), "RelativeSpeed", "Model",
                Arrays.asList("Spatial Dependency", "maxspeed"), Arrays.asList("Temporal Dependency"));
        User<EvaluationRecord> user = new BulkUser<EvaluationRecord>(diagramUsingHandler, new File("test.txt"),
                new EvaluationLoadingHandler());
        user.run();
    }

}