001package net.gdface.utils; 002 003import java.io.File; 004import java.io.FileWriter; 005import java.io.IOException; 006import java.io.InputStream; 007import java.io.InputStreamReader; 008import java.net.URL; 009import java.util.HashSet; 010import java.util.Properties; 011import java.util.Set; 012 013/** 014 * é…置文件读å–工具类 015 * @author guyadong 016 * 017 */ 018public class ConfigUtils { 019 private static final String JAR_SUFFIX = ".jar"; 020 021 /** 022 * 顺åºåŠ è½½ä¸åŒä½ç½®çš„properties文件,åŠ è½½é¡ºåºä¸º:<br> 023 * 1.调用{@link ClassLoader#getResource(String)}方法在{@code clazz}所在ä½ç½®æŸ¥æ‰¾,如果失败则抛出异常<br> 024 * 2.如果class在jar包ä¸,则å°è¯•读å–在jar所在ä½ç½®../confFolder/propFile,tomcat下å³ä¸ºWEB-INF/confFolder/propFile<br> 025 * 3.如果环境å˜é‡envVar定义,则从envVar指定的目录下读å–propFile<br> 026 * 4.user.dir下查找confFolder/propFileåŠ è½½é…ç½®<br> 027 * åŽé¢çš„é…ç½®å˜é‡ä¼šè¦†ç›–å‰é¢çš„定义<br> 028 * @param propFile è¦åŠ è½½çš„properties文件å,为{@code null}或空时抛出异常 {@link IllegalArgumentException} 029 * @param confFolder popFile所在文件夹,{@code null}时使用默认值'conf' 030 * @param envVar 环境å˜é‡å 用于定义propFileä½ç½®,å¯ä¸º{@code null} 031 * @param clazz ç”¨äºŽèŽ·å– {@link ClassLoader}的类,为null时使用本类的class 032 * @param showProp åŠ è½½åŽæ˜¯å¦æ˜¾ç¤ºæ‰€æœ‰å€¼ 033 * @return è¿”å›žåŠ è½½åŽçš„{@link Properties}对象 034 */ 035 public static Properties loadAllProperties(String propFile, String confFolder, String envVar, Class<?> clazz, boolean showProp) { 036 if(null==propFile||propFile.isEmpty()){ 037 throw new IllegalArgumentException("the argument 'propFile' must not be null or empty"); 038 } 039 if (null == confFolder){ 040 confFolder = "conf"; 041 } 042 if (null == clazz){ 043 clazz = ConfigUtils.class; 044 } 045 final String fileSeparator = System.getProperty("file.separator"); 046 String propPath = confFolder.concat(System.getProperty("file.separator")).concat(propFile); 047 Properties props = new Properties(); 048 Set<File> loadedFiles = new HashSet<File>(); 049 try { 050 // 在jaråŒ…ä¸æŸ¥æ‰¾é»˜è®¤é…置文件 051 URL url = clazz.getClassLoader().getResource(propPath.replace(fileSeparator, "/")); 052 if(null==url){ 053 throw new ExceptionInInitializerError(String.format("not found default properties %s", propPath)); 054 } 055 loadProperties(url, props); 056 } catch (Exception e) { 057 // 默认é…ç½®å¿…é¡»åŠ è½½æˆåŠŸå¦åˆ™æŠ›å‡ºå¼‚常 058 throw new ExceptionInInitializerError(String.format("fail to load default properties(åŠ è½½é»˜è®¤é…置文件失败) %s cause by %s", propPath, 059 e.getMessage())); 060 } 061 try { 062 // åŠ è½½ jar包所在ä½ç½® ../conf/cassdk.properties 063 URL classLocation = clazz.getProtectionDomain().getCodeSource().getLocation(); 064 if (classLocation.toString().endsWith(JAR_SUFFIX)) { 065 // jar包所在目录的父目录,tomcat下å³ä¸ºWEB-INF 066 File jarParent = new File(classLocation.getPath()).getParentFile().getParentFile(); 067 if (null != jarParent) { 068 File confFile = new File(jarParent, propPath); 069 if (confFile.isFile()) { 070 loadProperties(confFile.toURI().toURL(), props); 071 loadedFiles.add(confFile); 072 } 073 } 074 } 075 } catch (Exception e) { 076 } 077 try { 078 // 通过环境å˜é‡æŸ¥æ‰¾properties文件 079 if (envVar != null && !envVar.isEmpty()) { 080 String cf = System.getProperty(envVar); 081 if (null != cf&&!cf.isEmpty()) { 082 File envFile = new File(cf, propFile); 083 if (!loadedFiles.contains(envFile)) { 084 loadProperties(envFile.toURI().toURL(), props); 085 loadedFiles.add(envFile); 086 } 087 } else{ 088 log("not defined environment variable '%s'", envVar); 089 } 090 } 091 } catch (Exception e) { 092 } 093 try { 094 // 在当å‰è·¯å¾„下查找é…置文件 095 File propInUserDir = new File(System.getProperty("user.dir"), propPath); 096 if (propInUserDir.isFile() && !loadedFiles.contains(propInUserDir)) { 097 loadProperties(propInUserDir.toURI().toURL(), props); 098 loadedFiles.add(propInUserDir); 099 } 100 } catch (Exception e) { 101 } 102 103 // è¾“å‡ºæ‰€æœ‰å‚æ•°å€¼ 104 if(showProp){ 105 props.list(System.out); 106 } 107 return props; 108 } 109 110 /** 111 * 基于user.homeï¼ŒåŠ è½½ç›¸å¯¹è·¯å¾„propPath指定的properties文件 112 * @param propPath 113 * @return 114 */ 115 public static Properties loadPropertiesInUserHome(String propPath){ 116 Properties props = new Properties(); 117 try { 118 // 在user.home路径下查找é…置文件 119 File propInUserHome = new File(System.getProperty("user.home"), propPath); 120 if (propInUserHome.isFile() ) { 121 loadProperties(propInUserHome.toURI().toURL(), props); 122 } 123 } catch (Exception e) { 124 } 125 return props; 126 } 127 /** 128 * 基于user.home,ä¿å˜æŒ‡å®šçš„{@link Properties} 129 * @param properties 130 * @param propertiesFile properties文件å 131 * @throws IOException 132 * @see {@link Properties#store(java.io.Writer, String)} 133 * @see {@link System#getProperties()} 134 */ 135 public static void storePropertiesInUserHome(Properties properties,String propertiesFile) throws IOException{ 136 if(null==properties){ 137 throw new NullPointerException(); 138 } 139 if(null==propertiesFile||propertiesFile.isEmpty()){ 140 throw new IllegalArgumentException("propertiesFile must not be empty or null"); 141 } 142 File propInUserHome = new File(System.getProperty("user.home"), propertiesFile); 143 File parent=propInUserHome.getParentFile(); 144 if(!parent.exists()){ 145 parent.mkdirs(); 146 } 147 properties.store(new FileWriter(propInUserHome), null); 148 149 } 150 /** 151 * configure with the parameters given in the given url 152 * 153 * @param url 154 * the resource filename to be used 155 * @param props 156 * dest properties to add 157 * @throws IOException 158 */ 159 private static void loadProperties(URL url, Properties props) throws IOException { 160 if (null != url) { 161 InputStream is = null; 162 try { 163 props.load(new InputStreamReader(is = url.openStream(),"UTF-8")); 164 log("Load properties from %s", url.toString()); 165 } finally { 166 if (is != null){ 167 is.close(); 168 } 169 } 170 } 171 } 172 private static void log(String format, Object ... args){ 173 System.out.printf("[%s:%d]%s\n", 174 ConfigUtils.class.getSimpleName(), 175 Thread.currentThread() .getStackTrace()[2].getLineNumber(), 176 String.format(format, args)); 177 } 178}