001package org.cpsolver.studentsct; 002 003import java.io.BufferedReader; 004import java.io.File; 005import java.io.FileReader; 006import java.io.StringReader; 007import java.util.ArrayList; 008import java.util.HashMap; 009import java.util.Iterator; 010import java.util.List; 011import java.util.Map; 012import java.util.TreeSet; 013 014 015import org.cpsolver.ifs.util.CSVFile; 016import org.dom4j.Comment; 017import org.dom4j.Document; 018import org.dom4j.Element; 019import org.dom4j.Node; 020import 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 * @author Tomáš Müller 028 * @version StudentSct 1.3 (Student Sectioning)<br> 029 * Copyright (C) 2007 - 2014 Tomáš Müller<br> 030 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 031 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 032 * <br> 033 * This library is free software; you can redistribute it and/or modify 034 * it under the terms of the GNU Lesser General Public License as 035 * published by the Free Software Foundation; either version 3 of the 036 * License, or (at your option) any later version. <br> 037 * <br> 038 * This library is distributed in the hope that it will be useful, but 039 * WITHOUT ANY WARRANTY; without even the implied warranty of 040 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 041 * Lesser General Public License for more details. <br> 042 * <br> 043 * You should have received a copy of the GNU Lesser General Public 044 * License along with this library; if not see 045 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 046 */ 047public class GetInfo { 048 049 public static HashMap<String, String> getInfo(String comment) { 050 try { 051 BufferedReader reader = new BufferedReader(new StringReader(comment)); 052 String line = null; 053 HashMap<String, String> info = new HashMap<String, String>(); 054 while ((line = reader.readLine()) != null) { 055 int idx = line.indexOf(':'); 056 if (idx >= 0) { 057 String key = line.substring(0, idx).trim(); 058 String value = line.substring(idx + 1).trim(); 059 if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) { 060 value = value.substring(value.indexOf('(') + 1, value.indexOf(')')); 061 if (value.indexOf('/') >= 0) { 062 String bound = value.substring(value.indexOf('/') + 1); 063 if (bound.indexOf("..") >= 0) { 064 String min = bound.substring(0, bound.indexOf("..")); 065 String max = bound.substring(bound.indexOf("..") + 2); 066 info.put(key + " Min", min); 067 info.put(key + " Max", max); 068 } else { 069 info.put(key + " Bound", bound); 070 } 071 value = value.substring(0, value.indexOf('/')); 072 } 073 } 074 if (value.length() > 0) 075 info.put(key, value); 076 } 077 } 078 reader.close(); 079 return info; 080 } catch (Exception e) { 081 System.err.println("Error reading info, message: " + e.getMessage()); 082 return null; 083 } 084 } 085 086 public static HashMap<String, String> getInfo(File outputFile) { 087 try { 088 BufferedReader reader = new BufferedReader(new FileReader(outputFile)); 089 String line = null; 090 HashMap<String, String> info = new HashMap<String, String>(); 091 while ((line = reader.readLine()) != null) { 092 int idx = line.indexOf(','); 093 if (idx >= 0) { 094 String key = line.substring(0, idx).trim(); 095 String value = line.substring(idx + 1).trim(); 096 if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) { 097 value = value.substring(value.indexOf('(') + 1, value.indexOf(')')); 098 if (value.indexOf('/') >= 0) { 099 String bound = value.substring(value.indexOf('/') + 1); 100 if (bound.indexOf("..") >= 0) { 101 String min = bound.substring(0, bound.indexOf("..")); 102 String max = bound.substring(bound.indexOf("..") + 2); 103 info.put(key + " Min", min); 104 info.put(key + " Max", max); 105 } else { 106 info.put(key + " Bound", bound); 107 } 108 value = value.substring(0, value.indexOf('/')); 109 } 110 } 111 if (value.length() > 0) 112 info.put(key, value); 113 } 114 } 115 reader.close(); 116 return info; 117 } catch (Exception e) { 118 System.err.println("Error reading info, message: " + e.getMessage()); 119 return null; 120 } 121 } 122 123 public static HashMap<String, String> getInfo(Element root) { 124 try { 125 HashMap<String, String> info = new HashMap<String, String>(); 126 for (Iterator<?> i = root.elementIterator("property"); i.hasNext();) { 127 Element property = (Element) i.next(); 128 String key = property.attributeValue("name"); 129 String value = property.getText(); 130 if (key == null || value == null) 131 continue; 132 if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) { 133 value = value.substring(value.indexOf('(') + 1, value.indexOf(')')); 134 if (value.indexOf('/') >= 0) { 135 String bound = value.substring(value.indexOf('/') + 1); 136 if (bound.indexOf("..") >= 0) { 137 String min = bound.substring(0, bound.indexOf("..")); 138 String max = bound.substring(bound.indexOf("..") + 2); 139 info.put(key + " Min", min); 140 info.put(key + " Max", max); 141 } else { 142 info.put(key + " Bound", bound); 143 } 144 value = value.substring(0, value.indexOf('/')); 145 } 146 } 147 if (value.length() > 0) 148 info.put(key, value); 149 150 } 151 return info; 152 } catch (Exception e) { 153 System.err.println("Error reading info, message: " + e.getMessage()); 154 return null; 155 } 156 } 157 158 public static void getInfo(File folder, List<Info> infos, String prefix) { 159 File infoFile = new File(folder, "info.xml"); 160 if (infoFile.exists()) { 161 System.out.println("Reading " + infoFile + " ..."); 162 try { 163 Document document = (new SAXReader()).read(infoFile); 164 HashMap<String, String> info = getInfo(document.getRootElement()); 165 if (info != null && !info.isEmpty()) { 166 infos.add(new Info(prefix, info)); 167 return; 168 } 169 } catch (Exception e) { 170 System.err.println("Error reading file " + infoFile + ", message: " + e.getMessage()); 171 } 172 } 173 File outputFile = new File(folder, "output.csv"); 174 if (outputFile.exists()) { 175 System.out.println("Reading " + outputFile + " ..."); 176 try { 177 HashMap<String, String> info = getInfo(outputFile); 178 if (info != null && !info.isEmpty()) { 179 infos.add(new Info(prefix, info)); 180 return; 181 } 182 } catch (Exception e) { 183 System.err.println("Error reading file " + infoFile + ", message: " + e.getMessage()); 184 } 185 } 186 File solutionFile = new File(folder, "solution.xml"); 187 if (!solutionFile.exists()) 188 return; 189 try { 190 System.out.println("Reading " + solutionFile + " ..."); 191 Document document = (new SAXReader()).read(solutionFile); 192 for (Iterator<?> i = document.nodeIterator(); i.hasNext();) { 193 Node node = (Node) i.next(); 194 if (node instanceof Comment) { 195 Comment comment = (Comment) node; 196 if (comment.getText().indexOf("Solution Info:") >= 0) { 197 HashMap<String, String> info = getInfo(comment.getText()); 198 if (info != null) 199 infos.add(new Info(prefix, info)); 200 } 201 } 202 } 203 } catch (Exception e) { 204 System.err.println("Error reading file " + solutionFile + ", message: " + e.getMessage()); 205 } 206 } 207 208 public static void getInfos(File folder, List<Info> infos, String prefix) { 209 System.out.println("Checking " + folder + " ..."); 210 File[] files = folder.listFiles(); 211 getInfo(folder, infos, (prefix == null ? "" : prefix)); 212 for (int i = 0; i < files.length; i++) 213 if (files[i].isDirectory()) 214 getInfos(files[i], infos, (prefix == null ? "" : prefix + "/") + files[i].getName()); 215 } 216 217 public static void writeInfos(List<Info> infos, File file) { 218 try { 219 System.out.println("Writing " + file + " ..."); 220 TreeSet<String> keys = new TreeSet<String>(); 221 List<CSVFile.CSVField> headers = new ArrayList<CSVFile.CSVField>(); 222 headers.add(new CSVFile.CSVField("")); 223 for (Info info : infos) { 224 keys.addAll(info.getInfo().keySet()); 225 headers.add(new CSVFile.CSVField(info.getPrefix())); 226 } 227 CSVFile csvFile = new CSVFile(); 228 csvFile.setHeader(headers); 229 for (String key : keys) { 230 List<CSVFile.CSVField> line = new ArrayList<CSVFile.CSVField>(); 231 line.add(new CSVFile.CSVField(key)); 232 for (Info info : infos) { 233 String value = info.getInfo().get(key); 234 line.add(new CSVFile.CSVField(value == null ? "" : value)); 235 } 236 csvFile.addLine(line); 237 } 238 csvFile.save(file); 239 } catch (Exception e) { 240 System.err.println("Error writing file " + file + ", message: " + e.getMessage()); 241 } 242 } 243 244 public static void main(String[] args) { 245 try { 246 File folder = new File(args[0]); 247 List<Info> infos = new ArrayList<Info>(); 248 getInfos(folder, infos, null); 249 if (!infos.isEmpty()) 250 writeInfos(infos, new File(folder, "info.csv")); 251 } catch (Exception e) { 252 e.printStackTrace(); 253 } 254 } 255 256 public static class Info { 257 private String iPrefix; 258 private HashMap<String, String> iInfo; 259 260 public Info(String prefix, HashMap<String, String> info) { 261 iPrefix = prefix; 262 iInfo = info; 263 } 264 265 public String getPrefix() { 266 return iPrefix; 267 } 268 269 public Map<String, String> getInfo() { 270 return iInfo; 271 } 272 } 273 274}