KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > subversion > client > parser > EntriesCache


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 package org.netbeans.modules.subversion.client.parser;
20
21 import java.io.BufferedReader JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileReader JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Set JavaDoc;
31 import org.openide.ErrorManager;
32 import org.openide.xml.XMLUtil;
33 import org.xml.sax.Attributes JavaDoc;
34 import org.xml.sax.InputSource JavaDoc;
35 import org.xml.sax.SAXException JavaDoc;
36 import org.xml.sax.SAXParseException JavaDoc;
37 import org.xml.sax.XMLReader JavaDoc;
38 import org.xml.sax.helpers.DefaultHandler JavaDoc;
39
40 /**
41  *
42  * @author Tomas Stupka
43  */

44 public class EntriesCache {
45
46
47     private static final String JavaDoc SVN_THIS_DIR = "svn:this_dir"; // NOI18N
48
private static final String JavaDoc EMPTY_STRING = "";
49     private static final String JavaDoc DELIMITER = "\f";
50     
51     private class EntryAttributes extends HashMap JavaDoc<String JavaDoc, Map JavaDoc<String JavaDoc, String JavaDoc>> { };
52     
53     /**
54      * The order as it is defined should be the same as how the Subvesion entries handler
55      * expects to read the entries file. This ordering is based on Subversion 1.4.0
56      */

57     static String JavaDoc[] entryFileAttributes = new String JavaDoc[] {
58         "name",
59         "kind",
60         "revision",
61         "url",
62         "repos",
63         "schedule",
64         "text-time",
65         "checksum",
66         "committed-date",
67         "committed-rev",
68         "last-author",
69         "has-props",
70         "has-prop-mods",
71         "cachable-props",
72         "present-props",
73         "prop-reject-file",
74         "conflict-old",
75         "conflict-new",
76         "conflict-wrk",
77         "copied",
78         "copyfrom-url",
79         "copyfrom-rev",
80         "deleted",
81         "absent",
82         "incomplete",
83         "uuid",
84         "lock-token",
85         "lock-owner",
86         "lock-comment",
87         "lock-creation-date",
88     };
89     
90     private static final Set JavaDoc<String JavaDoc> BOOLEAN_ATTRIBUTES = new java.util.HashSet JavaDoc<String JavaDoc>();
91     static {
92         BOOLEAN_ATTRIBUTES.add("has-props");
93         BOOLEAN_ATTRIBUTES.add("has-prop-mods");
94         BOOLEAN_ATTRIBUTES.add("copied");
95         BOOLEAN_ATTRIBUTES.add("deleted");
96     }
97     
98     private class EntriesFile {
99         long ts;
100         long size;
101         EntryAttributes attributes;
102         EntriesFile(EntryAttributes attributes, long ts, long size) {
103             this.ts = ts;
104             this.size = size;
105             this.attributes = attributes;
106         }
107     }
108         
109     private class Entries extends HashMap JavaDoc<String JavaDoc, EntriesFile> {};
110     
111     private Entries entries;
112     private static EntriesCache instance;
113             
114     private EntriesCache() { }
115     
116     static EntriesCache getInstance() {
117         if(instance == null) {
118             instance = new EntriesCache();
119         }
120         return instance;
121     }
122     
123     Map JavaDoc<String JavaDoc, String JavaDoc> getFileAttributes(File JavaDoc file) throws IOException JavaDoc, SAXException JavaDoc {
124         File JavaDoc entriesFile = SvnWcUtils.getEntriesFile(file);
125         if(entriesFile==null) {
126             return null;
127         }
128         return getFileAttributes(entriesFile, file);
129     }
130
131     private synchronized Map JavaDoc<String JavaDoc, String JavaDoc> getFileAttributes(final File JavaDoc entriesFile, final File JavaDoc file) throws IOException JavaDoc, SAXException JavaDoc {
132         EntriesFile ef = getEntries().get(entriesFile.getAbsolutePath());
133         long lastModified = entriesFile.lastModified();
134         long fileLength = entriesFile.length();
135         if(ef == null || ef.ts != lastModified || ef.size != fileLength) {
136             EntryAttributes ea = getAttributesFromEntriesFile(entriesFile);
137             ef = new EntriesFile(getMergedAttributes(ea), lastModified, fileLength);
138             getEntries().put(entriesFile.getAbsolutePath(), ef);
139         }
140         if(ef.attributes.get(file.getName()) == null) {
141             // file does not exist in the svn metadata and
142
// wasn't added to the entires cache yet
143
Map JavaDoc<String JavaDoc, String JavaDoc> attributes = mergeThisDirAttributes(file.isDirectory(), file.getName(), ef.attributes);
144         }
145         
146         return ef.attributes.get(file.isDirectory() ? SVN_THIS_DIR : file.getName());
147     }
148
149     private EntryAttributes getMergedAttributes(EntryAttributes ea) throws SAXException JavaDoc {
150         for(String JavaDoc fileName : ea.keySet()) {
151             boolean isDirectory = ea.get(fileName).get("kind").equals("dir");
152             Map JavaDoc<String JavaDoc, String JavaDoc> attributes = mergeThisDirAttributes(isDirectory, fileName, ea);
153             if(isDirectory) {
154                 attributes.put(WorkingCopyDetails.IS_HANDLED, "" + (ea.get(SVN_THIS_DIR).get("deleted") == null)); // NOI18N
155
} else {
156                 if(ea.get(fileName) != null) {
157                     for(Map.Entry JavaDoc<String JavaDoc, String JavaDoc> entry : ea.get(fileName).entrySet()) {
158                         attributes.put(entry.getKey(), entry.getValue());
159                     }
160                 }
161                 // it's realy a file
162
attributes.put(WorkingCopyDetails.IS_HANDLED, "" + (ea.containsKey(fileName) && ea.get("deleted") == null)); // NOI18N
163
}
164         }
165         return ea;
166     }
167
168     private Map JavaDoc<String JavaDoc, String JavaDoc> mergeThisDirAttributes(final boolean isDirectory, final String JavaDoc fileName, final EntryAttributes ea) {
169         Map JavaDoc<String JavaDoc, String JavaDoc> attributes = ea.get(fileName);
170         if(attributes == null) {
171            attributes = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
172            ea.put(fileName, attributes);
173         }
174         for(Map.Entry JavaDoc<String JavaDoc, String JavaDoc> entry : ea.get(SVN_THIS_DIR).entrySet()) {
175             String JavaDoc key = entry.getKey();
176             String JavaDoc value = entry.getValue();
177             if(isDirectory) {
178                 attributes.put(key, value);
179             } else {
180                 if(key.equals("url")) {
181                     if( attributes.get(key) == null ) {
182                         attributes.put(key, value + "/" + fileName);
183                     }
184                 } else if( key.equals("uuid") ||
185                            key.equals("repos") ||
186                            key.equals("revision") ||
187                            key.equals(WorkingCopyDetails.VERSION_ATTR_KEY)) {
188                     if( attributes.get(key) == null ) {
189                         attributes.put(key, value);
190                     }
191                 }
192             }
193         }
194         return attributes;
195     }
196     
197     private EntryAttributes getAttributesFromEntriesFile(File JavaDoc entriesFile) throws IOException JavaDoc, SAXException JavaDoc {
198         //We need to check the first line of the File.
199
//If it is a number, its the new format.
200
//Otherwise, treat it as XML
201
boolean isXml = false;
202         BufferedReader JavaDoc fileReader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(new FileInputStream JavaDoc(entriesFile), "UTF8"));
203         try {
204             String JavaDoc firstLine = fileReader.readLine();
205             try {
206                 Integer.valueOf(firstLine);
207                 isXml = false;
208             } catch (NumberFormatException JavaDoc ex) {
209                 isXml = true;
210             }
211
212             if (isXml) {
213                 return loadAttributesFromXml(entriesFile);
214             } else {
215                 return loadAttributesFromPlainText(fileReader, entriesFile.getAbsolutePath());
216             }
217         } finally {
218             fileReader.close();
219         }
220     }
221     
222     private EntryAttributes loadAttributesFromXml(File JavaDoc entriesFile) throws IOException JavaDoc, SAXException JavaDoc {
223         //Parse the entries file
224
XMLReader JavaDoc saxReader = XMLUtil.createXMLReader();
225         XmlEntriesHandler xmlEntriesHandler = new XmlEntriesHandler();
226         saxReader.setContentHandler(xmlEntriesHandler);
227         saxReader.setErrorHandler(xmlEntriesHandler);
228         InputStream JavaDoc inputStream = new java.io.FileInputStream JavaDoc(entriesFile);
229
230         try {
231             saxReader.parse(new InputSource JavaDoc(inputStream));
232         } catch (SAXException JavaDoc ex) {
233             throw ex;
234         } finally {
235             inputStream.close();
236         }
237         return xmlEntriesHandler.getEntryAttributes();
238     }
239
240     //New entries file format, as of SVN 1.4.0
241
private EntryAttributes loadAttributesFromPlainText(BufferedReader JavaDoc entriesReader, String JavaDoc entryFilePath) throws IOException JavaDoc {
242         EntryAttributes returnValue = new EntryAttributes();
243         
244         int attrIndex = 0;
245         
246         String JavaDoc entryName = null;
247         Map JavaDoc<String JavaDoc, String JavaDoc> attributes = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
248         
249         String JavaDoc nextLine = entriesReader.readLine();
250         while (nextLine != null) {
251             if (attrIndex == 0) {
252                 entryName = nextLine;
253                 if (entryName.equals(EMPTY_STRING)) {
254                     entryName = SVN_THIS_DIR;
255                 }
256             }
257             
258             if (!(EMPTY_STRING.equals(nextLine))) {
259                 if (isBooleanValue(entryFileAttributes[attrIndex])) {
260                     nextLine = "true";
261                 }
262                 attributes.put(entryFileAttributes[attrIndex], nextLine);
263             }
264             attrIndex++;
265             nextLine = entriesReader.readLine();
266  
267             if(nextLine != null && attrIndex > entryFileAttributes.length - 1) {
268                 ErrorManager.getDefault().log(ErrorManager.WARNING, "Skipping attribute from position " + attrIndex + " in entry file " + entryFilePath); // NOI18N
269
for( ; nextLine != null && !DELIMITER.equals(nextLine); nextLine = entriesReader.readLine());
270             }
271             
272             if (DELIMITER.equals(nextLine)) {
273                 attributes.put(WorkingCopyDetails.VERSION_ATTR_KEY, WorkingCopyDetails.VERSION_14);
274                 returnValue.put(entryName, attributes);
275                 attributes = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
276                 attrIndex = 0;
277                 nextLine = entriesReader.readLine();
278                 continue;
279             }
280             
281         }
282         
283         return returnValue;
284     }
285     
286     private static boolean isBooleanValue(String JavaDoc attribute) {
287         return BOOLEAN_ATTRIBUTES.contains(attribute);
288     }
289     
290     private class XmlEntriesHandler extends DefaultHandler JavaDoc {
291         
292         private static final String JavaDoc ENTRY_ELEMENT_NAME = "entry"; // NOI18N
293
private static final String JavaDoc NAME_ATTRIBUTE = "name"; // NOI18N
294
private EntryAttributes entryAttributes;
295         
296         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc elementAttributes) throws SAXException JavaDoc {
297             if (ENTRY_ELEMENT_NAME.equals(qName)) {
298                 Map JavaDoc<String JavaDoc, String JavaDoc> attributes = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
299                 for (int i = 0; i < elementAttributes.getLength(); i++) {
300                     String JavaDoc name = elementAttributes.getQName(i);
301                     String JavaDoc value = elementAttributes.getValue(i);
302                     attributes.put(name, value);
303                 }
304                 
305                 String JavaDoc nameValue = attributes.get(NAME_ATTRIBUTE);
306                 if (EMPTY_STRING.equals(nameValue)) {
307                     nameValue = SVN_THIS_DIR;
308                 }
309                 if(entryAttributes == null) {
310                     entryAttributes = new EntryAttributes();
311                 }
312                 attributes.put(WorkingCopyDetails.VERSION_ATTR_KEY, WorkingCopyDetails.VERSION_13);
313                 entryAttributes.put(nameValue, attributes);
314             }
315         }
316
317         public void error(SAXParseException JavaDoc e) throws SAXException JavaDoc {
318             throw e;
319         }
320
321         public void fatalError(SAXParseException JavaDoc e) throws SAXException JavaDoc {
322             throw e;
323         }
324
325         public EntryAttributes getEntryAttributes() {
326             return entryAttributes;
327         }
328     }
329
330     private Entries getEntries() {
331         if(entries == null) {
332             entries = new Entries();
333         }
334         return entries;
335     }
336
337 }
338
Popular Tags