
com.alibaba.dubbo.common.utils.ConfigUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dubbo2 Show documentation
Show all versions of dubbo2 Show documentation
The all in one project of dubbo2
The newest version!
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.common.utils;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
/**
* @author ding.lid
* @author william.liangf
*/
public class ConfigUtils {
private static final Logger logger = LoggerFactory.getLogger(ConfigUtils.class);
public static boolean isNotEmpty(String value) {
return ! isEmpty(value);
}
public static boolean isEmpty(String value) {
return value == null || value.length() == 0
|| "false".equalsIgnoreCase(value)
|| "0".equalsIgnoreCase(value)
|| "null".equalsIgnoreCase(value)
|| "N/A".equalsIgnoreCase(value);
}
public static boolean isDefault(String value) {
return "true".equalsIgnoreCase(value)
|| "default".equalsIgnoreCase(value);
}
/**
* 扩展点列表中插入缺省扩展点。
*
* 扩展点列表支持
* - 特殊值
default
,表示缺省扩展点插入的位置
* - 特殊符号
-
,表示剔除。 -foo1
,剔除添加缺省扩展点foo1。-default
,剔除添加所有缺省扩展点。
*
*
* @param type 扩展点类型
* @param cfg 扩展点名列表
* @param def 缺省的扩展点的列表
* @return 完成缺省的扩展点列表插入后的列表
*/
public static List mergeValues(Class type, String cfg, List def) {
List defaults = new ArrayList();
if (def != null) {
for (String name : def) {
if (ExtensionLoader.getExtensionLoader(type).hasExtension(name)) {
defaults.add(name);
}
}
}
List names = new ArrayList();
// 加入初始值
String[] configs = (cfg == null || cfg.trim().length() == 0) ? new String[0] : Constants.COMMA_SPLIT_PATTERN.split(cfg);
for (String config : configs) {
if(config != null && config.trim().length() > 0) {
names.add(config);
}
}
// 不包含 -default
if (! names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
// 加入 插入缺省扩展点
int i = names.indexOf(Constants.DEFAULT_KEY);
if (i > 0) {
names.addAll(i, defaults);
} else {
names.addAll(0, defaults);
}
names.remove(Constants.DEFAULT_KEY);
}
else {
names.remove(Constants.DEFAULT_KEY);
}
// 合并-的配置项
for (String name : new ArrayList(names)) {
if (name.startsWith(Constants.REMOVE_VALUE_PREFIX)) {
names.remove(name);
names.remove(name.substring(1));
}
}
return names;
}
private static Pattern VARIABLE_PATTERN = Pattern.compile(
"\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?");
public static String replaceProperty(String expression, Map params) {
if (expression == null || expression.length() == 0 || expression.indexOf('$') < 0) {
return expression;
}
Matcher matcher = VARIABLE_PATTERN.matcher(expression);
StringBuffer sb = new StringBuffer();
while (matcher.find()) { // 逐个匹配
String key = matcher.group(1);
String value = System.getProperty(key);
if (value == null && params != null) {
value = params.get(key);
}
if (value == null) {
value = "";
}
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
}
matcher.appendTail(sb);
return sb.toString();
}
private static volatile Properties PROPERTIES;
public static Properties getProperties() {
if (PROPERTIES == null) {
synchronized (ConfigUtils.class) {
if (PROPERTIES == null) {
String path = System.getProperty(Constants.DUBBO_PROPERTIES_KEY);
if (path == null || path.length() == 0) {
path = System.getenv(Constants.DUBBO_PROPERTIES_KEY);
if (path == null || path.length() == 0) {
path = Constants.DEFAULT_DUBBO_PROPERTIES;
}
}
PROPERTIES = ConfigUtils.loadProperties(path, false, true);
}
}
}
return PROPERTIES;
}
public static void addProperties(Properties properties) {
if (properties != null) {
getProperties().putAll(properties);
}
}
public static void setProperties(Properties properties) {
if (properties != null) {
PROPERTIES = properties;
}
}
public static String getProperty(String key) {
return getProperty(key, null);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static String getProperty(String key, String defaultValue) {
String value = System.getProperty(key);
if (value != null && value.length() > 0) {
return value;
}
Properties properties = getProperties();
return replaceProperty(properties.getProperty(key, defaultValue), (Map)properties);
}
public static Properties loadProperties(String fileName) {
return loadProperties(fileName, false, false);
}
public static Properties loadProperties(String fileName, boolean allowMultiFile) {
return loadProperties(fileName, allowMultiFile, false);
}
/**
* Load properties file to {@link Properties} from class path.
*
* @param fileName properties file name. for example: dubbo.properties
, METE-INF/conf/foo.properties
* @param allowMultiFile if false
, throw {@link IllegalStateException} when found multi file on the class path.
* @param optional is optional. if false
, log warn when properties config file not found!s
* @return loaded {@link Properties} content.
* - return empty Properties if no file found.
*
- merge multi properties file if found multi file
*
* @throws IllegalStateException not allow multi-file, but multi-file exsit on class path.
*/
public static Properties loadProperties(String fileName, boolean allowMultiFile, boolean optional) {
Properties properties = new Properties();
if (fileName.startsWith("/")) {
try {
FileInputStream input = new FileInputStream(fileName);
try {
properties.load(input);
} finally {
input.close();
}
} catch (Throwable e) {
logger.warn("Failed to load " + fileName + " file from " + fileName + "(ingore this file): " + e.getMessage(), e);
}
return properties;
}
List list = new ArrayList();
try {
Enumeration urls = ClassHelper.getClassLoader().getResources(fileName);
list = new ArrayList();
while (urls.hasMoreElements()) {
list.add(urls.nextElement());
}
} catch (Throwable t) {
logger.warn("Fail to load " + fileName + " file: " + t.getMessage(), t);
}
if(list.size() == 0) {
if (! optional) {
logger.warn("No " + fileName + " found on the class path.");
}
return properties;
}
if(! allowMultiFile) {
if (list.size() > 1) {
String errMsg = String.format("only 1 %s file is expected, but %d dubbo.properties files found on class path: %s",
fileName, list.size(), list.toString());
logger.warn(errMsg);
// throw new IllegalStateException(errMsg); // see http://code.alibabatech.com/jira/browse/DUBBO-133
}
// fall back to use method getResourceAsStream
try {
properties.load(ClassHelper.getClassLoader().getResourceAsStream(fileName));
} catch (Throwable e) {
logger.warn("Failed to load " + fileName + " file from " + fileName + "(ingore this file): " + e.getMessage(), e);
}
return properties;
}
logger.info("load " + fileName + " properties file from " + list);
for(java.net.URL url : list) {
try {
Properties p = new Properties();
InputStream input = url.openStream();
if (input != null) {
try {
p.load(input);
properties.putAll(p);
} finally {
try {
input.close();
} catch (Throwable t) {}
}
}
} catch (Throwable e) {
logger.warn("Fail to load " + fileName + " file from " + url + "(ingore this file): " + e.getMessage(), e);
}
}
return properties;
}
private static int PID = -1;
public static int getPid() {
if (PID < 0) {
try {
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
String name = runtime.getName(); // format: "pid@hostname"
PID = Integer.parseInt(name.substring(0, name.indexOf('@')));
} catch (Throwable e) {
PID = 0;
}
}
return PID;
}
private ConfigUtils() {}
}