1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
/* 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
// ----------------------------------------------------------------------------
|