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