KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > interproc > PropertyDatabase


1 /*
2  * Bytecode analysis framework
3  * Copyright (C) 2005, University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.ba.interproc;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.BufferedWriter JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.io.OutputStreamWriter JavaDoc;
31 import java.io.Writer JavaDoc;
32 import java.nio.charset.Charset JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.TreeSet JavaDoc;
37
38 import edu.umd.cs.findbugs.ba.AnalysisContext;
39 import edu.umd.cs.findbugs.ba.ClassMember;
40 import edu.umd.cs.findbugs.ba.XFactory;
41 import edu.umd.cs.findbugs.ba.XField;
42 import edu.umd.cs.findbugs.ba.XMethod;
43
44 /**
45  * Property database for interprocedural analysis.
46  *
47  * @param <KeyType> key type: either XMethod or XField
48  * @param <ValueType> value type: a value that summarizes some property of the associated key
49  * @author David Hovemeyer
50  */

51 public abstract class PropertyDatabase<KeyType extends ClassMember, ValueType> {
52     private Map JavaDoc<KeyType, ValueType> propertyMap;
53     
54     /**
55      * Constructor.
56      * Creates an empty property database.
57      */

58     protected PropertyDatabase() {
59         this.propertyMap = new HashMap JavaDoc<KeyType, ValueType>();
60     }
61     
62     /**
63      * Set a property.
64      *
65      * @param key the key
66      * @param property the property
67      */

68     public void setProperty(KeyType key, ValueType property) {
69         propertyMap.put(key, property);
70     }
71     
72     /**
73      * Get a property.
74      *
75      * @param key the key
76      * @return the property, or null if no property is set for this key
77      */

78     public ValueType getProperty(KeyType key) {
79         return propertyMap.get(key);
80     }
81     
82     public Set JavaDoc<KeyType> getKeys() {
83         return propertyMap.keySet();
84     }
85     /**
86      * Return whether or not the database is empty.
87      *
88      * @return true if the database is empty, false it it has at least one entry
89      */

90     public boolean isEmpty() {
91         return propertyMap.isEmpty();
92     }
93     
94     /**
95      * Remove a property.
96      *
97      * @param key the key
98      * @return the old property, or null if there was no property defined for this key
99      */

100     public ValueType removeProperty(KeyType key) {
101         return propertyMap.remove(key);
102     }
103     
104     /**
105      * Read property database from given file.
106      *
107      * @param fileName name of the database file
108      * @throws IOException
109      * @throws MethodPropertyDatabaseFormatException
110      */

111     public void readFromFile(String JavaDoc fileName) throws IOException JavaDoc, PropertyDatabaseFormatException {
112         read(new FileInputStream JavaDoc(fileName));
113     }
114
115     /**
116      * Read property database from an input stream.
117      * The InputStream is guaranteed to be closed, even if an
118      * exception is thrown.
119      *
120      * @param in the InputStream
121      * @throws IOException
122      * @throws MethodPropertyDatabaseFormatException
123      */

124     public void read(InputStream JavaDoc in) throws IOException JavaDoc, PropertyDatabaseFormatException {
125         BufferedReader JavaDoc reader = null;
126         
127         try {
128             reader = new BufferedReader JavaDoc(
129                 new InputStreamReader JavaDoc(in, Charset.forName("UTF-8")));
130             String JavaDoc line;
131             while ((line = reader.readLine()) != null) {
132                 line = line.trim();
133                 if (line.equals(""))
134                     continue;
135                 int bar = line.indexOf('|');
136                 if (bar < 0) {
137                     throw new PropertyDatabaseFormatException(
138                             "Invalid property database: missing separator");
139                 }
140                 KeyType key = parseKey(line.substring(0, bar));
141                 ValueType property = decodeProperty(line.substring(bar+1));
142                 
143                 setProperty(key, property);
144             }
145         } finally {
146             try {
147                 if (reader != null)
148                     reader.close();
149             } catch (IOException JavaDoc e) {
150                 // Ignore
151
}
152         }
153     }
154     
155     /**
156      * Write property database to given file.
157      *
158      * @param fileName name of the database file
159      * @throws IOException
160      */

161     public void writeToFile(String JavaDoc fileName) throws IOException JavaDoc {
162         write(new FileOutputStream JavaDoc(fileName));
163     }
164
165     @SuppressWarnings JavaDoc("unchecked")
166     private KeyType intern(XFactory xFactory, KeyType key) {
167         KeyType result = key;
168         try {
169             if (key instanceof XField)
170                 return (KeyType) xFactory.intern((XField)key);
171             else if (key instanceof XMethod)
172                 return (KeyType) xFactory.intern((XMethod)key);
173         } catch (Exception JavaDoc e) {
174             return key;
175         }
176         return result;
177     }
178     /**
179      * Write property database to an OutputStream.
180      * The OutputStream is guaranteed to be closed, even if an
181      * exception is thrown.
182      *
183      * @param out the OutputStream
184      * @throws IOException
185      */

186     public void write(OutputStream JavaDoc out) throws IOException JavaDoc {
187         BufferedWriter JavaDoc writer = null;
188         boolean missingClassWarningsSuppressed = AnalysisContext.currentAnalysisContext().setMissingClassWarningsSuppressed(true);
189         
190         try {
191             writer = new BufferedWriter JavaDoc(
192                     new OutputStreamWriter JavaDoc(out, Charset.forName("UTF-8")));
193             
194             TreeSet JavaDoc<KeyType> sortedMethodSet = new TreeSet JavaDoc<KeyType>();
195             XFactory xFactory = AnalysisContext.currentXFactory();
196             sortedMethodSet.addAll(propertyMap.keySet());
197             for (KeyType key : sortedMethodSet) {
198                 if (AnalysisContext.currentAnalysisContext().isApplicationClass(key.getClassName())) {
199                     
200                 ValueType property = propertyMap.get(key);
201                 writeKey(writer, intern(xFactory, key));
202                 writer.write("|");
203                 writer.write(encodeProperty(property));
204                 writer.write("\n");
205                 }
206             }
207         } finally {
208             AnalysisContext.currentAnalysisContext().setMissingClassWarningsSuppressed(missingClassWarningsSuppressed);
209             
210             try {
211                 if (writer != null)
212                     writer.close();
213             } catch (IOException JavaDoc e) {
214                 // Ignore
215
}
216         }
217     }
218
219     /**
220      * Parse a key from a String.
221      *
222      * @param s a String
223      * @return the decoded key
224      * @throws PropertyDatabaseFormatException
225      */

226     protected abstract KeyType parseKey(String JavaDoc s) throws PropertyDatabaseFormatException;
227
228     /**
229      * Write an encoded key to given Writer.
230      *
231      * @param writer the Writer
232      * @param key the key
233      */

234     protected abstract void writeKey(Writer JavaDoc writer, KeyType key) throws IOException JavaDoc;
235
236     /**
237      * Subclasses must define this to instantiate the actual property
238      * value from its string encoding.
239      *
240      * @param propStr String containing the encoded property
241      * @return the property
242      * @throws MethodPropertyDatabaseFormatException
243      */

244     protected abstract ValueType decodeProperty(String JavaDoc propStr)
245         throws PropertyDatabaseFormatException;
246
247     /**
248      * Subclasses must define this to encode a property
249      * as a string for output to a file.
250      *
251      * @param property the property
252      * @return a String which encodes the property
253      */

254     protected abstract String JavaDoc encodeProperty(ValueType property);
255
256 }
257
Popular Tags