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.util.Timer;
026
027 import org.apache.log4j.Logger;
028
029 /**
030 * <p>
031 * This class implements HasBeenInstrumented so that when cobertura
032 * instruments itself, it will omit this class. It does this to
033 * avoid an infinite recursion problem because instrumented classes
034 * make use of this class.
035 * </p>
036 */
037 public class CoverageDataFactory extends InstrumentationPersistence
038 implements Runnable, HasBeenInstrumented
039 {
040
041 private static final Logger logger = Logger
042 .getLogger(CoverageDataFactory.class);
043 static final CoverageDataFactory instrumentationFactory = new CoverageDataFactory();
044
045 Timer timer = new Timer(true);
046
047 private CoverageDataFactory()
048 {
049 merge(loadInstrumentation());
050
051 if (logger.isInfoEnabled())
052 {
053 logger.info("loaded: " + keySet().size() + " items.");
054 }
055
056 /*
057 * TODO:
058 * I suspect this causes problems when
059 * net.sourceforge.cobertura.instrumentation.interval
060 * is not equal to 0. It seems like it deletes cobertura.ser just as
061 * it begins running the first test. So then we only have coverage
062 * data about the lines we tests. Also, attempting to load this as
063 * we begin testing prints an ugly file not found exception... Hmm,
064 * what's going on here? It should load with no problems, I think.
065 * It looks like it's trying to load the file from the wrong place,
066 * or something.
067 */
068 if (getInstrumentationInterval() > 0)
069 {
070 timer.schedule(new SaveInstrumentationTimer(this),
071 getInstrumentationInterval(),
072 getInstrumentationInterval());
073 }
074
075 Runtime.getRuntime().addShutdownHook(new Thread(this));
076 }
077
078 int getInstrumentationInterval()
079 {
080 return Integer.getInteger(
081 "net.sourceforge.cobertura.instrumentation.interval", 0)
082 .intValue() * 1000;
083 }
084
085 public void run()
086 {
087 if (logger.isInfoEnabled())
088 {
089 logger.info("shutdown hook started");
090 }
091
092 saveInstrumentation();
093
094 if (logger.isInfoEnabled())
095 {
096 logger.info("saved: " + keySet().size() + " items.");
097 }
098
099 if (logger.isInfoEnabled())
100 {
101 logger.info("shutdown hook has finished");
102 }
103 }
104
105 public static CoverageDataFactory getInstance()
106 {
107 return instrumentationFactory;
108 }
109
110 public CoverageData newInstrumentation(String className)
111 {
112 if (!instrumentation.containsKey(className))
113 {
114 instrumentation.put(className, new CoverageData());
115 }
116 return (CoverageData)instrumentation.get(className);
117 }
118 }