• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: EMMAProperties.java,v 1.1.1.1.2.3 2004/07/16 23:32:03 vlad_r Exp $
8  */
9 package com.vladium.emma;
10 
11 import java.io.File;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.Properties;
16 import java.util.WeakHashMap;
17 
18 import com.vladium.util.ClassLoaderResolver;
19 import com.vladium.util.IProperties;
20 import com.vladium.util.Property;
21 import com.vladium.emma.report.IReportProperties;
22 import com.vladium.emma.report.ReportProperties;
23 
24 // ----------------------------------------------------------------------------
25 /**
26  * A reflection of "${IAppConstants.APP_PROPERTY_RES_NAME}.properties" resource
27  * as viewed by a given classloader.
28  *
29  * @author Vlad Roubtsov, (C) 2003
30  */
31 public
32 abstract class EMMAProperties
33 {
34     // public: ................................................................
35 
36     public static final String GENERIC_PROPERTY_OVERRIDE_PREFIX = "D";
37 
38     // [the DEFAULT_xxx settings duplicate the defaults in APP_DEFAULT_PROPERTIES_RES_NAME
39     // resource to provide a safe fallback option if that resource cannot be loaded]
40 
41     public static final String DEFAULT_META_DATA_OUT_FILE       = "coverage.em";
42     public static final Boolean DEFAULT_META_DATA_OUT_MERGE     = Boolean.TRUE;
43     public static final String PREFIX_META_DATA                 = "metadata.";
44     public static final String PROPERTY_META_DATA_OUT_FILE      = PREFIX_META_DATA + "out.file";
45     public static final String PROPERTY_META_DATA_OUT_MERGE     = PREFIX_META_DATA + "out.merge";
46 
47     public static final String DEFAULT_COVERAGE_DATA_OUT_FILE   = "coverage.ec";
48     public static final Boolean DEFAULT_COVERAGE_DATA_OUT_MERGE = Boolean.TRUE;
49     public static final String PREFIX_COVERAGE_DATA             = "coverage.";
50     public static final String PROPERTY_COVERAGE_DATA_OUT_FILE  = PREFIX_COVERAGE_DATA + "out.file";
51     public static final String PROPERTY_COVERAGE_DATA_OUT_MERGE = PREFIX_COVERAGE_DATA + "out.merge";
52 
53     public static final String DEFAULT_SESSION_DATA_OUT_FILE    = "coverage.es";
54     public static final Boolean DEFAULT_SESSION_DATA_OUT_MERGE  = Boolean.TRUE;
55     public static final String PREFIX_SESSION_DATA              = "session.";
56     public static final String PROPERTY_SESSION_DATA_OUT_FILE   = PREFIX_SESSION_DATA + "out.file";
57     public static final String PROPERTY_SESSION_DATA_OUT_MERGE  = PREFIX_SESSION_DATA + "out.merge";
58 
59     public static final String PROPERTY_TEMP_FILE_EXT           = ".et";
60 
61     public static final Map SYSTEM_PROPERTY_REDIRECTS; // set in <clinit>
62 
63 
64     /**
65      * Global method used to create an appearance that all app work has been
66      * done at the same point in time (useful for setting archive and report
67      * timestamps etc).
68      *
69      * @return the result of System.currentTimeMillis (), evaluated on the
70      * first call only
71      */
getTimeStamp()72     public static synchronized long getTimeStamp ()
73     {
74         long result = s_timestamp;
75         if (result == 0)
76         {
77             s_timestamp = result = System.currentTimeMillis ();
78         }
79 
80         return result;
81     }
82 
83 
makeAppVersion(final int major, final int minor, final int build)84     public static String makeAppVersion (final int major, final int minor, final int build)
85     {
86         final StringBuffer buf = new StringBuffer ();
87 
88         buf.append (major);
89         buf.append ('.');
90         buf.append (minor);
91         buf.append ('.');
92         buf.append (build);
93 
94         return buf.toString ();
95     }
96 
97 
98     /**
99      * Wraps a Properties into a IProperties with the app's standard property
100      * mapping in place.
101      *
102      * @param properties [null results in null result]
103      */
wrap(final Properties properties)104     public static IProperties wrap (final Properties properties)
105     {
106         if (properties == null) return null;
107 
108         return IProperties.Factory.wrap (properties, ReportProperties.REPORT_PROPERTY_MAPPER);
109     }
110 
111     /**
112      * Retrieves application properties as classloader resource with a given name.
113      * [as seen from ClassLoaderResolver.getClassLoader ()]. The result is cached
114      * using this loader as a weak key.
115      *
116      * @return properties [can be null]
117      */
getAppProperties()118     public static synchronized IProperties getAppProperties ()
119     {
120         final ClassLoader loader = ClassLoaderResolver.getClassLoader ();
121 
122         return getAppProperties (loader);
123     }
124 
getAppProperties(final ClassLoader loader)125     public static synchronized IProperties getAppProperties (final ClassLoader loader)
126     {
127         IProperties properties = (IProperties) s_properties.get (loader);
128 
129         if (properties != null)
130             return properties;
131         else
132         {
133             final String appName = IAppConstants.APP_NAME_LC;
134 
135             // note: this does not use Property.getAppProperties() by design,
136             // because that mechanism is not property alias-capable
137 
138             final IProperties systemRedirects = wrap (Property.getSystemPropertyRedirects (EMMAProperties.SYSTEM_PROPERTY_REDIRECTS));
139             final IProperties appDefaults = wrap (Property.getProperties (appName + "_default.properties", loader));
140             final IProperties systemFile;
141             {
142                 final String fileName = Property.getSystemProperty (appName + ".properties");
143                 final File file = fileName != null
144                     ? new File (fileName)
145                     : null;
146 
147                 systemFile = wrap (Property.getLazyPropertiesFromFile (file));
148             }
149             final IProperties system = wrap (Property.getSystemProperties (appName));
150             final IProperties userOverrides = wrap (Property.getProperties (appName + ".properties", loader));
151 
152             // "vertical" inheritance order:
153             //      (1) user overrides ("emma.properties" classloader resource)
154             //      (2) system properties (java.lang.System.getProperties(),
155             //                             filtered by the app prefix)
156             //      (3) system file properties ("emma.properties" system property,
157             //                                  interpreted as a property file)
158             //      (4) app defaults ("emma_default.properties" classloader resource)
159             //      (5) system property redirects (report.out.encoding->file.encoding,
160             //                                     report.out.dir->user.dir, etc)
161 
162             properties = IProperties.Factory.combine (userOverrides,
163                          IProperties.Factory.combine (system,
164                          IProperties.Factory.combine (systemFile,
165                          IProperties.Factory.combine (appDefaults,
166                                                       systemRedirects))));
167 
168             s_properties.put (loader, properties);
169 
170             return properties;
171         }
172     }
173 
174     // protected: .............................................................
175 
176     // package: ...............................................................
177 
178     // private: ...............................................................
179 
180 
EMMAProperties()181     private EMMAProperties () {} // prevent subclassing
182 
183 
184     private static long s_timestamp;
185 
186     private static final Map /* ClassLoader->Properties */ s_properties; // set in <clinit>
187 
188     static
189     {
190         s_properties = new WeakHashMap ();
191 
192         final Map redirects = new HashMap ();
IReportProperties.PREFIX.concat(IReportProperties.OUT_ENCODING)193         redirects.put (IReportProperties.PREFIX.concat (IReportProperties.OUT_ENCODING),
194                        "file.encoding");
IReportProperties.PREFIX.concat(IReportProperties.OUT_DIR)195         redirects.put (IReportProperties.PREFIX.concat (IReportProperties.OUT_DIR),
196                        "user.dir");
197 
198         SYSTEM_PROPERTY_REDIRECTS = Collections.unmodifiableMap (redirects);
199     }
200 
201 } // end of class
202 // ----------------------------------------------------------------------------
203