1 19 20 package org.netbeans.modules.versioning.system.cvss; 21 22 import org.netbeans.modules.turbo.TurboProvider; 23 import org.openide.filesystems.FileUtil; 24 import org.openide.filesystems.Repository; 25 import org.openide.ErrorManager; 26 27 import java.io.*; 28 import java.util.*; 29 30 35 class DiskMapTurboProvider implements TurboProvider { 36 37 static final String ATTR_STATUS_MAP = "org.netbeans.modules.versioning.system.cvss.DiskMapTurboProvider.STATUS_MAP"; 39 private File cacheStore; 40 private int storeSerial; 41 42 private int cachedStoreSerial = -1; 43 private Map<File, FileInformation> cachedValues; 44 45 private static final int STATUS_VALUABLE = FileInformation.STATUS_MANAGED & 46 ~FileInformation.STATUS_VERSIONED_UPTODATE & ~FileInformation.STATUS_NOTVERSIONED_EXCLUDED; 47 48 DiskMapTurboProvider() { 49 initCacheStore(); 50 } 51 52 synchronized Map<File, FileInformation> getAllModifiedValues() { 53 if (cachedStoreSerial != storeSerial || cachedValues == null) { 54 cachedValues = new HashMap<File, FileInformation>(); 55 File [] files = cacheStore.listFiles(); 56 for (int i = 0; i < files.length; i++) { 57 File file = files[i]; 58 DataInputStream dis = null; 59 try { 60 dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); 61 for (;;) { 62 int pathLen = dis.readInt(); 63 dis.readInt(); 64 String path = readChars(dis, pathLen); 65 Map value = readValue(dis, path); 66 for (Iterator j = value.keySet().iterator(); j.hasNext();) { 67 File f = (File) j.next(); 68 FileInformation info = (FileInformation) value.get(f); 69 if ((info.getStatus() & STATUS_VALUABLE) != 0) { 70 cachedValues.put(f, info); 71 } 72 } 73 } 74 } catch (EOFException e) { 75 } catch (Exception e) { 77 ErrorManager.getDefault().notify(e); 78 } finally { 79 if (dis != null) try { dis.close(); } catch (IOException e) {} 80 } 81 } 82 cachedStoreSerial = storeSerial; 83 cachedValues = Collections.unmodifiableMap(cachedValues); 84 } 85 return cachedValues; 86 } 87 88 public boolean recognizesAttribute(String name) { 89 return ATTR_STATUS_MAP.equals(name); 90 } 91 92 public boolean recognizesEntity(Object key) { 93 return key instanceof File; 94 } 95 96 public synchronized Object readEntry(Object key, String name, MemoryCache memoryCache) { 97 assert key instanceof File; 98 assert name != null; 99 100 boolean readFailed = false; 101 File dir = (File) key; 102 File store = getStore(dir); 103 if (!store.isFile()) { 104 return null; 105 } 106 107 String dirPath = dir.getAbsolutePath(); 108 int dirPathLen = dirPath.length(); 109 DataInputStream dis = null; 110 try { 111 dis = new DataInputStream(new BufferedInputStream(new FileInputStream(store))); 112 for (;;) { 113 int pathLen = dis.readInt(); 114 int mapLen = dis.readInt(); 115 if (pathLen != dirPathLen) { 116 skip(dis, pathLen * 2 + mapLen); 117 } else { 118 String path = readChars(dis, pathLen); 119 if (dirPath.equals(path)) { 120 return readValue(dis, path); 121 } else { 122 skip(dis, mapLen); 123 } 124 } 125 } 126 } catch (EOFException e) { 127 } catch (Exception e) { 129 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 130 readFailed = true; 131 } finally { 132 if (dis != null) try { dis.close(); } catch (IOException e) {} 133 } 134 if (readFailed) store.delete(); 135 return null; 136 } 137 138 public synchronized boolean writeEntry(Object key, String name, Object value) { 139 assert key instanceof File; 140 assert name != null; 141 142 if (value != null) { 143 if (!(value instanceof Map)) return false; 144 if (!isValuable(value)) value = null; 145 } 146 147 File dir = (File) key; 148 String dirPath = dir.getAbsolutePath(); 149 int dirPathLen = dirPath.length(); 150 File store = getStore(dir); 151 152 if (value == null && !store.exists()) return true; 153 154 File storeNew = new File(store.getParentFile(), store.getName() + ".new"); 156 DataOutputStream oos = null; 157 DataInputStream dis = null; 158 try { 159 oos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(storeNew))); 160 if (value != null) { 161 writeEntry(oos, dirPath, value); 162 } 163 if (store.exists()) { 164 dis = new DataInputStream(new BufferedInputStream(new FileInputStream(store))); 165 for (;;) { 166 int pathLen; 167 try { 168 pathLen = dis.readInt(); 169 } catch (EOFException e) { 170 break; 171 } 172 int mapLen = dis.readInt(); 173 if (pathLen == dirPathLen) { 174 String path = readChars(dis, pathLen); 175 if (dirPath.equals(path)) { 176 skip(dis, mapLen); 177 } else { 178 oos.writeInt(pathLen); 179 oos.writeInt(mapLen); 180 oos.writeChars(path); 181 copyStreams(oos, dis, mapLen); 182 } 183 } else { 184 oos.writeInt(pathLen); 185 oos.writeInt(mapLen); 186 copyStreams(oos, dis, mapLen + pathLen * 2); 187 } 188 } 189 } 190 } catch (Exception e) { 191 ErrorManager.getDefault().annotate(e, "Copy: " + store.getAbsolutePath() + " to: " + storeNew.getAbsolutePath()); ErrorManager.getDefault().notify(e); 193 return true; 194 } finally { 195 if (oos != null) try { oos.close(); } catch (IOException e) {} 196 if (dis != null) try { dis.close(); } catch (IOException e) {} 197 } 198 storeSerial++; 199 store.delete(); 200 storeNew.renameTo(store); 201 return true; 202 } 203 204 private void skip(InputStream is, long len) throws IOException { 205 while (len > 0) { 206 long n = is.skip(len); 207 if (n < 0) throw new EOFException("Missing " + len + " bytes."); len -= n; 209 } 210 } 211 212 private String readChars(DataInputStream dis, int len) throws IOException { 213 StringBuffer sb = new StringBuffer (len); 214 while (len-- > 0) { 215 sb.append(dis.readChar()); 216 } 217 return sb.toString(); 218 } 219 220 private Map<File, FileInformation> readValue(DataInputStream dis, String dirPath) throws IOException { 221 Map<File, FileInformation> map = new HashMap<File, FileInformation>(); 222 int len = dis.readInt(); 223 while (len-- > 0) { 224 int nameLen = dis.readInt(); 225 String name = readChars(dis, nameLen); 226 File file = new File(dirPath, name); 227 int status = dis.readInt(); 228 FileInformation info = new FileInformation(status & 65535, status > 65535); 229 map.put(file, info); 230 } 231 return map; 232 } 233 234 private void writeEntry(DataOutputStream dos, String dirPath, Object value) throws IOException { 235 236 Map map = (Map) value; 237 Set set = map.keySet(); 238 ByteArrayOutputStream baos = new ByteArrayOutputStream(set.size() * 50); 239 DataOutputStream temp = new DataOutputStream(baos); 240 241 temp.writeInt(set.size()); 242 for (Iterator i = set.iterator(); i.hasNext();) { 243 File file = (File) i.next(); 244 FileInformation info = (FileInformation) map.get(file); 245 temp.writeInt(file.getName().length()); 246 temp.writeChars(file.getName()); 247 temp.writeInt(info.getStatus() + (info.isDirectory() ? 65536 : 0)); 248 } 249 temp.close(); 250 byte [] valueBytes = baos.toByteArray(); 251 252 dos.writeInt(dirPath.length()); 253 dos.writeInt(valueBytes.length); 254 dos.writeChars(dirPath); 255 dos.write(valueBytes); 256 } 257 258 private boolean isValuable(Object value) { 259 Map map = (Map) value; 260 for (Iterator i = map.values().iterator(); i.hasNext();) { 261 FileInformation info = (FileInformation) i.next(); 262 if ((info.getStatus() & STATUS_VALUABLE) != 0) return true; 263 } 264 return false; 265 } 266 267 private File getStore(File dir) { 268 String dirPath = dir.getAbsolutePath(); 269 int dirHash = dirPath.hashCode(); 270 return new File(cacheStore, Integer.toString(dirHash % 173 + 172) + ".bin"); } 272 273 private void initCacheStore() { 274 String userDir = System.getProperty("netbeans.user"); if (userDir != null) { 276 cacheStore = new File(new File(new File (userDir, "var"), "cache"), "cvscache"); } else { 278 File cachedir = FileUtil.toFile(Repository.getDefault().getDefaultFileSystem().getRoot()); 279 cacheStore = new File(cachedir, "cvscache"); } 281 cacheStore.mkdirs(); 282 } 283 284 private static void copyStreams(OutputStream out, InputStream in, int len) throws IOException { 285 byte [] buffer = new byte[4096]; 286 for (;;) { 287 int n = (len <= 4096) ? len : 4096; 288 n = in.read(buffer, 0, n); 289 if (n < 0) throw new EOFException("Missing " + len + " bytes."); out.write(buffer, 0, n); 291 if ((len -= n) == 0) break; 292 } 293 out.flush(); 294 } 295 } 296 | Popular Tags |