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    }