001    package net.sf.cpsolver.coursett;
002    
003    import java.io.BufferedReader;
004    import java.io.File;
005    import java.io.FileReader;
006    import java.io.StringReader;
007    import java.util.ArrayList;
008    import java.util.HashMap;
009    import java.util.Iterator;
010    import java.util.List;
011    import java.util.Map;
012    import java.util.TreeSet;
013    
014    import net.sf.cpsolver.coursett.model.Lecture;
015    import net.sf.cpsolver.coursett.model.Placement;
016    import net.sf.cpsolver.coursett.model.TimetableModel;
017    import net.sf.cpsolver.ifs.solution.Solution;
018    import net.sf.cpsolver.ifs.util.CSVFile;
019    import net.sf.cpsolver.ifs.util.DataProperties;
020    import net.sf.cpsolver.ifs.util.Progress;
021    
022    import org.apache.log4j.BasicConfigurator;
023    import org.dom4j.Document;
024    import org.dom4j.Element;
025    import 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 Tomas Muller<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     */
051    public 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    }