blob: 14bfba453e7b4d87b7ca00e9951744e942440a3e [file] [log] [blame]
/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Common Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/cpl-v10.html
*
* $Id: EMMAProperties.java,v 1.1.1.1.2.3 2004/07/16 23:32:03 vlad_r Exp $
*/
package com.vladium.emma;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.WeakHashMap;
import com.vladium.util.ClassLoaderResolver;
import com.vladium.util.IProperties;
import com.vladium.util.Property;
import com.vladium.emma.report.IReportProperties;
import com.vladium.emma.report.ReportProperties;
// ----------------------------------------------------------------------------
/**
* A reflection of "${IAppConstants.APP_PROPERTY_RES_NAME}.properties" resource
* as viewed by a given classloader.
*
* @author Vlad Roubtsov, (C) 2003
*/
public
abstract class EMMAProperties
{
// public: ................................................................
public static final String GENERIC_PROPERTY_OVERRIDE_PREFIX = "D";
// [the DEFAULT_xxx settings duplicate the defaults in APP_DEFAULT_PROPERTIES_RES_NAME
// resource to provide a safe fallback option if that resource cannot be loaded]
public static final String DEFAULT_META_DATA_OUT_FILE = "coverage.em";
public static final Boolean DEFAULT_META_DATA_OUT_MERGE = Boolean.TRUE;
public static final String PREFIX_META_DATA = "metadata.";
public static final String PROPERTY_META_DATA_OUT_FILE = PREFIX_META_DATA + "out.file";
public static final String PROPERTY_META_DATA_OUT_MERGE = PREFIX_META_DATA + "out.merge";
public static final String DEFAULT_COVERAGE_DATA_OUT_FILE = "coverage.ec";
public static final Boolean DEFAULT_COVERAGE_DATA_OUT_MERGE = Boolean.TRUE;
public static final String PREFIX_COVERAGE_DATA = "coverage.";
public static final String PROPERTY_COVERAGE_DATA_OUT_FILE = PREFIX_COVERAGE_DATA + "out.file";
public static final String PROPERTY_COVERAGE_DATA_OUT_MERGE = PREFIX_COVERAGE_DATA + "out.merge";
public static final String DEFAULT_SESSION_DATA_OUT_FILE = "coverage.es";
public static final Boolean DEFAULT_SESSION_DATA_OUT_MERGE = Boolean.TRUE;
public static final String PREFIX_SESSION_DATA = "session.";
public static final String PROPERTY_SESSION_DATA_OUT_FILE = PREFIX_SESSION_DATA + "out.file";
public static final String PROPERTY_SESSION_DATA_OUT_MERGE = PREFIX_SESSION_DATA + "out.merge";
public static final String PROPERTY_TEMP_FILE_EXT = ".et";
public static final Map SYSTEM_PROPERTY_REDIRECTS; // set in <clinit>
/**
* Global method used to create an appearance that all app work has been
* done at the same point in time (useful for setting archive and report
* timestamps etc).
*
* @return the result of System.currentTimeMillis (), evaluated on the
* first call only
*/
public static synchronized long getTimeStamp ()
{
long result = s_timestamp;
if (result == 0)
{
s_timestamp = result = System.currentTimeMillis ();
}
return result;
}
public static String makeAppVersion (final int major, final int minor, final int build)
{
final StringBuffer buf = new StringBuffer ();
buf.append (major);
buf.append ('.');
buf.append (minor);
buf.append ('.');
buf.append (build);
return buf.toString ();
}
/**
* Wraps a Properties into a IProperties with the app's standard property
* mapping in place.
*
* @param properties [null results in null result]
*/
public static IProperties wrap (final Properties properties)
{
if (properties == null) return null;
return IProperties.Factory.wrap (properties, ReportProperties.REPORT_PROPERTY_MAPPER);
}
/**
* Retrieves application properties as classloader resource with a given name.
* [as seen from ClassLoaderResolver.getClassLoader ()]. The result is cached
* using this loader as a weak key.
*
* @return properties [can be null]
*/
public static synchronized IProperties getAppProperties ()
{
final ClassLoader loader = ClassLoaderResolver.getClassLoader ();
return getAppProperties (loader);
}
public static synchronized IProperties getAppProperties (final ClassLoader loader)
{
IProperties properties = (IProperties) s_properties.get (loader);
if (properties != null)
return properties;
else
{
final String appName = IAppConstants.APP_NAME_LC;
// note: this does not use Property.getAppProperties() by design,
// because that mechanism is not property alias-capable
final IProperties systemRedirects = wrap (Property.getSystemPropertyRedirects (EMMAProperties.SYSTEM_PROPERTY_REDIRECTS));
final IProperties appDefaults = wrap (Property.getProperties (appName + "_default.properties", loader));
final IProperties systemFile;
{
final String fileName = Property.getSystemProperty (appName + ".properties");
final File file = fileName != null
? new File (fileName)
: null;
systemFile = wrap (Property.getLazyPropertiesFromFile (file));
}
final IProperties system = wrap (Property.getSystemProperties (appName));
final IProperties userOverrides = wrap (Property.getProperties (appName + ".properties", loader));
// "vertical" inheritance order:
// (1) user overrides ("emma.properties" classloader resource)
// (2) system properties (java.lang.System.getProperties(),
// filtered by the app prefix)
// (3) system file properties ("emma.properties" system property,
// interpreted as a property file)
// (4) app defaults ("emma_default.properties" classloader resource)
// (5) system property redirects (report.out.encoding->file.encoding,
// report.out.dir->user.dir, etc)
properties = IProperties.Factory.combine (userOverrides,
IProperties.Factory.combine (system,
IProperties.Factory.combine (systemFile,
IProperties.Factory.combine (appDefaults,
systemRedirects))));
s_properties.put (loader, properties);
return properties;
}
}
// protected: .............................................................
// package: ...............................................................
// private: ...............................................................
private EMMAProperties () {} // prevent subclassing
private static long s_timestamp;
private static final Map /* ClassLoader->Properties */ s_properties; // set in <clinit>
static
{
s_properties = new WeakHashMap ();
final Map redirects = new HashMap ();
redirects.put (IReportProperties.PREFIX.concat (IReportProperties.OUT_ENCODING),
"file.encoding");
redirects.put (IReportProperties.PREFIX.concat (IReportProperties.OUT_DIR),
"user.dir");
SYSTEM_PROPERTY_REDIRECTS = Collections.unmodifiableMap (redirects);
}
} // end of class
// ----------------------------------------------------------------------------