001 /*
002 * Cobertura - http://cobertura.sourceforge.net/
003 *
004 * Copyright (C) 2003 jcoverage ltd.
005 * Copyright (C) 2005 Mark Doliner <thekingant@users.sourceforge.net>
006 *
007 * Cobertura is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published
009 * by the Free Software Foundation; either version 2 of the License,
010 * or (at your option) any later version.
011 *
012 * Cobertura is distributed in the hope that it will be useful, but
013 * WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Cobertura; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020 * USA
021 */
022
023 package net.sourceforge.cobertura.coverage;
024
025 import java.io.File;
026 import java.io.FileInputStream;
027 import java.io.FileNotFoundException;
028 import java.io.FileOutputStream;
029 import java.io.IOException;
030 import java.io.InputStream;
031 import java.io.ObjectInputStream;
032 import java.io.ObjectOutputStream;
033 import java.util.Collections;
034 import java.util.HashMap;
035 import java.util.Iterator;
036 import java.util.Map;
037 import java.util.Set;
038
039 import org.apache.log4j.Logger;
040
041 /**
042 * <p>
043 * This class implements HasBeenInstrumented so that when cobertura
044 * instruments itself, it will omit this class. It does this to
045 * avoid an infinite recursion problem because instrumented classes
046 * make use of this class.
047 * </p>
048 */
049 public class InstrumentationPersistence implements HasBeenInstrumented
050 {
051
052 /**
053 * Default file name used to write instrumentation information.
054 */
055 public static final String FILE_NAME = "cobertura.ser";
056
057 private static final Logger logger = Logger
058 .getLogger(InstrumentationPersistence.class);
059
060 final Map instrumentation = new HashMap();
061
062 protected Map loadInstrumentation()
063 {
064 File directory = getDirectory();
065
066 if (logger.isInfoEnabled())
067 {
068 logger.info("loading: " + directory + '/' + FILE_NAME);
069 }
070
071 try
072 {
073 return loadInstrumentation(new FileInputStream(new File(
074 directory, FILE_NAME)));
075 }
076 catch (FileNotFoundException ex)
077 {
078 logger.info(ex);
079 return Collections.EMPTY_MAP;
080 }
081 }
082
083 protected Map loadInstrumentation(InputStream is)
084 {
085 ObjectInputStream objects = null;
086 try
087 {
088 objects = new ObjectInputStream(is);
089 Map m = (Map)objects.readObject();
090 if (logger.isInfoEnabled())
091 {
092 logger.info("loaded " + m.size() + " entries.");
093 }
094 return m;
095 }
096 catch (ClassNotFoundException ex)
097 {
098 logger.error(ex);
099 return Collections.EMPTY_MAP;
100 }
101 catch (IOException ex)
102 {
103 logger.error(ex);
104 return Collections.EMPTY_MAP;
105 }
106 finally
107 {
108 if (objects != null)
109 {
110 try
111 {
112 objects.close();
113 }
114 catch (IOException ex)
115 {
116 if (logger.isDebugEnabled())
117 {
118 logger.debug(ex);
119 }
120 }
121 }
122
123 if (is != null)
124 {
125 try
126 {
127 is.close();
128 }
129 catch (IOException ex)
130 {
131 if (logger.isDebugEnabled())
132 {
133 logger.debug(ex);
134 }
135 }
136 }
137 }
138 }
139
140 protected void merge(Map m)
141 {
142 Iterator i = m.entrySet().iterator();
143 while (i.hasNext())
144 {
145 Map.Entry entry = (Map.Entry)i.next();
146 String classname = (String)entry.getKey();
147 if (instrumentation.containsKey(classname))
148 {
149 getInstrumentation(classname).merge(
150 (CoverageData)entry.getValue());
151 }
152 else
153 {
154 instrumentation.put(classname, entry.getValue());
155 }
156 }
157 }
158
159 private File getDirectory()
160 {
161 if (System.getProperty("net.sourceforge.cobertura.rawcoverage.dir") != null)
162 {
163 return new File(System
164 .getProperty("net.sourceforge.cobertura.rawcoverage.dir"));
165 }
166 return new File(System.getProperty("user.dir"));
167 }
168
169 protected void saveInstrumentation()
170 {
171 File directory = getDirectory();
172
173 if (logger.isInfoEnabled())
174 {
175 logger.info("saving: " + directory + '/' + FILE_NAME);
176 }
177
178 saveInstrumentation(directory);
179 }
180
181 protected void saveInstrumentation(File destDir)
182 {
183 FileOutputStream os = null;
184 ObjectOutputStream objects = null;
185
186 try
187 {
188 os = new FileOutputStream(new File(destDir, FILE_NAME));
189 objects = new ObjectOutputStream(os);
190 objects.writeObject(instrumentation);
191 if (logger.isInfoEnabled())
192 {
193 logger.info("saved " + instrumentation.size() + " entries.");
194 }
195 }
196 catch (IOException ex)
197 {
198 logger.error(ex);
199 }
200 finally
201 {
202 if (objects != null)
203 {
204 try
205 {
206 objects.close();
207 }
208 catch (IOException ex)
209 {
210 if (logger.isDebugEnabled())
211 {
212 logger.debug(ex);
213 }
214 }
215 }
216
217 if (os != null)
218 {
219 try
220 {
221 os.close();
222 }
223 catch (IOException ex)
224 {
225 if (logger.isDebugEnabled())
226 {
227 logger.debug(ex);
228 }
229 }
230 }
231 }
232 }
233
234 protected CoverageData getInstrumentation(String classname)
235 {
236 return (CoverageData)instrumentation.get(classname);
237 }
238
239 protected Set keySet()
240 {
241 return Collections.unmodifiableSet(instrumentation.keySet());
242 }
243
244 }