001    package net.sf.cpsolver.studentsct;
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.ifs.util.CSVFile;
015    
016    import org.dom4j.Comment;
017    import org.dom4j.Document;
018    import org.dom4j.Element;
019    import org.dom4j.Node;
020    import 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.2 (Student Sectioning)<br>
028     *          Copyright (C) 2007 - 2010 Tomas Muller<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     */
046    public 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    }