001 package net.sf.cpsolver.coursett; 002 003 import java.io.File; 004 import java.io.FileOutputStream; 005 import java.io.IOException; 006 import java.util.HashMap; 007 import java.util.Iterator; 008 import java.util.Map; 009 010 import org.dom4j.Document; 011 import org.dom4j.DocumentHelper; 012 import org.dom4j.Element; 013 import org.dom4j.io.OutputFormat; 014 import org.dom4j.io.SAXReader; 015 import org.dom4j.io.XMLWriter; 016 017 /** 018 * Conversion of ids to sequential numbers. This class is used by 019 * {@link TimetableXMLSaver} to anonymise benchmark data sets. Conversion file 020 * can be provided by IdConvertor.File system property (e.g. 021 * -DIdConvertor.File=.\idconf.xml). <br> 022 * <br> 023 * 024 * @version CourseTT 1.2 (University Course Timetabling)<br> 025 * Copyright (C) 2006 - 2010 Tomas Muller<br> 026 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 027 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 028 * <br> 029 * This library is free software; you can redistribute it and/or modify 030 * it under the terms of the GNU Lesser General Public License as 031 * published by the Free Software Foundation; either version 3 of the 032 * License, or (at your option) any later version. <br> 033 * <br> 034 * This library is distributed in the hope that it will be useful, but 035 * WITHOUT ANY WARRANTY; without even the implied warranty of 036 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 037 * Lesser General Public License for more details. <br> 038 * <br> 039 * You should have received a copy of the GNU Lesser General Public 040 * License along with this library; if not see 041 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 042 */ 043 public class IdConvertor { 044 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(IdConvertor.class); 045 private static IdConvertor sInstance = null; 046 private HashMap<String, HashMap<String, String>> iConversion = new HashMap<String, HashMap<String, String>>(); 047 private String iFile = null; 048 049 /** 050 * Constructor -- use {@link IdConvertor#getInstance} to get an instance of 051 * this class. 052 */ 053 protected IdConvertor(String file) { 054 iFile = file; 055 load(); 056 } 057 058 /** Get an instance of IdConvertor class. */ 059 public static IdConvertor getInstance() { 060 if (sInstance == null) 061 sInstance = new IdConvertor(null); 062 return sInstance; 063 } 064 065 /** Convert id of given type. */ 066 public String convert(String type, String id) { 067 synchronized (iConversion) { 068 HashMap<String, String> conversion = iConversion.get(type); 069 if (conversion == null) { 070 conversion = new HashMap<String, String>(); 071 iConversion.put(type, conversion); 072 } 073 String newId = conversion.get(id); 074 if (newId == null) { 075 newId = String.valueOf(conversion.size() + 1); 076 conversion.put(id, newId); 077 } 078 return newId; 079 } 080 } 081 082 /** 083 * Save id conversion file. Name of the file needs to be provided by system 084 * property IdConvertor.File 085 */ 086 public void save() { 087 (new File(iFile)).getParentFile().mkdirs(); 088 Document document = DocumentHelper.createDocument(); 089 Element root = document.addElement("id-convertor"); 090 synchronized (iConversion) { 091 for (Map.Entry<String, HashMap<String, String>> entry : iConversion.entrySet()) { 092 String type = entry.getKey(); 093 HashMap<String, String> conversion = entry.getValue(); 094 Element convEl = root.addElement(type); 095 for (Map.Entry<String, String> idConv : conversion.entrySet()) { 096 convEl.addElement("conv").addAttribute("old", idConv.getKey()).addAttribute("new", 097 idConv.getValue()); 098 } 099 } 100 } 101 FileOutputStream fos = null; 102 try { 103 fos = new FileOutputStream(iFile); 104 (new XMLWriter(fos, OutputFormat.createPrettyPrint())).write(document); 105 fos.flush(); 106 fos.close(); 107 fos = null; 108 } catch (Exception e) { 109 sLogger.error("Unable to save id conversions, reason: " + e.getMessage(), e); 110 } finally { 111 try { 112 if (fos != null) 113 fos.close(); 114 } catch (IOException e) { 115 } 116 } 117 } 118 119 /** 120 * Load id conversion file. Name of the file needs to be provided by system 121 * property IdConvertor.File 122 */ 123 public void load() { 124 try { 125 if (iFile == null) 126 iFile = System.getProperty("IdConvertor.File", "idconv.xml"); 127 if (iFile == null || !(new File(iFile)).exists()) 128 return; 129 Document document = (new SAXReader()).read(iFile); 130 Element root = document.getRootElement(); 131 synchronized (iConversion) { 132 iConversion.clear(); 133 for (Iterator<?> i = root.elementIterator(); i.hasNext();) { 134 Element convEl = (Element) i.next(); 135 HashMap<String, String> conversion = new HashMap<String, String>(); 136 iConversion.put(convEl.getName(), conversion); 137 for (Iterator<?> j = convEl.elementIterator("conv"); j.hasNext();) { 138 Element e = (Element) j.next(); 139 conversion.put(e.attributeValue("old"), e.attributeValue("new")); 140 } 141 } 142 } 143 } catch (Exception e) { 144 sLogger.error("Unable to load id conversions, reason: " + e.getMessage(), e); 145 } 146 } 147 }