001/** 002 * @Title: Configuratoin.java 003 * @Package net.gdface.utils 004 * @Description: 管ç†properties文件 005 * @author guyadong 006 * @date 2014-10-14 下åˆ3:20:09 007 * @version V1.0 008 */ 009package net.gdface.utils; 010 011import java.io.File; 012import java.io.IOException; 013import java.io.InputStream; 014import java.lang.reflect.InvocationTargetException; 015import java.net.URL; 016import java.util.Properties; 017import java.util.Map.Entry; 018 019/**读å–é…置文件(properties)ä¸çš„傿•° 020 * @author guyadong 021 * 022 */ 023public class Configuration extends Properties{ 024 private static final long serialVersionUID = -3929851625670931787L; 025 /** 026 * property 属性åå‰ç¼€,在调用{@link #getProperty(String)}或其他getPropertyæ–¹æ³•æ—¶å‚æ•°ä¼šè‡ªåŠ¨åŠ ä¸Šè¯¥å‰ç¼€,默认为"", 027 * 如prefix为 net.gdface.facedbsdk.FaceDbSDKLocal 028 * 调用getProperty("minThread")时,其实是执行getProperty("net.gdface.facedbsdk.FaceDbSDKLocal.minThread") 029 */ 030 private ThreadLocal<String> prefixs = new ThreadLocal<String>() { 031 @Override 032 protected String initialValue() { 033 return "";//prefixåˆå§‹å€¼ä¸º"" 034 } 035 }; 036 037 /**使用指定的ClassLoaderåŠ è½½properties文件propFile 038 * @param classLoader 039 * @param propFile 040 * @throws IOException 041 * @see #configure(URL) 042 */ 043 public Configuration(ClassLoader classLoader,String propFile) throws IOException { 044 URL url= classLoader.getResource(propFile); 045 if(null==url) 046 throw new IOException(String.format("Cant found resource [%s] by %s",propFile,classLoader.getClass().getName())); 047 configure(url); 048 } 049 /** 050 * 从{@link File}æž„é€ å¯¹è±¡ 051 * @param propFile 052 * @throws IOException 053 */ 054 public Configuration(File propFile) throws IOException { 055 this(propFile.toURI().toURL()); 056 } 057 public Configuration() { 058 super(); 059 } 060 public Configuration(Properties defaults) { 061 super(defaults); 062 } 063 /** 064 * @param url 065 * @throws IOException 066 */ 067 public Configuration(URL url) throws IOException { 068 configure(url); 069 } 070 /** 071 * æ ¹æ®{@link URL}åŠ è½½é…置文件 072 * @param url 073 * @throws IOException 074 * @see #configure(InputStream) 075 */ 076 private void configure(URL url) throws IOException { 077 if(null==url) 078 throw new NullPointerException("parameter [url] is null"); 079 System.out.printf("Load properties from [%s]\n", url.toString()); 080 InputStream is = url.openStream(); 081 try { 082 load(is); 083 } finally { 084 is.close(); 085 } 086 } 087 088 /** 089 * è¯»å–æŒ‡å®šçš„keyï¼Œç”¨é™æ€valueOf方法(如果有)å°†ä¹‹è½¬æ¢æˆclazz指定的类型<br> 090 * 适用于{@link Number},{@link Boolean}类型,如果keyä¸å˜åœ¨æˆ–为空或转æ¢å‡ºé”™åˆ™è¿”回null 091 * 092 * @param key 093 * @param clazz 094 * @return 095 */ 096 @SuppressWarnings("unchecked") 097 private <T> T _getPropertyBaseType(String key, Class<T> clazz) { 098 if (null == key||0==key.length()) 099 throw new IllegalArgumentException("the argument 'key' must not be null or empty"); 100 if (null == clazz) 101 throw new IllegalArgumentException("the argument 'clazz' must not be null"); 102 String value = getProperty(key); 103 try { 104 return null == value|| 0 == value.length() ? null : (T) clazz.getMethod("valueOf", String.class).invoke(null, value.trim()); 105 } catch (NoSuchMethodException e) { 106 new RuntimeException( 107 String.format("%s:not found static method 'valueOf' for %s", e.getClass().getSimpleName(), 108 clazz.getName()), e); 109 } catch (IllegalAccessException e) { 110 new RuntimeException( 111 String.format("%s:can't invoke method 'valueOf' for %s", e.getClass().getSimpleName(), 112 clazz.getName()), e); 113 } catch (InvocationTargetException e) { 114 try { 115 throw e.getCause(); 116 } catch (NumberFormatException ie) { 117 System.out.printf("%s: [%s=%s] can't be convert to %s\n", e.getClass().getSimpleName(), key, value, 118 clazz.getName()); 119 } catch (Throwable ie) { 120 new RuntimeException(ie); 121 } 122 } 123 return null; 124 } 125 126 /** 127 * 设置指定的key为value 128 * 129 * @param key 130 * 为{@link null}时抛出 {@link IllegalArgumentException}<br> 131 * 适用于{@link Number},{@link Boolean}类型 132 * @param value 133 * 为{@code null}æ—¶åˆ é™¤key并返回{@code null} 134 * @return ç”¨é™æ€valueOf方法返回key原æ¥çš„值 135 */ 136 @SuppressWarnings("unchecked") 137 private <T> T _setPropertyBaseType(String key, T value) { 138 if (null == key||0==key.length()) 139 throw new IllegalArgumentException("the argument 'key' must not be null or empty"); 140 // value为nullæ—¶åˆ é™¤key,并返回null 141 if(null==value){remove(key);return null;} 142 try { 143 String old = (String) setProperty(key,value.toString()); 144 return null == old|| 0 == old.length() ? null : (T) value.getClass().getMethod("valueOf", String.class).invoke(null, old.trim()); 145 } catch (NoSuchMethodException e) { 146 new RuntimeException( 147 String.format("%s:not found static method 'valueOf' for %s", e.getClass().getSimpleName(), 148 value.getClass().getName()), e); 149 } catch (IllegalAccessException e) { 150 new RuntimeException( 151 String.format("%s:can't invoke method 'valueOf' for %s", e.getClass().getSimpleName(), 152 value.getClass().getName()), e); 153 } catch (InvocationTargetException e) { 154 try { 155 throw e.getCause(); 156 } catch (NumberFormatException ie) { 157 System.out.printf("%s: [%s=%s] can't be convert to %s\n", e.getClass().getSimpleName(), key, value.toString(), 158 value.getClass().getName()); 159 } catch (Throwable ie) { 160 new RuntimeException(ie); 161 } 162 } 163 return null; 164 } 165 166 @Override 167 public String getProperty(String key) { 168 return super.getProperty(this.getPrefix()+key); 169 } 170 171 @Override 172 public String getProperty(String key, String defaultValue) { 173 return super.getProperty(key, defaultValue); 174 } 175 176 @Override 177 public synchronized Object setProperty(String key, String value) { 178 return super.setProperty(this.getPrefix()+key, value); 179 } 180 /**è¯»å–æŒ‡å®šçš„keyï¼Œå°†ä¹‹è½¬æ¢æˆä¸ŽdefaultValue类型相åŒçš„对象,如果keyä¸å˜åœ¨æˆ–转æ¢å‡ºé”™åˆ™è¿”回defaultValue 181 * @param key 182 * @param defaultValue 缺çœå€¼ 183 * @return 184 */ 185 public <T> T getPropertyBaseType(String key, T defaultValue) { 186 if (null == defaultValue) 187 throw new IllegalArgumentException("the argument 'defaultValue' must not be null"); 188 @SuppressWarnings("unchecked") 189 T res = (T) _getPropertyBaseType(key,defaultValue.getClass()); 190 return ((null==res)?defaultValue:res); 191 } 192 193 public Boolean getPropertyBoolean(String key) { 194 return _getPropertyBaseType(key, Boolean.class); 195 } 196 197 public Boolean getPropertyBoolean(String key, Boolean defaultValue) { 198 return getPropertyBaseType(key, defaultValue); 199 } 200 201 public Byte getPropertyByte(String key) { 202 return _getPropertyBaseType(key, Byte.class); 203 } 204 public Byte getPropertyByte(String key,Byte defaultValue) { 205 return getPropertyBaseType(key, defaultValue); 206 } 207 public Double getPropertyDouble(String key) { 208 return _getPropertyBaseType(key, Double.class); 209 } 210 211 public Double getPropertyDouble(String key,Double defaultValue) { 212 return getPropertyBaseType(key, defaultValue); 213 } 214 215 public Float getPropertyFloat(String key) { 216 return _getPropertyBaseType(key, Float.class); 217 } 218 219 public Float getPropertyFloat(String key,Float defaultValue) { 220 return getPropertyBaseType(key, defaultValue); 221 } 222 223 public Integer getPropertyInteger(String key) { 224 return _getPropertyBaseType(key, Integer.class); 225 } 226 227 public Integer getPropertyInteger(String key,Integer defaultValue) { 228 return getPropertyBaseType(key, defaultValue); 229 } 230 231 public Long getPropertyLong(String key) { 232 return _getPropertyBaseType(key, Long.class); 233 } 234 public Long getPropertyLong(String key,Long defaultValue) { 235 return getPropertyBaseType(key, defaultValue); 236 } 237 public Short getPropertyShort(String key) { 238 return _getPropertyBaseType(key, Short.class); 239 } 240 public Short getPropertyShort(String key,Short defaultValue) { 241 return getPropertyBaseType(key, defaultValue); 242 } 243 ////////////// 244 245 public Boolean setPropertyBoolean(String key, Boolean value) { 246 return _setPropertyBaseType(key, value); 247 } 248 249 public Byte setPropertyByte(String key,Byte value) { 250 return _setPropertyBaseType(key, value); 251 } 252 253 public Double setPropertyDouble(String key,Double value) { 254 return _setPropertyBaseType(key, value); 255 } 256 257 public Float setPropertyFloat(String key,Float value) { 258 return _setPropertyBaseType(key, value); 259 } 260 261 public Integer setPropertyInteger(String key,Integer value) { 262 return _setPropertyBaseType(key, value); 263 } 264 265 public Long setPropertyLong(String key,Long value) { 266 return _setPropertyBaseType(key, value); 267 } 268 public Short setPropertyShort(String key,Short value) { 269 return _setPropertyBaseType(key, value); 270 } 271 272 public void setPropertyBooleanIfAbsent(String key, Boolean value) { 273 if(!containsKey(key)){ 274 setPropertyBoolean(key, value); 275 } 276 } 277 278 public void setPropertyIfAbsent(String key, String value) { 279 if(!containsKey(key)){ 280 setProperty(key, value); 281 } 282 } 283 284 public void setPropertyByteIfAbsent(String key,Byte value) { 285 if(!containsKey(key)){ 286 setPropertyByte(key, value); 287 } 288 } 289 290 public void setPropertyDoubleIfAbsent(String key,Double value) { 291 if(!containsKey(key)){ 292 setPropertyDouble(key, value); 293 } 294 } 295 296 public void setPropertyFloatIfAbsent(String key,Float value) { 297 if(!containsKey(key)){ 298 setPropertyFloat(key, value); 299 } 300 } 301 302 public void setPropertyIntegerIfAbsent(String key,Integer value) { 303 if(!containsKey(key)){ 304 setPropertyInteger(key, value); 305 } 306 } 307 308 public void setPropertyLongIfAbsent(String key,Long value) { 309 if(!containsKey(key)){ 310 setPropertyLong(key, value); 311 } 312 } 313 314 public void setPropertyShortIfAbsent(String key,Short value) { 315 if(!containsKey(key)){ 316 setPropertyShort(key, value); 317 } 318 } 319 /**å¦‚æžœå‚æ•°ä¸ºnull,则prefix设置为"" 320 * @param prefix è¦è®¾ç½®çš„ prefix 321 * @return 322 */ 323 public Configuration setPrefix(String prefix) { 324 prefixs.set(null==prefix?"":prefix); 325 return this; 326 } 327 /** 328 * 设置 {@link #prefixs}空 329 * @return 330 */ 331 public Configuration resetPrefix() { 332 return setPrefix(null); 333 } 334 /** 335 * @return prefix 336 */ 337 public String getPrefix() { 338 return prefixs.get(); 339 } 340 /** 341 * 返回如果指定了 {@link java.util.Properties#defaults},åˆ™è¿”å›žæ‰€æœ‰ç›¸å¯¹å¢žåŠ æˆ–ä¿®æ”¹çš„å€¼<br> 342 * å¦åˆ™è¿”回所有值 343 * @param out 输出对象,å¯ä¸ºnull 344 * @return 345 */ 346 public Properties changedProperties(Properties out){ 347 if(null==out)out=new Properties(); 348 if(null==defaults) 349 out.putAll(this); 350 else 351 for(Entry<Object, Object> entry:entrySet()){ 352 String key=(String) entry.getKey(); 353 String value=(String)entry.getValue(); 354 if(!defaults.containsKey(key)||!value.equals(defaults.getProperty(key))){ 355 out.setProperty(key, value); 356 } 357 } 358 return out; 359 } 360}