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 * @version StudentSct 1.3 (Student Sectioning)<br> 028 * Copyright (C) 2007 - 2014 Tomáš Müller<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 */ 046public 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}