com.alipay.rdf.file.loader.ExtensionLoader Maven / Gradle / Ivy
package com.alipay.rdf.file.loader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import com.alipay.rdf.file.exception.RdfErrorEnum;
import com.alipay.rdf.file.exception.RdfFileException;
import com.alipay.rdf.file.util.RdfFileLogUtil;
import com.alipay.rdf.file.util.RdfFileUtil;
/**
* Copyright (C) 2013-2018 Ant Financial Services Group
*
* @author hongwei.quhw
* @version $Id: ExtensionLoader.java, v 0.1 2017年4月1日 上午10:26:46 hongwei.quhw Exp $
*/
@SuppressWarnings("unchecked")
public class ExtensionLoader {
private static final String RDF_SERVICE_DIR = "META-INF/rdf-file/services/";
private static final ConcurrentHashMap, ExtensionLoader>> EXTENSION_LOADERS = new ConcurrentHashMap, ExtensionLoader>>();
private final Object instanceLock = new Object();
private final Object clazzLock = new Object();
private final Class> type;
private ConcurrentHashMap cachedInstances = null;
private ConcurrentHashMap> cachedClasses = null;
private ConcurrentHashMap, List> cachedClass2Names = null;
private ExtensionLoader(Class> type) {
this.type = type;
}
public static ExtensionLoader getExtensionLoader(Class type) {
RdfFileUtil.assertNotNull(type, "rdf-file#getExtensionLoader(type=null)",
RdfErrorEnum.ILLEGAL_ARGUMENT);
ExtensionLoader loader = (ExtensionLoader) EXTENSION_LOADERS.get(type);
if (loader == null) {
loader = new ExtensionLoader(type);
EXTENSION_LOADERS.putIfAbsent(type, loader);
}
return loader;
}
public T getExtension(String name) {
return getExtensions().get(RdfFileUtil.assertTrimNotBlank(name, "Extension name == null"));
}
public T getNewExtension(String name) {
Class> clazz = getExtensionClasses().get(RdfFileUtil.assertTrimNotBlank(name,
"rdf-file#Extension name == null", RdfErrorEnum.ILLEGAL_ARGUMENT));
if (clazz == null) {
System.out.println(cachedClasses);
}
RdfFileUtil.assertNotNull(clazz,
"rdf-file#Extension type=" + type.getName() + ", name =" + name + ", class == null",
RdfErrorEnum.EXTENSION_ERROR);
try {
return (T) clazz.newInstance();
} catch (InstantiationException e) {
throw new RdfFileException(e, RdfErrorEnum.EXTENSION_ERROR);
} catch (IllegalAccessException e) {
throw new RdfFileException(e, RdfErrorEnum.EXTENSION_ERROR);
}
}
public Map getExtensions() {
if (null == cachedInstances) {
synchronized (instanceLock) {
if (null == cachedInstances) {
ConcurrentHashMap tempCachedInstances = new ConcurrentHashMap();
loadFile(tempCachedInstances);
cachedInstances = tempCachedInstances;
}
}
}
return cachedInstances;
}
public List getExtensionAlias(Class> clazz) {
getExtensionClasses();
return cachedClass2Names.get(clazz);
}
public Class getExtensionClass(String name) {
return (Class) getExtensionClasses().get(name);
}
public ConcurrentHashMap> getExtensionClasses() {
if (null == cachedClasses) {
synchronized (clazzLock) {
if (null == cachedClasses) {
ConcurrentHashMap> tempCachedClasses = new ConcurrentHashMap>();
cachedClass2Names = new ConcurrentHashMap, List>();
loadExtensionFile(tempCachedClasses);
cachedClasses = tempCachedClasses;
}
}
}
return cachedClasses;
}
private void loadFile(ConcurrentHashMap cachedInstances) {
ConcurrentHashMap> extensionClasses = getExtensionClasses();
for (Entry> entry : extensionClasses.entrySet()) {
try {
cachedInstances.put(entry.getKey(), (T) entry.getValue().newInstance());
} catch (InstantiationException e) {
throw new RdfFileException(e, RdfErrorEnum.EXTENSION_ERROR);
} catch (IllegalAccessException e) {
throw new RdfFileException(e, RdfErrorEnum.EXTENSION_ERROR);
}
}
}
private void loadExtensionFile(ConcurrentHashMap> cachedClasses) {
String fileName = RDF_SERVICE_DIR + type.getName();
try {
Enumeration urls = RdfFileUtil.getDefaultClassLoader().getResources(fileName);
if (null == urls) {
return;
}
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream(), "utf-8"));
try {
String line = null;
while ((line = reader.readLine()) != null) {
line = line.trim();
int idx = line.indexOf('=');
if (idx < 1) {
throw new RdfFileException("rdf-file#type=" + type.getName()
+ ",extension服务配置格式错误 url=" + url.toString(),
RdfErrorEnum.EXTENSION_ERROR);
}
String key = RdfFileUtil.assertTrimNotBlank(line.substring(0, idx));
line = RdfFileUtil.assertTrimNotBlank(line.substring(idx + 1));
if (line.length() > 0) {
Class> clazz = Class.forName(line, true,
RdfFileUtil.getDefaultClassLoader());
if (!type.isAssignableFrom(clazz)) {
throw new RdfFileException(
"rdf-file#type=" + type.getName() + ", class: [" + line
+ "] is not subtype of "
+ type.getName(),
RdfErrorEnum.EXTENSION_ERROR);
}
String[] aliases = key.split(",");
List aliasList = cachedClass2Names.get(clazz);
if (null == aliasList) {
aliasList = new ArrayList();
cachedClass2Names.put(clazz, aliasList);
}
for (String alias : aliases) {
alias = RdfFileUtil.assertTrimNotBlank(alias);
Class> old = cachedClasses.get(alias);
if (null != old) {
if (RdfFileLogUtil.common.isWarn()) {
RdfFileLogUtil.common
.warn("rdf-file#type=" + type.getName() + ",class=["
+ clazz.getName() + "],key=[" + alias
+ "] 重复定义了 url=" + url.getPath());
}
} else {
cachedClasses.putIfAbsent(alias, clazz);
aliasList.add(alias);
}
}
}
}
} finally {
if (null != reader) {
reader.close();
}
}
}
} catch (RdfFileException e) {
throw e;
} catch (Throwable e) {
throw new RdfFileException(
"rdf-file#type=" + type.getName() + ",ExtensionLoader " + fileName + " 扩展失败", e,
RdfErrorEnum.EXTENSION_ERROR);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy