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 }