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