001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.api.config; 021 022 import com.google.common.collect.Lists; 023 import com.google.common.collect.Maps; 024 import org.apache.commons.lang.ArrayUtils; 025 import org.apache.commons.lang.StringUtils; 026 import org.sonar.api.BatchComponent; 027 import org.sonar.api.ServerComponent; 028 import org.sonar.api.utils.DateUtils; 029 030 import java.util.*; 031 032 /** 033 * Project Settings on batch side, Global Settings on server side. 034 * <p/> 035 * Replace the deprecated component org.apache.commons.configuration.Configuration 036 * 037 * @since 2.12 038 */ 039 public class Settings implements BatchComponent, ServerComponent { 040 041 protected Map<String, String> properties = Maps.newHashMap(); 042 protected PropertyDefinitions definitions; 043 044 public Settings() { 045 this(new PropertyDefinitions()); 046 } 047 048 public Settings(PropertyDefinitions definitions) { 049 this.definitions = definitions; 050 } 051 052 public final String getDefaultValue(String key) { 053 return definitions.getDefaultValue(key); 054 } 055 056 public final boolean hasKey(String key) { 057 return properties.containsKey(key); 058 } 059 060 public final boolean hasDefaultValue(String key) { 061 return StringUtils.isNotEmpty(getDefaultValue(key)); 062 } 063 064 public final String getString(String key) { 065 String value = properties.get(key); 066 if (value == null) { 067 value = getDefaultValue(key); 068 } 069 return value; 070 } 071 072 public final boolean getBoolean(String key) { 073 String value = getString(key); 074 return StringUtils.isNotEmpty(value) && Boolean.parseBoolean(value); 075 } 076 077 public final int getInt(String key) { 078 String value = getString(key); 079 if (StringUtils.isNotEmpty(value)) { 080 return Integer.parseInt(value); 081 } 082 return 0; 083 } 084 085 public final long getLong(String key) { 086 String value = getString(key); 087 if (StringUtils.isNotEmpty(value)) { 088 return Long.parseLong(value); 089 } 090 return 0L; 091 } 092 093 public final Date getDate(String key) { 094 String value = getString(key); 095 if (StringUtils.isNotEmpty(value)) { 096 return DateUtils.parseDate(value); 097 } 098 return null; 099 } 100 101 public final Date getDateTime(String key) { 102 String value = getString(key); 103 if (StringUtils.isNotEmpty(value)) { 104 return DateUtils.parseDateTime(value); 105 } 106 return null; 107 } 108 109 /** 110 * Value is splitted by comma and trimmed. 111 * <p/> 112 * Examples : 113 * <ul> 114 * <li>"one,two,three " -> ["one", "two", "three"]</li> 115 * <li>" one, two, three " -> ["one", "two", "three"]</li> 116 * <li>"one, , three" -> ["one", "", "three"]</li> 117 * </ul> 118 */ 119 public final String[] getStringArray(String key) { 120 return getStringArrayBySeparator(key, ","); 121 } 122 123 /** 124 * Value is splitted and trimmed. 125 */ 126 public final String[] getStringArrayBySeparator(String key, String separator) { 127 String value = getString(key); 128 if (value != null) { 129 String[] strings = StringUtils.splitByWholeSeparator(value, separator); 130 String[] result = new String[strings.length]; 131 for (int index = 0; index < strings.length; index++) { 132 result[index] = StringUtils.trim(strings[index]); 133 } 134 return result; 135 } 136 return ArrayUtils.EMPTY_STRING_ARRAY; 137 } 138 139 public List<String> getKeysStartingWith(String prefix) { 140 List<String> result = Lists.newArrayList(); 141 for (String key : properties.keySet()) { 142 if (StringUtils.startsWith(key, prefix)) { 143 result.add(key); 144 } 145 } 146 return result; 147 } 148 149 public final Settings appendProperty(String key, String value) { 150 String newValue = properties.get(key); 151 if (StringUtils.isEmpty(newValue)) { 152 newValue = value; 153 } else { 154 newValue += "," + value; 155 } 156 properties.put(key, newValue); 157 return this; 158 } 159 160 public final Settings setProperty(String key, String value) { 161 if (!clearIfNullValue(key, value)) { 162 properties.put(key, value); 163 } 164 return this; 165 } 166 167 public final Settings setProperty(String key, Boolean value) { 168 if (!clearIfNullValue(key, value)) { 169 properties.put(key, String.valueOf(value)); 170 } 171 return this; 172 } 173 174 public final Settings setProperty(String key, Integer value) { 175 if (!clearIfNullValue(key, value)) { 176 properties.put(key, String.valueOf(value)); 177 } 178 return this; 179 } 180 181 public final Settings setProperty(String key, Long value) { 182 if (!clearIfNullValue(key, value)) { 183 properties.put(key, String.valueOf(value)); 184 } 185 return this; 186 } 187 188 public final Settings setProperty(String key, Double value) { 189 if (!clearIfNullValue(key, value)) { 190 properties.put(key, String.valueOf(value)); 191 } 192 return this; 193 } 194 195 public final Settings setProperty(String key, Date date) { 196 return setProperty(key, date, false); 197 } 198 199 public final Settings addProperties(Map<String, String> props) { 200 properties.putAll(props); 201 return this; 202 } 203 204 public final Settings addProperties(Properties props) { 205 for (Map.Entry<Object, Object> entry : props.entrySet()) { 206 properties.put(entry.getKey().toString(), entry.getValue().toString()); 207 } 208 return this; 209 } 210 211 public final Settings addSystemProperties() { 212 return addProperties(System.getProperties()); 213 } 214 215 public final Settings addEnvironmentVariables() { 216 return addProperties(System.getenv()); 217 } 218 219 public final Settings setProperties(Map<String, String> props) { 220 properties = Maps.newHashMap(props); 221 return this; 222 } 223 224 public final Settings setProperty(String key, Date date, boolean includeTime) { 225 if (!clearIfNullValue(key, date)) { 226 properties.put(key, includeTime ? DateUtils.formatDateTime(date) : DateUtils.formatDate(date)); 227 } 228 return this; 229 } 230 231 public final Settings removeProperty(String key) { 232 properties.remove(key); 233 return this; 234 } 235 236 public final Settings clear() { 237 properties.clear(); 238 return this; 239 } 240 241 /** 242 * @return unmodifiable properties 243 */ 244 public final Map<String, String> getProperties() { 245 return Collections.unmodifiableMap(properties); 246 } 247 248 public final PropertyDefinitions getDefinitions() { 249 return definitions; 250 } 251 252 private boolean clearIfNullValue(String key, Object value) { 253 if (value == null) { 254 properties.remove(key); 255 return true; 256 } 257 return false; 258 } 259 260 /** 261 * Create empty settings. Definition of available properties is loaded from the given annotated class. 262 * This method is usually used by unit tests. 263 */ 264 public static Settings createForComponent(Object component) { 265 return new Settings(new PropertyDefinitions(component)); 266 } 267 }