001/* 002 * Copyright (c) 2007-2011, Regents of the University of Colorado 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions are met: 007 * 008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 009 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 010 * Neither the name of the University of Colorado at Boulder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 011 * 012 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 013 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 014 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 015 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 016 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 017 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 018 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 019 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 020 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 021 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 022 * POSSIBILITY OF SUCH DAMAGE. 023 */ 024package org.cleartk.util.collection; 025 026import java.io.BufferedReader; 027import java.io.BufferedWriter; 028import java.io.IOException; 029import java.io.PrintWriter; 030import java.io.Reader; 031import java.io.Serializable; 032import java.io.Writer; 033import java.util.ArrayList; 034import java.util.Collections; 035import java.util.List; 036import java.util.Map; 037import java.util.Set; 038 039import org.cleartk.util.BaseConversion; 040 041import com.google.common.collect.BiMap; 042import com.google.common.collect.ForwardingMap; 043import com.google.common.collect.HashBiMap; 044 045/** 046 * <br> 047 * Copyright (c) 2007-2011, Regents of the University of Colorado <br> 048 * All rights reserved. 049 * 050 * <p> 051 * 052 * @author Philip 053 * 054 */ 055public class CompressedStringBiMap extends ForwardingMap<String, String> implements 056 GenKeyBiMap<String, String>, Serializable { 057 058 private static final long serialVersionUID = 5362169827584657941L; 059 060 private HashBiMap<String, String> delegate; 061 062 private int count; 063 064 public CompressedStringBiMap() { 065 this.delegate = HashBiMap.create(); 066 this.count = 0; 067 } 068 069 @Override 070 public String getOrGenerateKey(String value) { 071 if (this.containsValue(value)) 072 return this.inverse().get(value); 073 074 synchronized (this) { 075 String key = BaseConversion.convertBase(this.count, 62); 076 this.put(key, value); 077 return key; 078 } 079 } 080 081 @Override 082 public String put(String key, String value) { 083 this.count++; 084 return this.delegate.put(key, value); 085 } 086 087 @Override 088 public String forcePut(String key, String value) { 089 return this.delegate.forcePut(key, value); 090 } 091 092 @Override 093 public void putAll(Map<? extends String, ? extends String> map) { 094 this.standardPutAll(map); 095 } 096 097 @Override 098 public BiMap<String, String> inverse() { 099 return this.delegate.inverse(); 100 } 101 102 @Override 103 protected Map<String, String> delegate() { 104 return this.delegate; 105 } 106 107 @Override 108 public Set<String> values() { 109 return this.delegate.values(); 110 } 111 112 public void read(Reader reader) throws IOException { 113 clear(); 114 115 BufferedReader input = new BufferedReader(reader); 116 117 String line = input.readLine(); 118 119 if (line == null) 120 return; 121 122 int tempcount = Integer.parseInt(line); 123 124 while ((line = input.readLine()) != null) { 125 int tabLocation = line.lastIndexOf('\t'); 126 String value = line.substring(0, tabLocation); 127 String key = line.substring(tabLocation + 1); 128 put(key, value); 129 } 130 131 count = tempcount; 132 input.close(); 133 134 } 135 136 public void write(Writer writer) { 137 write(writer, false); 138 } 139 140 public void write(Writer writer, boolean sortOutput) { 141 PrintWriter out = new PrintWriter(new BufferedWriter(writer)); 142 out.println(count); 143 if (sortOutput) { 144 List<String> lookupList = new ArrayList<String>(); 145 for (Map.Entry<String, String> entry : entrySet()) { 146 lookupList.add(String.format("%s\t%s", entry.getValue(), entry.getKey())); 147 } 148 Collections.sort(lookupList); 149 150 // write the sorted key value pairs 151 for (String lookupString : lookupList) { 152 out.println(lookupString); 153 } 154 } else { 155 for (Map.Entry<String, String> entry : entrySet()) { 156 out.println(String.format("%s\t%s", entry.getValue(), entry.getKey())); 157 } 158 } 159 out.close(); 160 } 161}