##### Coverage Report - org.owasp.dependencycheck.data.update.DataStoreMetaInfo

Classes in this File | Line Coverage | Branch Coverage | Complexity
DataStoreMetaInfo |
65% | 48/73
62% | 10/16
| 3.111111111111111;3.111

1 |  |
     /*
2 |  |
      * This file is part of dependency-check-core.
3 |  |
      *
4 |  |
      * Dependency-check-core is free software: you can redistribute it and/or modify it
5 |  |
      * under the terms of the GNU General Public License as published by the Free
6 |  |
      * Software Foundation, either version 3 of the License, or (at your option) any
7 |  |
      * later version.
8 |  |
      *
9 |  |
      * Dependency-check-core is distributed in the hope that it will be useful, but
10 |  |
      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 |  |
      * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 |  |
      * details.
13 |  |
      *
14 |  |
      * You should have received a copy of the GNU General Public License along with
15 |  |
      * dependency-check-core. If not, see http://www.gnu.org/licenses/.
16 |  |
      *
17 |  |
      * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
18 |  |
      */
19 |  |
     package org.owasp.dependencycheck.data.update;
20 |  |
21 |  |
     import java.io.File;
22 |  |
     import java.io.FileInputStream;
23 |  |
     import java.io.FileNotFoundException;
24 |  |
     import java.io.FileOutputStream;
25 |  |
     import java.io.IOException;
26 |  |
     import java.io.InputStream;
27 |  |
     import java.io.OutputStream;
28 |  |
     import java.io.OutputStreamWriter;
29 |  |
     import java.util.Properties;
30 |  |
     import java.util.logging.Level;
31 |  |
     import java.util.logging.Logger;
32 |  |
     import org.owasp.dependencycheck.data.UpdateException;
33 |  |
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
34 |  |
     import org.owasp.dependencycheck.utils.Settings;
35 |  |
36 |  |
     /**
37 |  |
      *
38 |  |
      * @author Jeremy Long (jeremy.long@owasp.org)
39 |  |
      */
40 |  |
     public class DataStoreMetaInfo {
41 |  |
42 |  |
         /**
43 |  |
          * Batch key word, used as key to store information about batch mode.
44 |  |
          */
45 |  |
         public static final String BATCH = "batch";
46 |  |
         /**
47 |  |
          * Modified key word, used as a key to store information about the modified
48 |  |
          * file (i.e. the containing the last 8 days of updates)..
49 |  |
          */
50 |  |
         public static final String MODIFIED = "modified";
51 |  |
         /**
52 |  |
          * The name of the properties file containing the timestamp of the last
53 |  |
          * update.
54 |  |
          */
55 |  |
         private static final String UPDATE_PROPERTIES_FILE = "data.properties";
56 |  |
         /**
57 |  |
          * The properties file key for the last updated field - used to store the
58 |  |
          * last updated time of the Modified NVD CVE xml file.
59 |  |
          */
60 |  |
         public static final String LAST_UPDATED = "lastupdated.modified";
61 |  |
         /**
62 |  |
          * Stores the last updated time for each of the NVD CVE files. These
63 |  |
          * timestamps should be updated if we process the modified file within 7
64 |  |
          * days of the last update.
65 |  |
          */
66 |  |
         public static final String LAST_UPDATED_BASE = "lastupdated.";
67 |  |
         /**
68 |  |
          * A collection of properties about the data.
69 |  |
          */
70 | 11 |
         private Properties properties = new Properties();
71 |  |
         /**
72 |  |
          * Indicates whether or not the updates are using a batch update mode or
73 |  |
          * not.
74 |  |
          */
75 |  |
         private boolean batchUpdateMode;
76 |  |
77 |  |
         /**
78 |  |
          * Get the value of batchUpdateMode.
79 |  |
          *
80 |  |
          * @return the value of batchUpdateMode
81 |  |
          */
82 |  |
         protected boolean isBatchUpdateMode() {
83 | 2 |
             return batchUpdateMode;
84 |  |
         }
85 |  |
86 |  |
         /**
87 |  |
          * Set the value of batchUpdateMode.
88 |  |
          *
89 |  |
          * @param batchUpdateMode new value of batchUpdateMode
90 |  |
          */
91 |  |
         protected void setBatchUpdateMode(boolean batchUpdateMode) {
92 | 1 |
             this.batchUpdateMode = batchUpdateMode;
93 | 1 |
         }
94 |  |
95 |  |
         /**
96 |  |
          * Constructs a new data properties object.
97 |  |
          */
98 | 11 |
         public DataStoreMetaInfo() {
99 | 11 |
             batchUpdateMode = !Settings.getString(Settings.KEYS.BATCH_UPDATE_URL, "").isEmpty();
100 | 11 |
             loadProperties();
101 | 11 |
         }
102 |  |
103 |  |
         /**
104 |  |
          * Loads the data's meta properties.
105 |  |
          */
106 |  |
         private void loadProperties() {
107 | 11 |
             final File file = getPropertiesFile();
108 | 11 |
             if (file.exists()) {
109 | 9 |
                 InputStream is = null;
110 |  |
                 try {
111 | 9 |
                     is = new FileInputStream(file);
112 | 0 |
                 } catch (FileNotFoundException ignore) {
113 |  |
                     //we will never get here as we check for existence above.
114 | 0 |
                     Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignore);
115 | 9 |
                 }
116 |  |
                 try {
117 | 9 |
                     properties.load(is);
118 | 0 |
                 } catch (IOException ex) {
119 | 0 |
                     final String msg = String.format("Unable to load properties file '%s'", file.getPath());
120 | 0 |
                     Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.WARNING, msg);
121 | 0 |
                     Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
122 |  |
                 } finally {
123 | 9 |
                     if (is != null) {
124 |  |
                         try {
125 | 9 |
                             is.close();
126 | 0 |
                         } catch (IOException ex) {
127 | 0 |
                             final String msg = String.format("Unable to close properties file '%s'", file.getPath());
128 | 0 |
                             Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.WARNING, msg);
129 | 0 |
                             Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
130 | 9 |
                         }
131 |  |
                     }
132 |  |
                 }
133 |  |
             }
134 | 11 |
         }
135 |  |
136 |  |
         /**
137 |  |
          * Returns whether or not any properties are set.
138 |  |
          *
139 |  |
          * @return whether or not any properties are set
140 |  |
          */
141 |  |
         public boolean isEmpty() {
142 | 3 |
             return properties.isEmpty();
143 |  |
         }
144 |  |
145 |  |
         /**
146 |  |
          * Writes a properties file containing the last updated date to the
147 |  |
          * VULNERABLE_CPE directory.
148 |  |
          *
149 |  |
          * @param updatedValue the updated nvdcve entry
150 |  |
          * @throws UpdateException is thrown if there is an update exception
151 |  |
          */
152 |  |
         public void save(NvdCveInfo updatedValue) throws UpdateException {
153 | 1 |
             if (updatedValue == null) {
154 | 0 |
                 return;
155 |  |
             }
156 | 1 |
             final File cveProp = getPropertiesFile();
157 | 1 |
             final Properties prop = new Properties();
158 | 1 |
             if (cveProp.exists()) {
159 | 1 |
                 FileInputStream in = null;
160 |  |
                 try {
161 | 1 |
                     in = new FileInputStream(cveProp);
162 | 1 |
                     prop.load(in);
163 | 0 |
                 } catch (Exception ignoreMe) {
164 | 0 |
                     Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignoreMe);
165 |  |
                 } finally {
166 | 1 |
                     if (in != null) {
167 |  |
                         try {
168 | 1 |
                             in.close();
169 | 0 |
                         } catch (Exception ignoreMeToo) {
170 | 0 |
                             Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignoreMeToo);
171 | 1 |
                         }
172 |  |
                     }
173 |  |
                 }
174 |  |
             }
175 | 1 |
             prop.put("version", CveDB.DB_SCHEMA_VERSION);
176 | 1 |
             prop.put(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp()));
177 |  |
178 | 1 |
             OutputStream os = null;
179 | 1 |
             OutputStreamWriter out = null;
180 |  |
             try {
181 | 1 |
                 os = new FileOutputStream(cveProp);
182 | 1 |
                 out = new OutputStreamWriter(os, "UTF-8");
183 | 1 |
                 prop.store(out, "Meta data about data and data sources used by dependency-check");
184 | 0 |
             } catch (FileNotFoundException ex) {
185 | 0 |
                 Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
186 | 0 |
                 throw new UpdateException("Unable to find last updated properties file.", ex);
187 | 0 |
             } catch (IOException ex) {
188 | 0 |
                 Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
189 | 0 |
                 throw new UpdateException("Unable to update last updated properties file.", ex);
190 |  |
             } finally {
191 | 1 |
                 if (out != null) {
192 |  |
                     try {
193 | 1 |
                         out.close();
194 | 0 |
                     } catch (IOException ex) {
195 | 0 |
                         Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ex);
196 | 1 |
                     }
197 |  |
                 }
198 | 1 |
                 if (os != null) {
199 |  |
                     try {
200 | 1 |
                         os.close();
201 | 0 |
                     } catch (IOException ex) {
202 | 0 |
                         Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ex);
203 | 1 |
                     }
204 |  |
                 }
205 |  |
             }
206 | 1 |
         }
207 |  |
208 |  |
         /**
209 |  |
          * Returns the property value for the given key. If the key is not contained
210 |  |
          * in the underlying properties null is returned.
211 |  |
          *
212 |  |
          * @param key the property key
213 |  |
          * @return the value of the property
214 |  |
          */
215 |  |
         public String getProperty(String key) {
216 | 1 |
             return properties.getProperty(key);
217 |  |
         }
218 |  |
219 |  |
         /**
220 |  |
          * Returns the property value for the given key. If the key is not contained
221 |  |
          * in the underlying properties the default value is returned.
222 |  |
          *
223 |  |
          * @param key the property key
224 |  |
          * @param defaultValue the default value
225 |  |
          * @return the value of the property
226 |  |
          */
227 |  |
         public String getProperty(String key, String defaultValue) {
228 | 1 |
             return properties.getProperty(key, defaultValue);
229 |  |
         }
230 |  |
231 |  |
         /**
232 |  |
          * Retrieves the properties file.
233 |  |
          *
234 |  |
          * @return the properties file
235 |  |
          */
236 |  |
         public static File getPropertiesFile() {
237 | 16 |
             final File dataDirectory = Settings.getFile(Settings.KEYS.DATA_DIRECTORY);
238 | 16 |
             final File file = new File(dataDirectory, UPDATE_PROPERTIES_FILE);
239 | 16 |
             return file;
240 |  |
         }
241 |  |
     }