KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > subversion > DiskMapTurboProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.subversion;
21
22 import org.netbeans.modules.subversion.util.*;
23 import org.netbeans.modules.turbo.TurboProvider;
24 import org.openide.filesystems.FileUtil;
25 import org.openide.filesystems.Repository;
26 import org.openide.ErrorManager;
27
28 import java.io.*;
29 import java.util.*;
30
31 /**
32  * Storage of file attributes with shortcut to retrieve all stored values.
33  *
34  * @author Maros Sandor
35  */

36 class DiskMapTurboProvider implements TurboProvider {
37
38     static final String JavaDoc ATTR_STATUS_MAP = "subversion.STATUS_MAP"; // NOI18N
39

40     private static final int STATUS_VALUABLE = FileInformation.STATUS_MANAGED & ~FileInformation.STATUS_VERSIONED_UPTODATE;
41     private static final String JavaDoc CACHE_DIRECTORY = "svncache"; // NOI18N
42

43     private File cacheStore;
44     private int storeSerial;
45
46     private int cachedStoreSerial = -1;
47     private Map<File, FileInformation> cachedValues;
48     
49     DiskMapTurboProvider() {
50         initCacheStore();
51     }
52
53     synchronized Map<File, FileInformation> getAllModifiedValues() {
54         if (cachedStoreSerial != storeSerial || cachedValues == null) {
55             cachedValues = new HashMap<File, FileInformation>();
56             File [] files = cacheStore.listFiles();
57             for (int i = 0; i < files.length; i++) {
58                 File file = files[i];
59                 if (file.getName().endsWith(".bin") == false) { // NOI18N
60
// on windows list returns already deleted .new files
61
continue;
62                 }
63                 DataInputStream dis = null;
64                 try {
65                     int retry = 0;
66                     while (true) {
67                         try {
68                             dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
69                             break;
70                         } catch (IOException ioex) {
71                             retry++;
72                             if (retry > 7) {
73                                 throw ioex;
74                             }
75                             Thread.sleep(retry * 30);
76                         }
77                     }
78
79                     for (;;) {
80                         int pathLen = dis.readInt();
81                         dis.readInt();
82                         String JavaDoc path = readChars(dis, pathLen);
83                         Map value = readValue(dis, path);
84                         for (Iterator j = value.keySet().iterator(); j.hasNext();) {
85                             File f = (File) j.next();
86                             FileInformation info = (FileInformation) value.get(f);
87                             if ((info.getStatus() & STATUS_VALUABLE) != 0) {
88                                 cachedValues.put(f, info);
89                             }
90                         }
91                     }
92                 } catch (EOFException e) {
93                     // reached EOF, no entry for this key
94
} catch (Exception JavaDoc e) {
95                     ErrorManager.getDefault().notify(e);
96                 } finally {
97                     if (dis != null) try { dis.close(); } catch (IOException e) {}
98                 }
99             }
100             cachedStoreSerial = storeSerial;
101             cachedValues = Collections.unmodifiableMap(cachedValues);
102         }
103         return cachedValues;
104     }
105
106     public boolean recognizesAttribute(String JavaDoc name) {
107         return ATTR_STATUS_MAP.equals(name);
108     }
109
110     public boolean recognizesEntity(Object JavaDoc key) {
111         return key instanceof File;
112     }
113
114     public synchronized Object JavaDoc readEntry(Object JavaDoc key, String JavaDoc name, MemoryCache memoryCache) {
115         assert key instanceof File;
116         assert name != null;
117
118         boolean readFailed = false;
119         File dir = (File) key;
120         File store = getStore(dir);
121         if (!store.isFile()) {
122             return null;
123         }
124
125         String JavaDoc dirPath = dir.getAbsolutePath();
126         int dirPathLen = dirPath.length();
127         DataInputStream dis = null;
128         try {
129
130             int retry = 0;
131             while (true) {
132                 try {
133                     dis = new DataInputStream(new BufferedInputStream(new FileInputStream(store)));
134                     break;
135                 } catch (IOException ioex) {
136                     retry++;
137                     if (retry > 7) {
138                         throw ioex;
139                     }
140                     Thread.sleep(retry * 30);
141                 }
142             }
143
144             for (;;) {
145                 int pathLen = dis.readInt();
146                 int mapLen = dis.readInt();
147                 if (pathLen != dirPathLen) {
148                     skip(dis, pathLen * 2 + mapLen);
149                 } else {
150                     String JavaDoc path = readChars(dis, pathLen);
151                     if (dirPath.equals(path)) {
152                         return readValue(dis, path);
153                     } else {
154                         skip(dis, mapLen);
155                     }
156                 }
157             }
158         } catch (EOFException e) {
159             // reached EOF, no entry for this key
160
} catch (Exception JavaDoc e) {
161             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
162             readFailed = true;
163         } finally {
164             if (dis != null) try { dis.close(); } catch (IOException e) {}
165         }
166         if (readFailed) store.delete();
167         return null;
168     }
169
170     public synchronized boolean writeEntry(Object JavaDoc key, String JavaDoc name, Object JavaDoc value) {
171         assert key instanceof File;
172         assert name != null;
173
174         if (value != null) {
175             if (!(value instanceof Map)) return false;
176             if (!isValuable(value)) value = null;
177         }
178
179         File dir = (File) key;
180         String JavaDoc dirPath = dir.getAbsolutePath();
181         int dirPathLen = dirPath.length();
182         File store = getStore(dir);
183
184         if (value == null && !store.exists()) return true;
185
186         File storeNew = new File(store.getParentFile(), store.getName() + ".new"); // NOI18N
187

188         DataOutputStream oos = null;
189         DataInputStream dis = null;
190         try {
191             oos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(storeNew)));
192             if (value != null) {
193                 writeEntry(oos, dirPath, value);
194             }
195             if (store.exists()) {
196                 int retry = 0;
197                 while (true) {
198                     try {
199                         dis = new DataInputStream(new BufferedInputStream(new FileInputStream(store)));
200                         break;
201                     } catch (IOException ioex) {
202                         retry++;
203                         if (retry > 7) {
204                             throw ioex;
205                         }
206                         Thread.sleep(retry * 30);
207                     }
208                 }
209
210                 for (;;) {
211                     int pathLen;
212                     try {
213                         pathLen = dis.readInt();
214                     } catch (EOFException e) {
215                         break;
216                     }
217                     int mapLen = dis.readInt();
218                     if (pathLen == dirPathLen) {
219                         String JavaDoc path = readChars(dis, pathLen);
220                         if (dirPath.equals(path)) {
221                             skip(dis, mapLen);
222                         } else {
223                             oos.writeInt(pathLen);
224                             oos.writeInt(mapLen);
225                             oos.writeChars(path);
226                             copyStreams(oos, dis, mapLen);
227                         }
228                     } else {
229                         oos.writeInt(pathLen);
230                         oos.writeInt(mapLen);
231                         copyStreams(oos, dis, mapLen + pathLen * 2);
232                     }
233                 }
234             }
235         } catch (Exception JavaDoc e) {
236             ErrorManager.getDefault().annotate(e, "Copy: " + store.getAbsolutePath() + " to: " + storeNew.getAbsolutePath()); // NOI18N
237
ErrorManager.getDefault().notify(e);
238             return true;
239         } finally {
240             if (oos != null) try { oos.close(); } catch (IOException e) {}
241             if (dis != null) try { dis.close(); } catch (IOException e) {}
242         }
243         storeSerial++;
244         try {
245             FileUtils.renameFile(storeNew, store);
246         } catch (IOException ex) {
247             ErrorManager.getDefault().notify(ex);
248         }
249         return true;
250     }
251
252     private void skip(InputStream is, long len) throws IOException {
253         while (len > 0) {
254             long n = is.skip(len);
255             if (n < 0) throw new EOFException("Missing " + len + " bytes."); // NOI18N
256
len -= n;
257         }
258     }
259
260     private String JavaDoc readChars(DataInputStream dis, int len) throws IOException {
261         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(len);
262         while (len-- > 0) {
263             sb.append(dis.readChar());
264         }
265         return sb.toString();
266     }
267
268     private Map<File, FileInformation> readValue(DataInputStream dis, String JavaDoc dirPath) throws IOException {
269         Map<File, FileInformation> map = new HashMap<File, FileInformation>();
270         int len = dis.readInt();
271         while (len-- > 0) {
272             int nameLen = dis.readInt();
273             String JavaDoc name = readChars(dis, nameLen);
274             File file = new File(dirPath, name);
275             int status = dis.readInt();
276             FileInformation info = new FileInformation(status & 65535, status > 65535);
277             map.put(file, info);
278         }
279         return map;
280     }
281
282     private void writeEntry(DataOutputStream dos, String JavaDoc dirPath, Object JavaDoc value) throws IOException {
283
284         Map map = (Map) value;
285         Set set = map.keySet();
286         ByteArrayOutputStream baos = new ByteArrayOutputStream(set.size() * 50);
287         DataOutputStream temp = new DataOutputStream(baos);
288
289         temp.writeInt(set.size());
290         for (Iterator i = set.iterator(); i.hasNext();) {
291             File file = (File) i.next();
292             FileInformation info = (FileInformation) map.get(file);
293             temp.writeInt(file.getName().length());
294             temp.writeChars(file.getName());
295             temp.writeInt(info.getStatus() + (info.isDirectory() ? 65536 : 0));
296         }
297         temp.close();
298         byte [] valueBytes = baos.toByteArray();
299
300         dos.writeInt(dirPath.length());
301         dos.writeInt(valueBytes.length);
302         dos.writeChars(dirPath);
303         dos.write(valueBytes);
304     }
305
306     private boolean isValuable(Object JavaDoc value) {
307         Map map = (Map) value;
308         for (Iterator i = map.values().iterator(); i.hasNext();) {
309             FileInformation info = (FileInformation) i.next();
310             if ((info.getStatus() & STATUS_VALUABLE) != 0) return true;
311         }
312         return false;
313     }
314
315     private File getStore(File dir) {
316         String JavaDoc dirPath = dir.getAbsolutePath();
317         int dirHash = dirPath.hashCode();
318         return new File(cacheStore, Integer.toString(dirHash % 173 + 172) + ".bin"); // NOI18N
319
}
320
321     private void initCacheStore() {
322         String JavaDoc userDir = System.getProperty("netbeans.user"); // NOI18N
323
if (userDir != null) {
324             cacheStore = new File(new File(new File (userDir, "var"), "cache"), CACHE_DIRECTORY); // NOI18N
325
} else {
326             File cachedir = FileUtil.toFile(Repository.getDefault().getDefaultFileSystem().getRoot());
327             cacheStore = new File(cachedir, CACHE_DIRECTORY); // NOI18N
328
}
329         cacheStore.mkdirs();
330     }
331
332     private static void copyStreams(OutputStream out, InputStream in, int len) throws IOException {
333         byte [] buffer = new byte[4096];
334         for (;;) {
335             int n = (len <= 4096) ? len : 4096;
336             n = in.read(buffer, 0, n);
337             if (n < 0) throw new EOFException("Missing " + len + " bytes."); // NOI18N
338
out.write(buffer, 0, n);
339             if ((len -= n) == 0) break;
340         }
341         out.flush();
342     }
343 }
344
Popular Tags