1 19 package org.netbeans.modules.subversion.config; 20 21 import java.io.ByteArrayOutputStream ; 22 import java.io.EOFException ; 23 import java.io.File ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStream ; 27 import java.io.UnsupportedEncodingException ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 import java.util.TreeMap ; 32 import org.netbeans.modules.subversion.util.FileUtils; 33 import org.openide.ErrorManager; 34 35 41 public class KVFile { 42 43 44 private Map <Key, byte[]> map; 45 46 private Map <String , Key> keyMap; 47 48 private final File file; 49 50 55 public KVFile(File file) { 56 this.file = file; 57 try { 58 if(file.exists()) { 59 parse(); 60 } 61 } catch (IOException ex) { 62 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 63 } 64 } 65 66 72 protected byte[] getValue(Key key) { 73 return (byte[]) getMap().get(key); 74 } 75 76 82 protected String getStringValue(Key key) { 83 try { 84 byte[] value = getValue(key); 85 86 if (value == null) { 87 return null; 88 } 89 return new String (value, "UTF8"); 90 } catch (UnsupportedEncodingException ex) { 91 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex); 92 return null; 93 } 94 } 95 96 100 protected void setValue(Key key, byte[] value) { 101 getMap().put(key, value); 102 } 103 104 109 public Map <Key, byte[]> getMap() { 110 if(map==null) { 111 map = new TreeMap <Key, byte[]>(); 112 } 113 return map; 114 } 115 116 121 private Map <String , Key> getKeyMap() { 122 if(keyMap == null) { 123 keyMap = new HashMap <String , Key>(); 124 } 125 return keyMap; 126 } 127 128 protected Key getKey(Key key) { 129 Key storedKey = getKey(key.getName()); 130 if(storedKey == null) { 131 setKey(key); 132 return key; 133 } 134 return storedKey; 135 } 136 137 private Key getKey(String name) { 138 return getKeyMap().get(name); 139 } 140 141 protected void setKey(Key key) { 142 getKeyMap().put(key.getName(), key); 143 } 144 145 149 private void parse() throws IOException { 150 InputStream is = null; 151 try { 152 is = FileUtils.createInputStream(file); 153 int keyIdx = 0; 154 while(!checkEOF(is)) { 155 int keyLength = readEntryLength(is); byte[] keyName = new byte[keyLength]; 157 is.read(keyName); 158 is.read(); int valueLength = readEntryLength(is); byte[] value = new byte[valueLength]; 161 is.read(value); 162 Key key = new Key(keyIdx, new String (keyName, "UTF8")); 163 setKey(key); 164 getMap().put(key, value); 165 is.read(); keyIdx++; 167 } 168 } catch (EOFException eofe) { 169 if(getMap().size() > 0) { 170 throw new EOFException (file.getAbsolutePath()); 173 } 174 } finally { 176 try { 177 if (is != null) { 178 is.close(); 179 } 180 } catch (IOException e) { 181 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } 183 } 184 } 185 186 private boolean checkEOF(InputStream is) throws IOException { 187 is.mark(3); 188 byte[] end = new byte[3]; 189 is.read(end); 190 is.reset(); 191 if(end[0] == -1 || end[1] == -1 || end[2] == -1) { 192 throw new EOFException (); 193 } 194 return end[0] == 'E' && end[1] == 'N' && end[2] == 'D'; 195 } 196 197 private int readEntryLength(InputStream is) throws IOException { 198 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 199 byte b = (byte) is.read(); 200 while ( b != '\n') { 201 if(b == -1) { 202 throw new EOFException (); 203 } 204 baos.write(b); 205 b = (byte) is.read(); 206 } 207 String line = baos.toString(); 208 return Integer.decode(line.substring(2)).intValue(); 209 } 210 211 public void store() throws IOException { 212 store(file); 213 } 214 215 public void store(File file) throws IOException { 216 OutputStream os = null; 217 try { 218 File parent = file.getParentFile(); 219 if(parent!=null && !parent.exists()) { 220 parent.mkdirs(); 221 } 222 os = FileUtils.createOutputStream(file); 223 for (Iterator it = getMap().keySet().iterator(); it.hasNext();) { 224 Key key = (Key) it.next(); 225 byte[] value = (byte[]) map.get(key); 226 227 StringBuffer sb = new StringBuffer (); 228 sb.append("K "); sb.append(key.getName().length()); 230 sb.append("\n"); sb.append(key.getName()); 232 sb.append("\n"); sb.append("V "); sb.append(value.length); 235 sb.append("\n"); os.write(sb.toString().getBytes("UTF8")); 237 os.write(value); 238 os.write("\n".getBytes()); } 240 os.write("END\n".getBytes()); os.flush(); 242 243 } finally { 244 if(os != null) { 245 try { 246 os.close(); 247 } catch (IOException ex) { 248 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 249 } 250 } 251 } 252 } 253 254 protected File getFile() { 255 return file; 256 } 257 258 void setValue(Key key, String value) { 259 setValue(key, value.getBytes()); 260 } 261 262 265 protected static class Key implements Comparable { 266 267 private final int idx; 268 269 private final String name; 270 271 protected Key(int idx, String name) { 272 this.name = name; 273 this.idx = idx; 274 } 275 public int getIndex() { 276 return idx; 277 } 278 public String getName() { 279 return name; 280 } 281 public boolean equals(Object obj) { 282 if( !(obj instanceof Key) ) { 283 return false; 284 } 285 Key key = (Key) obj; 286 return key.getIndex() == getIndex() && key.getName().equals(getName()); 287 } 288 public int hashCode() { 289 StringBuffer sb = new StringBuffer (); 290 sb.append(getName()); 291 sb.append(getIndex()); 292 return sb.toString().hashCode(); 293 } 294 public int compareTo(Object obj) { 295 if( !(obj instanceof Key) ) { 296 return 0; 297 } 298 Key key = (Key) obj; 299 if (key.getIndex() < getIndex()) { 300 return 1; 301 } else if (key.getIndex() > getIndex()) { 302 return -1; 303 } 304 return 0; 305 } 306 public String toString() { 307 return name; 308 } 309 } 310 311 } 312 | Popular Tags |