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.Hashtable; 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. 019 * This class is used by {@link TimetableXMLSaver} to anonymise benchmark data sets. 020 * Conversion file can be provided by IdConvertor.File system property (e.g. -DIdConvertor.File=.\idconf.xml). 021 * <br><br> 022 * 023 * @version 024 * CourseTT 1.1 (University Course Timetabling)<br> 025 * Copyright (C) 2006 Tomáš Müller<br> 026 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 027 * Lazenska 391, 76314 Zlin, Czech Republic<br> 028 * <br> 029 * This library is free software; you can redistribute it and/or 030 * modify it under the terms of the GNU Lesser General Public 031 * License as published by the Free Software Foundation; either 032 * version 2.1 of the License, or (at your option) any later version. 033 * <br><br> 034 * This library is distributed in the hope that it will be useful, 035 * but 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. 038 * <br><br> 039 * You should have received a copy of the GNU Lesser General Public 040 * License along with this library; if not, write to the Free Software 041 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 Hashtable iConversion = new Hashtable(); 047 private String iFile = null; 048 049 /** Constructor -- use {@link IdConvertor#getInstance} to get an instance of this class. */ 050 protected IdConvertor(String file) { 051 iFile = file; 052 load(); 053 } 054 055 /** Get an instance of IdConvertor class. */ 056 public static IdConvertor getInstance() { 057 if (sInstance==null) 058 sInstance = new IdConvertor(null); 059 return sInstance; 060 } 061 062 /** Convert id of given type. */ 063 public String convert(String type, String id) { 064 synchronized (iConversion) { 065 Hashtable conversion = (Hashtable)iConversion.get(type); 066 if (conversion==null) { 067 conversion = new Hashtable(); 068 iConversion.put(type, conversion); 069 } 070 String newId = (String)conversion.get(id); 071 if (newId==null) { 072 newId = String.valueOf(conversion.size()+1); 073 conversion.put(id, newId); 074 } 075 return newId; 076 } 077 } 078 079 /** Save id conversion file. Name of the file needs to be provided by system property IdConvertor.File */ 080 public void save() { 081 (new File(iFile)).getParentFile().mkdirs(); 082 Document document = DocumentHelper.createDocument(); 083 Element root = document.addElement("id-convertor"); 084 synchronized (iConversion) { 085 for (Iterator i=iConversion.entrySet().iterator();i.hasNext();) { 086 Map.Entry entry = (Map.Entry)i.next(); 087 String type = (String)entry.getKey(); 088 Hashtable conversion = (Hashtable)entry.getValue(); 089 Element convEl = root.addElement(type); 090 for (Iterator j=conversion.entrySet().iterator();j.hasNext();) { 091 Map.Entry idConv = (Map.Entry)j.next(); 092 convEl.addElement("conv").addAttribute("old",(String)idConv.getKey()).addAttribute("new",(String)idConv.getValue()); 093 } 094 } 095 } 096 FileOutputStream fos = null; 097 try { 098 fos = new FileOutputStream(iFile); 099 (new XMLWriter(fos,OutputFormat.createPrettyPrint())).write(document); 100 fos.flush();fos.close();fos=null; 101 } catch (Exception e) { 102 sLogger.error("Unable to save id conversions, reason: "+e.getMessage(),e); 103 } finally { 104 try { 105 if (fos!=null) fos.close(); 106 } catch (IOException e) {} 107 } 108 } 109 110 /** Load id conversion file. Name of the file needs to be provided by system property IdConvertor.File */ 111 public void load() { 112 try { 113 if (iFile==null) iFile = (String)System.getProperty("IdConvertor.File","idconv.xml"); 114 if (iFile==null || !(new File(iFile)).exists()) return; 115 Document document = (new SAXReader()).read(iFile); 116 Element root = document.getRootElement(); 117 synchronized (iConversion) { 118 iConversion.clear(); 119 for (Iterator i=root.elementIterator();i.hasNext();) { 120 Element convEl = (Element)i.next(); 121 Hashtable conversion = new Hashtable(); 122 iConversion.put(convEl.getName(),conversion); 123 for (Iterator j=convEl.elementIterator("conv");j.hasNext();) { 124 Element e = (Element)j.next(); 125 conversion.put(e.attributeValue("old"),e.attributeValue("new")); 126 } 127 } 128 } 129 } catch (Exception e) { 130 sLogger.error("Unable to load id conversions, reason: "+e.getMessage(),e); 131 } 132 } 133 }