1/* 2 * Copyright 2003-2009 OFFIS, Henri Tremblay 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.easymock.internal; 17 18import java.io.BufferedInputStream; 19import java.io.IOException; 20import java.io.InputStream; 21import java.util.Map; 22import java.util.Properties; 23 24/** 25 * Contains properties used by EasyMock to change its default behavior. The 26 * loading order is (any step being able to overload the properties of the 27 * previous step): 28 * <ul> 29 * <li>easymock.properties in classpath default package</li> 30 * <li>System properties</li> 31 * <li>explicit call to setProperty</li> 32 * </ul> 33 */ 34public final class EasyMockProperties { 35 36 private static final String PREFIX = "easymock."; 37 38 // volatile for double-checked locking 39 private static volatile EasyMockProperties instance; 40 41 private final Properties properties = new Properties(); 42 43 public static EasyMockProperties getInstance() { 44 if (instance == null) { 45 synchronized (EasyMockProperties.class) { 46 // ///CLOVER:OFF 47 if (instance == null) { 48 // ///CLOVER:ON 49 instance = new EasyMockProperties(); 50 } 51 } 52 } 53 return instance; 54 } 55 56 private EasyMockProperties() { 57 // Load the easymock.properties file 58 InputStream in = getClassLoader().getResourceAsStream( 59 "easymock.properties"); 60 if (in != null) { 61 in = new BufferedInputStream(in); 62 try { 63 properties.load(in); 64 } catch (IOException e) { 65 throw new RuntimeException( 66 "Failed to read easymock.properties file"); 67 } finally { 68 try { 69 in.close(); 70 } catch (IOException e) { 71 // Doesn't matter 72 } 73 } 74 } 75 // Then overload it with system properties 76 for (Map.Entry<Object, Object> entry : System.getProperties() 77 .entrySet()) { 78 if (entry.getKey() instanceof String 79 && entry.getKey().toString().startsWith(PREFIX)) { 80 properties.put(entry.getKey(), entry.getValue()); 81 } 82 } 83 } 84 85 /** 86 * Searches for the property with the specified key. If the key is not 87 * found, return the default value. 88 * 89 * @param key 90 * key leading to the property 91 * @param defaultValue 92 * the value to be returned if the key isn't found 93 * @return the value found for the key or the default value 94 */ 95 public String getProperty(String key, String defaultValue) { 96 return properties.getProperty(key, defaultValue); 97 } 98 99 /** 100 * Searches for the property with the specified key. Return null if the key 101 * is not found. 102 * 103 * @param key 104 * key leading to the property 105 * @return the value found for the key or null 106 */ 107 public String getProperty(String key) { 108 return properties.getProperty(key); 109 } 110 111 /** 112 * Add a value referenced by the provided key. A null value will remove the 113 * key 114 * 115 * @param key 116 * the key of the new property 117 * @param value 118 * the value corresponding to <tt>key</tt>. 119 * @return the property previous value 120 */ 121 public String setProperty(String key, String value) { 122 if (!key.startsWith(PREFIX)) { 123 throw new IllegalArgumentException("Invalid key (" + key 124 + "), an easymock property starts with \"" + PREFIX + "\""); 125 } 126 if (value == null) { 127 return (String) properties.remove(key); 128 } 129 return (String) properties.setProperty(key, value); 130 } 131 132 private ClassLoader getClassLoader() { 133 ClassLoader cl = null; 134 try { 135 cl = Thread.currentThread().getContextClassLoader(); 136 } catch (Throwable ex) { 137 // Cannot access thread context ClassLoader - falling back to system 138 // class loader 139 } 140 if (cl == null) { 141 // No thread context class loader -> use class loader of this class. 142 cl = getClass().getClassLoader(); 143 } 144 return cl; 145 } 146} 147