    001package net.sf.cpsolver.coursett;
    002
    003import java.io.BufferedReader;
    004import java.io.File;
    005import java.io.FileReader;
    006import java.io.StringReader;
    007import java.util.ArrayList;
    008import java.util.HashMap;
    009import java.util.Iterator;
    010import java.util.List;
    011import java.util.Map;
    012import java.util.TreeSet;
    013
    014import net.sf.cpsolver.coursett.model.Lecture;
    015import net.sf.cpsolver.coursett.model.Placement;
    016import net.sf.cpsolver.coursett.model.TimetableModel;
    017import net.sf.cpsolver.ifs.solution.Solution;
    018import net.sf.cpsolver.ifs.util.CSVFile;
    019import net.sf.cpsolver.ifs.util.DataProperties;
    020import net.sf.cpsolver.ifs.util.Progress;
    021
    022import org.apache.log4j.BasicConfigurator;
    023import org.dom4j.Document;
    024import org.dom4j.Element;
    025import org.dom4j.io.SAXReader;
    026
    027/**
    028 * Process all solutions (files solution.xml or output.csv) in all subfolders of
    029 * the given folder and create a CSV (comma separated values text file) with
    030 * solution infos of the found solutions.
    031 *
    032 * @version CourseTT 1.2 (University Course Timetabling)<br>
    033 *          Copyright (C) 2007 - 2010 Tomáš Müller<br>
    034 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    035 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    036 * <br>
    037 *          This library is free software; you can redistribute it and/or modify
    038 *          it under the terms of the GNU Lesser General Public License as
    039 *          published by the Free Software Foundation; either version 3 of the
    040 *          License, or (at your option) any later version. <br>
    041 * <br>
    042 *          This library is distributed in the hope that it will be useful, but
    043 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    044 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    045 *          Lesser General Public License for more details. <br>
    046 * <br>
    047 *          You should have received a copy of the GNU Lesser General Public
    048 *          License along with this library; if not see
    049 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    050 */
    051public class GetInfo {
    052
    053    public static HashMap<String, String> getInfoOfASolution(File file) {
    054        try {
    055            DataProperties properties = new DataProperties();
    056            properties.setProperty("General.Input", file.getPath());
    057            TimetableXMLLoader loader = new TimetableXMLLoader(new TimetableModel(properties));
    058            loader.load();
    059            File newOutputFile = new File(file.getParentFile(), "new-output.csv");
    060            Test.saveOutputCSV(new Solution<Lecture, Placement>(loader.getModel()), newOutputFile);
    061            Progress.removeInstance(loader.getModel());
    062            System.out.println("  Reading " + newOutputFile + " ...");
    063            HashMap<String, String> info = getInfo(newOutputFile);
    064            File outputFile = new File(file.getParentFile(), "output.csv");
    065            if (outputFile.exists()) {
    066                System.out.println("  Reading " + outputFile + " ...");
    067                HashMap<String, String> info2 = getInfo(outputFile);
    068                if (info2.containsKey("000.002 Time [sec]"))
    069                    info.put("000.002 Time [sec]", info2.get("000.002 Time [sec]"));
    070            }
    071            return info;
    072        } catch (Exception e) {
    073            System.err.println("Error reading info, message: " + e.getMessage());
    074            e.printStackTrace();
    075            return null;
    076        }
    077    }
    078
    079    public static HashMap<String, String> getInfo(String comment) {
    080        try {
    081            BufferedReader reader = new BufferedReader(new StringReader(comment));
    082            String line = null;
    083            HashMap<String, String> info = new HashMap<String, String>();
    084            while ((line = reader.readLine()) != null) {
    085                int idx = line.indexOf(':');
    086                if (idx >= 0) {
    087                    String key = line.substring(0, idx).trim();
    088                    String value = line.substring(idx + 1).trim();
    089                    if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) {
    090                        value = value.substring(value.indexOf('(') + 1, value.indexOf(')'));
    091                        if (value.indexOf('/') >= 0) {
    092                            String bound = value.substring(value.indexOf('/') + 1);
    093                            if (bound.indexOf("..") >= 0) {
    094                                String min = bound.substring(0, bound.indexOf(".."));
    095                                String max = bound.substring(bound.indexOf("..") + 2);
    096                                info.put(key + " Min", min);
    097                                info.put(key + " Max", max);
    098                            } else {
    099                                info.put(key + " Bound", bound);
    100                            }
    101                            value = value.substring(0, value.indexOf('/'));
    102                        }
    103                    }
    104                    if (value.length() > 0)
    105                        info.put(key, value);
    106                }
    107            }
    108            reader.close();
    109            return info;
    110        } catch (Exception e) {
    111            System.err.println("Error reading info, message: " + e.getMessage());
    112            e.printStackTrace();
    113            return null;
    114        }
    115    }
    116
    117    public static HashMap<String, String> getInfo(File outputFile) {
    118        try {
    119            BufferedReader reader = new BufferedReader(new FileReader(outputFile));
    120            String line = null;
    121            HashMap<String, String> info = new HashMap<String, String>();
    122            while ((line = reader.readLine()) != null) {
    123                int idx = line.indexOf(',');
    124                if (idx >= 0) {
    125                    String key = line.substring(0, idx).trim();
    126                    String value = line.substring(idx + 1).trim();
    127                    if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) {
    128                        value = value.substring(value.indexOf('(') + 1, value.indexOf(')'));
    129                        if (value.indexOf('/') >= 0) {
    130                            String bound = value.substring(value.indexOf('/') + 1);
    131                            if (bound.indexOf("..") >= 0) {
    132                                String min = bound.substring(0, bound.indexOf(".."));
    133                                String max = bound.substring(bound.indexOf("..") + 2);
    134                                info.put(key + " Min", min);
    135                                info.put(key + " Max", max);
    136                            } else {
    137                                info.put(key + " Bound", bound);
    138                            }
    139                            value = value.substring(0, value.indexOf('/'));
    140                        }
    141                    }
    142                    if (value.length() > 0)
    143                        info.put(key, value);
    144                }
    145            }
    146            reader.close();
    147            return info;
    148        } catch (Exception e) {
    149            System.err.println("Error reading info, message: " + e.getMessage());
    150            e.printStackTrace();
    151            return null;
    152        }
    153    }
    154
    155    public static HashMap<String, String> getInfo(Element root) {
    156        try {
    157            HashMap<String, String> info = new HashMap<String, String>();
    158            for (Iterator<?> i = root.elementIterator("property"); i.hasNext();) {
    159                Element property = (Element) i.next();
    160                String key = property.attributeValue("name");
    161                String value = property.getText();
    162                if (key == null || value == null)
    163                    continue;
    164                if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) {
    165                    value = value.substring(value.indexOf('(') + 1, value.indexOf(')'));
    166                    if (value.indexOf('/') >= 0) {
    167                        String bound = value.substring(value.indexOf('/') + 1);
    168                        if (bound.indexOf("..") >= 0) {
    169                            String min = bound.substring(0, bound.indexOf(".."));
    170                            String max = bound.substring(bound.indexOf("..") + 2);
    171                            info.put(key + " Min", min);
    172                            info.put(key + " Max", max);
    173                        } else {
    174                            info.put(key + " Bound", bound);
    175                        }
    176                        value = value.substring(0, value.indexOf('/'));
    177                    }
    178                }
    179                if (value.length() > 0)
    180                    info.put(key, value);
    181
    182            }
    183            return info;
    184        } catch (Exception e) {
    185            System.err.println("Error reading info, message: " + e.getMessage());
    186            return null;
    187        }
    188    }
    189
    190    public static void getInfo(File folder, List<Info> infos, String prefix) {
    191        File infoFile = new File(folder, "info.xml");
    192        if (infoFile.exists()) {
    193            System.out.println("Reading " + infoFile + " ...");
    194            try {
    195                Document document = (new SAXReader()).read(infoFile);
    196                HashMap<String, String> info = getInfo(document.getRootElement());
    197                if (info != null && !info.isEmpty()) {
    198                    infos.add(new Info(prefix, info));
    199                    return;
    200                }
    201            } catch (Exception e) {
    202                System.err.println("Error reading file " + infoFile + ", message: " + e.getMessage());
    203            }
    204        }
    205        File solutionFile = new File(folder, "solution.xml");
    206        if (solutionFile.exists()) {
    207            /*
    208             * File newOutputFile = new File(folder, "new-output.csv"); if
    209             * (newOutputFile.exists()) {
    210             * System.out.println("Reading "+newOutputFile+" ..."); try {
    211             * HashMap info = getInfo(newOutputFile); if (info!=null &&
    212             * !info.isEmpty()) { infos.addElement(new Object[]{prefix,info});
    213             * return; } } catch (Exception e) {
    214             * System.err.println("Error reading file "
    215             * +infoFile+", message: "+e.getMessage()); } }
    216             */
    217            System.out.println("Reading " + solutionFile + " ...");
    218            try {
    219                HashMap<String, String> info = getInfoOfASolution(solutionFile);
    220                if (info != null && !info.isEmpty()) {
    221                    infos.add(new Info(prefix, info));
    222                    return;
    223                }
    224            } catch (Exception e) {
    225                System.err.println("Error reading file " + infoFile + ", message: " + e.getMessage());
    226            }
    227        }
    228        File outputFile = new File(folder, "output.csv");
    229        if (outputFile.exists()) {
    230            System.out.println("Reading " + outputFile + " ...");
    231            try {
    232                HashMap<String, String> info = getInfo(outputFile);
    233                if (info != null && !info.isEmpty()) {
    234                    infos.add(new Info(prefix, info));
    235                    return;
    236                }
    237            } catch (Exception e) {
    238                System.err.println("Error reading file " + infoFile + ", message: " + e.getMessage());
    239            }
    240        }
    241    }
    242
    243    public static void getInfos(File folder, List<Info> infos, String prefix) {
    244        System.out.println("Checking " + folder + " ...");
    245        File[] files = folder.listFiles();
    246        getInfo(folder, infos, (prefix == null ? "" : prefix));
    247        for (int i = 0; i < files.length; i++)
    248            if (files[i].isDirectory())
    249                getInfos(files[i], infos, (prefix == null ? "" : prefix + "/") + files[i].getName());
    250    }
    251
    252    public static void writeInfos(List<Info> infos, File file) {
    253        try {
    254            System.out.println("Writing " + file + " ...");
    255            TreeSet<String> keys = new TreeSet<String>();
    256            ArrayList<CSVFile.CSVField> headers = new ArrayList<CSVFile.CSVField>();
    257            headers.add(new CSVFile.CSVField(""));
    258            for (Info o : infos) {
    259                keys.addAll(o.getInfo().keySet());
    260                headers.add(new CSVFile.CSVField(o.getPrefix()));
    261            }
    262            CSVFile csvFile = new CSVFile();
    263            csvFile.setHeader(headers);
    264            for (String key : keys) {
    265                ArrayList<CSVFile.CSVField> line = new ArrayList<CSVFile.CSVField>();
    266                line.add(new CSVFile.CSVField(key));
    267                for (Info o : infos) {
    268                    Map<String, String> info = o.getInfo();
    269                    String value = info.get(key);
    270                    line.add(new CSVFile.CSVField(value == null ? "" : value));
    271                }
    272                csvFile.addLine(line);
    273            }
    274            csvFile.save(file);
    275        } catch (Exception e) {
    276            System.err.println("Error writing file " + file + ", message: " + e.getMessage());
    277        }
    278    }
    279
    280    public static void main(String[] args) {
    281        try {
    282            BasicConfigurator.configure();
    283            File folder = new File(args[0]);
    284            List<Info> infos = new ArrayList<Info>();
    285            getInfos(folder, infos, null);
    286            if (!infos.isEmpty())
    287                writeInfos(infos, new File(folder, "info.csv"));
    288        } catch (Exception e) {
    289            e.printStackTrace();
    290        }
    291    }
    292
    293    public static class Info {
    294        private String iPrefix;
    295        private HashMap<String, String> iInfo;
    296
    297        public Info(String prefix, HashMap<String, String> info) {
    298            iPrefix = prefix;
    299            iInfo = info;
    300        }
    301
    302        public String getPrefix() {
    303            return iPrefix;
    304        }
    305
    306        public Map<String, String> getInfo() {
    307            return iInfo;
    308        }
    309    }
    310}