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