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 * Clear id conversion table.
084 */
085 public void clear() {
086 iConversion.clear();
087 }
088
089 /**
090 * Save id conversion file.
091 * @param file id file to save
092 */
093 public void save(File file) {
094 file.getParentFile().mkdirs();
095 Document document = DocumentHelper.createDocument();
096 Element root = document.addElement("id-convertor");
097 synchronized (iConversion) {
098 for (Map.Entry<String, HashMap<String, String>> entry : iConversion.entrySet()) {
099 String type = entry.getKey();
100 HashMap<String, String> conversion = entry.getValue();
101 Element convEl = root.addElement(type);
102 for (Map.Entry<String, String> idConv : conversion.entrySet()) {
103 convEl.addElement("conv").addAttribute("old", idConv.getKey()).addAttribute("new",
104 idConv.getValue());
105 }
106 }
107 }
108 FileOutputStream fos = null;
109 try {
110 fos = new FileOutputStream(file);
111 (new XMLWriter(fos, OutputFormat.createPrettyPrint())).write(document);
112 fos.flush();
113 fos.close();
114 fos = null;
115 } catch (Exception e) {
116 sLogger.error("Unable to save id conversions, reason: " + e.getMessage(), e);
117 } finally {
118 try {
119 if (fos != null)
120 fos.close();
121 } catch (IOException e) {
122 }
123 }
124 }
125
126 /**
127 * Save id conversion file. Name of the file needs to be provided by system
128 * property IdConvertor.File
129 */
130 public void save() {
131 if (iFile == null)
132 iFile = System.getProperty("IdConvertor.File");
133 if (iFile != null) save(new File(iFile));
134 }
135
136 /**
137 * Load id conversion file.
138 * @param file id file to load
139 */
140 public void load(File file) {
141 if (!file.exists()) return;
142 try {
143 Document document = (new SAXReader()).read(file);
144 Element root = document.getRootElement();
145 synchronized (iConversion) {
146 iConversion.clear();
147 for (Iterator<?> i = root.elementIterator(); i.hasNext();) {
148 Element convEl = (Element) i.next();
149 HashMap<String, String> conversion = new HashMap<String, String>();
150 iConversion.put(convEl.getName(), conversion);
151 for (Iterator<?> j = convEl.elementIterator("conv"); j.hasNext();) {
152 Element e = (Element) j.next();
153 conversion.put(e.attributeValue("old"), e.attributeValue("new"));
154 }
155 }
156 }
157 } catch (Exception e) {
158 sLogger.error("Unable to load id conversions, reason: " + e.getMessage(), e);
159 }
160 }
161
162 /**
163 * Load id conversion file. Name of the file needs to be provided by system
164 * property IdConvertor.File
165 */
166 public void load() {
167 if (iFile == null)
168 iFile = System.getProperty("IdConvertor.File");
169 if (iFile != null) load(new File(iFile));
170 }
171 }