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 }