Source code: cvebrowser/dictionary/data/parser/CSVFile.java
1 package cvebrowser.dictionary.data.parser;
2
3 import java.io.IOException;
4
5 import cvebrowser.util.parser.FileType;
6 import cvebrowser.util.parser.ParserException;
7 import cvebrowser.util.parser.Types;
8
9 import java.io.LineNumberReader;
10 import java.io.FileInputStream;
11 import java.io.InputStream;
12 import java.io.BufferedReader;
13 import java.io.InputStreamReader;
14 import java.io.FileNotFoundException;
15 import java.io.File;
16 import java.io.ObjectOutputStream;
17 import java.io.ObjectInputStream;
18
19 import java.util.zip.GZIPInputStream;
20 import java.util.ResourceBundle;
21 import java.util.Locale;
22 import java.util.HashMap;
23
24 import java.util.regex.Pattern;
25 import java.util.regex.Matcher;
26
27 /**
28 * Base class to manage CVE / CAN CSV files.
29 * @author Jose Vicente Nunez Zuleta (josevnz@users.sourceforge.net)
30 * @version 0.4 - 10/02/2003
31 */
32 public final class CSVFile implements FileType {
33
34 private int _type;
35 private String _version;
36 private static ResourceBundle _bundle = ResourceBundle.getBundle(CSVFile.class.getName(), Locale.getDefault());
37 private static final String [] _searchPattern = {
38 "\"CVE Version (\\d{8})\"",
39 "\"Date: (\\d{8})\",,,,,"
40 };
41
42 private Pattern [] _versionPattern;
43
44 /**
45 * Instance to the LineNumberReader used to parse the CVS file
46 */
47 private LineNumberReader _reader;
48 private InputStream _stream;
49 private HashMap _typeMap;
50 private String _file;
51
52 /**
53 * Number of chars that will be counted to keep the mark.
54 */
55 protected static final int KEEP_MARK_LIMIT = 1000000;
56
57 /**
58 * Opens a file for processing. The file could be uncompressed or compressed with Gzip.
59 * @param file_ the name of the file to process
60 * @throws IllegalArgumentException If any of the required arguments is null.
61 * @throws ParserException
62 * @throws IOException
63 * @since 0.1
64 */
65 public CSVFile(String file_) throws IllegalArgumentException, ParserException, IOException {
66 if (file_ == null) {
67 throw new IllegalArgumentException(_bundle.getString("cvebrowser.dictionary.data.parser.CSVFile.CSVFile.error.argumentIsRequired"));
68 }
69 File csvFile = new File(file_); // Use a file object to check if the proposed file can be used.
70 if ( (csvFile != null) && csvFile.exists() && csvFile.canRead() && (csvFile.length() > 0) ) {
71 init(new FileInputStream(file_));
72 _file = file_;
73 } else {
74 throw new IllegalArgumentException(_bundle.getString("cvebrowser.dictionary.data.parser.CSVFile.CSVFile.error.fileCannotBeUsed") + "(" + file_ + ")");
75 }
76 }
77
78 /**
79 * Parametric constructor.
80 * @param inputStream_ the input stream to process
81 * @throws IllegalArgumentException If any of the required arguments is null.
82 * @throws ParserException
83 * @throws IOException
84 * @since 0.2
85 */
86 public CSVFile(InputStream inputStream_) throws IllegalArgumentException, ParserException, IOException {
87 init(inputStream_);
88 }
89
90 /**
91 * Opens a input stream for processing. The stream could be uncompressed or compressed with Gzip.
92 * @param inputStream_ the input stream to process
93 * @throws IllegalArgumentException If any of the required arguments is null.
94 * @throws ParserException
95 * @throws IOException
96 * @since 0.2
97 */
98 protected void init(InputStream inputStream_) throws IllegalArgumentException, ParserException, IOException {
99 if (inputStream_ == null) {
100 throw new IllegalArgumentException(_bundle.getString("cvebrowser.dictionary.data.parser.CSVFile.CSVFile.error.argumentIsRequired") + ": inputStream_");
101 }
102 _stream = inputStream_;
103 _typeMap = new HashMap();
104 _typeMap.put(String.valueOf(Types.DATA_TYPE_CVE), Types.TEXT_CVE);
105 _typeMap.put(String.valueOf(Types.DATA_TYPE_CAN), Types.TEXT_CAN);
106 Matcher matcher = null;
107 _versionPattern = new Pattern[_searchPattern.length];
108 _type = Types.DATA_TYPE_UNKNOWN;
109 _version = Types.UNKNOWN_VERSION;
110 try {
111 // try to get a compressed stream. If that fails get a non compressed stream.
112 try {
113 _reader = new LineNumberReader(new InputStreamReader(new GZIPInputStream(inputStream_)));
114 // The uncompression failed, try to get an uncompressed stream (maybe the file is not compressed).
115 } catch (IOException ioexp) {
116 _reader = new LineNumberReader(new InputStreamReader(inputStream_));
117 }
118 // Mark the stream
119 if (_reader.markSupported()) {
120 _reader.mark(KEEP_MARK_LIMIT);
121 }
122 // Compile all the patterns
123 for (int idx = 0; idx < _versionPattern.length; idx++) {
124 _versionPattern[idx] = Pattern.compile(_searchPattern[idx]);
125 }
126 String line = _reader.readLine();
127 if (line == null) {
128 throw new ParserException(_bundle.getString("cvebrowser.dictionary.data.parser.CSVFile.CSVFile.error.lastLineWasNull"), new NullPointerException());
129 }
130 matcher = _versionPattern[0].matcher(line);
131 if (matcher.find()) { // Is a CVE CVS data file. Now get the version
132 _type = Types.DATA_TYPE_CVE;
133 _version = matcher.group(1);
134 } else { // A CAN file has the version on the second line
135 line = _reader.readLine();
136 matcher = _versionPattern[1].matcher(line);
137 if (matcher.find()) { // Is a CVE CVS data file. Now get the version
138 _type = Types.DATA_TYPE_CAN;
139 _version = matcher.group(1);
140 }
141 }
142 } catch (IOException ioexp) {
143 if (_reader != null) {
144 try { _reader.close(); } catch (IOException ignore) {};
145 }
146 throw new ParserException(_bundle.getString("cvebrowser.dictionary.data.parser.CSVFile.CSVFile.error.exception"), ioexp);
147 } finally {
148 // Reset the _reader to their original position
149 if (_reader.markSupported()) {
150 _reader.reset();
151 }
152 }
153 }
154
155 /**
156 * Returns the type of a given file.
157 * @return int Type of the file as defined in {@link Types Types}
158 * @throws ParserException
159 * @see Types
160 * @since 0.1
161 */
162 public int getType() throws ParserException {
163 return _type;
164 }
165
166 /**
167 * Get the type as a string
168 * @return String
169 * @throws ParserException
170 */
171 public String getTypeAsString() throws ParserException {
172 return (String) _typeMap.get(String.valueOf(_type));
173 }
174
175 /**
176 * Return the version of the given CSV (CAN or CVE) file.
177 * @return String
178 * @since 0.1
179 */
180 public String getVersion() throws ParserException {
181 return _version;
182 }
183
184 /**
185 * Release any opened resources. Calling any method after this invocation will cause an error.
186 * @since 0.1
187 */
188 public void close() {
189 if (_reader != null) {
190 try { _reader.close(); } catch (IOException ignore) {};
191 }
192 if (_stream != null) {
193 try { _stream.close(); } catch (IOException ignore) {};
194 }
195 }
196
197 /**
198 * Returns the underliying reader to the caller.
199 * @return LineNumberReader
200 * @throws IOException
201 * @since 0.1
202 */
203 public LineNumberReader getLineNumberReader() throws IOException {
204 return _reader;
205 }
206
207 /**
208 * Return the inout stream containing the CVS file to the caller.
209 * @return InputStream
210 * @since 0.3
211 */
212 public InputStream getInputStream() {
213 return _stream;
214 }
215
216 /**
217 * Release any opened resources
218 * @since 0.1
219 */
220 public void finalize() {
221 close();
222 if (_typeMap != null) {
223 _typeMap.clear();
224 }
225 }
226
227 /**
228 * Make this class uncloneable. Anyone who wants to use this class must use the constructor.
229 * @throws CloneNotSupportedException
230 */
231 public final Object clone() throws java.lang.CloneNotSupportedException {
232 throw new java.lang.CloneNotSupportedException();
233 }
234
235 /**
236 * Make this class unserializable. Any attempt to serialize will throw an exception.
237 * @param out_
238 * @throws IOException
239 */
240 private final void writeObject(ObjectOutputStream out_) throws java.io.IOException {
241 throw new java.io.IOException();
242 }
243
244 /**
245 * Make this class undeserializeable. Throw an exception if this method is ever called.
246 * @param in_
247 * @throws IOException
248 */
249 private final void readObject(ObjectInputStream in_) throws java.io.IOException {
250 throw new java.io.IOException();
251 }
252 }