All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.featherfly.hammer.tpl.TplConfigFactoryImpl Maven / Gradle / Ivy

There is a newer version: 0.7.2
Show newest version

package cn.featherfly.hammer.tpl;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.MetadataReader;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import cn.featherfly.common.io.ClassPathScanningProvider;
import cn.featherfly.common.io.FileUtils;
import cn.featherfly.common.lang.ClassLoaderUtils;
import cn.featherfly.common.lang.ClassUtils;
import cn.featherfly.common.lang.LangUtils;
import cn.featherfly.common.lang.UriUtils;
import cn.featherfly.common.lang.matcher.MethodAnnotationMatcher;
import cn.featherfly.constant.ConstantPool;
import cn.featherfly.hammer.HammerException;
import cn.featherfly.hammer.config.HammerConstant;
import cn.featherfly.hammer.tpl.annotation.Mapper;
import cn.featherfly.hammer.tpl.annotation.Template;

/**
 * 

* Config *

* * @author zhongj */ public class TplConfigFactoryImpl implements TplConfigFactory { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); private static final String MULTI_SAME_EXECUTEID = "!" + ID_SIGN + "!"; private ObjectMapper mapper; private boolean devMode; private String suffix; private String prefix; private Map configs = new HashMap<>(); private Map executIdFileMap = new HashMap<>(); private ResourcePatternResolver resourcePatternResolver; private ClassPathScanningProvider classPathScanningProvider; private Set basePackages = new HashSet<>(); /** * */ public TplConfigFactoryImpl() { this(HammerConstant.DEFAULT_PREFIX); } /** * @param basePackages basePackages */ public TplConfigFactoryImpl(Set basePackages) { this(HammerConstant.DEFAULT_PREFIX, basePackages); } /** * @param prefix prefix */ public TplConfigFactoryImpl(String prefix) { this(prefix, HammerConstant.DEFAULT_SUFFIX); } /** * @param prefix prefix * @param basePackages basePackages */ public TplConfigFactoryImpl(String prefix, Set basePackages) { this(prefix, HammerConstant.DEFAULT_SUFFIX, basePackages); } /** * @param prefix prefix * @param suffix suffix */ public TplConfigFactoryImpl(String prefix, String suffix) { this(prefix, suffix, null); } /** * @param prefix prefix * @param suffix suffix * @param basePackages basePackages */ public TplConfigFactoryImpl(String prefix, String suffix, Set basePackages) { mapper = new ObjectMapper(new YAMLFactory()); mapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); if (LangUtils.isEmpty(prefix)) { this.prefix = HammerConstant.DEFAULT_PREFIX; } else { this.prefix = prefix; } if (LangUtils.isEmpty(suffix)) { this.suffix = HammerConstant.DEFAULT_SUFFIX; } else { this.suffix = suffix; } this.basePackages = basePackages == null ? new HashSet<>() : basePackages; devMode = ConstantPool.getDefault().getConstantParameter().isDevMode(); // 读取模板文件 initConfigs(); // 读取mapper类 resolverMapper(); } private void resolverMapper() { if (LangUtils.isEmpty(basePackages)) { return; } if (classPathScanningProvider == null) { classPathScanningProvider = new ClassPathScanningProvider(); } for (String basePackage : basePackages) { Set metadataReaders = classPathScanningProvider.findMetadata(basePackage); for (MetadataReader metadataReader : metadataReaders) { if (metadataReader.getAnnotationMetadata().hasAnnotatedMethods(Template.class.getName())) { readConfig(ClassUtils.forName(metadataReader.getClassMetadata().getClassName())); } } } } // private TplExecuteConfigs readConfig(TplExecuteId tplExecuteId) { // if (tplExecuteId instanceof TplExecuteIdFileImpl) { // return readConfig(tplExecuteId.getId()); // } else if (tplExecuteId instanceof TplExecuteIdMapperImpl) { // return readConfig(((TplExecuteIdMapperImpl) tplExecuteId).getMapper()); // } else { // throw new HammerException("Unsupported TplExecuteId type -> " + tplExecuteId.getClass().getName()); // } // } private String getNamespace(Class type) { Mapper mapper = type.getAnnotation(Mapper.class); return mapper == null || LangUtils.isEmpty(mapper.namespace()) ? type.getName() : mapper.namespace(); } private TplExecuteConfigs readConfig(Class type) { Collection methods = ClassUtils.findMethods(type, new MethodAnnotationMatcher(Template.class)); String globalNamespace = getNamespace(type); TplExecuteConfigs newConfigs = new TplExecuteConfigs(); newConfigs.setName(globalNamespace); newConfigs.setFilePath(ClassUtils.packageToDir(type.getName())); String fileDirectory = ClassUtils.packageToDir(type); Set executeIds = new HashSet<>(); for (Method method : methods) { Template template = method.getAnnotation(Template.class); if (LangUtils.isEmpty(template.value())) { continue; } String name = LangUtils.isEmpty(template.name()) ? method.getName() : template.name(); String namespace = LangUtils.isEmpty(template.namespace()) ? globalNamespace : template.namespace(); checkName(executeIds, name, namespace); TplExecuteConfig config = new TplExecuteConfig(); config.setQuery(template.value()); config.setTplName(namespace + ID_SIGN + name); config.setExecuteId(name); config.setName(type.getSimpleName()); config.setFileName(type.getSimpleName() + ".class"); config.setFileDirectory(fileDirectory); logger.debug("type -> {} , namespace -> {} , {} -> {}", type.getName(), namespace, name, config); newConfigs.put(name, config); if (executIdFileMap.containsKey(config.getExecuteId()) && !executIdFileMap.get(config.getExecuteId()).equals(newConfigs.getName())) { executIdFileMap.put(config.getExecuteId(), MULTI_SAME_EXECUTEID); } else { executIdFileMap.put(config.getExecuteId(), newConfigs.getName()); } } logger.debug("type -> {} , namespace -> {} , configs -> {}", type.getName(), globalNamespace, newConfigs); configs.put(newConfigs.getName(), newConfigs); return newConfigs; } private void checkName(Set executeIds, String name, String namespace) { if (name.contains(ID_SIGN)) { throw new HammerException("invalidate character [" + ID_SIGN + "] in executeId [" + name + "]"); } if (executeIds.contains(name)) { throw new HammerException("duplicated executeId [" + name + "] in [" + namespace + "]"); } } private void initConfigs() { resourcePatternResolver = new PathMatchingResourcePatternResolver(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + UriUtils.linkUri(prefix, "**/*") + suffix; try { Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { if (FileUtils.isResourceInJar(resource.getURL())) { readConfig(FileUtils.getPathInJar(resource.getURL())); } else { String path = resource.getURL().getPath(); Enumeration enums = ClassLoader.getSystemResources(""); while (enums.hasMoreElements()) { String rootPath = enums.nextElement().getPath(); if (path.startsWith(rootPath)) { path = org.apache.commons.lang3.StringUtils.substring(path, rootPath.length()); break; } } logger.debug("init read config : {}", path); readConfig(path); } } } catch (IOException e) { // TODO 使用exceptioncode throw new HammerException("使用路径" + packageSearchPath + "扫描tpl配置文件时I/O异常", e); } } private TplExecuteConfigs readConfig(final String filePath) { String finalFilePath = toFinalFilePath(filePath); final String fileName = org.apache.commons.lang3.StringUtils.substringAfterLast(finalFilePath, "/"); final String fileDirectory = org.apache.commons.lang3.StringUtils.substringBeforeLast(finalFilePath, "/"); final String name = org.apache.commons.lang3.StringUtils.substringBeforeLast(finalFilePath, suffix); try { InputStream in = ClassLoaderUtils.getResourceAsStream(finalFilePath, TplConfigFactoryImpl.class); if (in == null) { throw new HammerException("can not read config from " + finalFilePath + " it may be does not exist"); } TplExecuteConfigs tplExecuteConfigs = mapper.readerFor(TplExecuteConfigs.class).readValue(in); TplExecuteConfigs newConfigs = new TplExecuteConfigs(); newConfigs.setFilePath(finalFilePath); newConfigs.setName(org.apache.commons.lang3.StringUtils.removeEnd(finalFilePath, suffix)); Set executeIds = new HashSet<>(); tplExecuteConfigs.forEach((k, v) -> { TplExecuteConfig config = new TplExecuteConfig(); if (v instanceof String) { config.setQuery(v.toString()); } else { @SuppressWarnings("unchecked") Map map = (Map) v; if (LangUtils.isNotEmpty(map.get("query"))) { config.setQuery(map.get("query").toString()); } if (LangUtils.isNotEmpty(map.get("count"))) { config.setCount(map.get("count").toString()); } if (LangUtils.isNotEmpty(map.get("type"))) { config.setType(TplType.valueOf(map.get("type").toString())); } } checkName(executeIds, k, finalFilePath); executeIds.add(k); config.setTplName(newConfigs.getName() + ID_SIGN + k); config.setExecuteId(k); config.setName(name); config.setFileName(fileName); config.setFileDirectory(fileDirectory); logger.debug("filePath -> {} , finalFilePath -> {} , {} -> {}", filePath, finalFilePath, k, config); // System.out.println(config); newConfigs.put(k, config); if (executIdFileMap.containsKey(config.getExecuteId()) && !executIdFileMap.get(config.getExecuteId()).equals(finalFilePath)) { executIdFileMap.put(config.getExecuteId(), MULTI_SAME_EXECUTEID); } else { executIdFileMap.put(config.getExecuteId(), finalFilePath); } }); logger.debug("filePath -> {} , finalFilePath -> {} , configs -> {}", filePath, finalFilePath, newConfigs); configs.put(finalFilePath, newConfigs); return newConfigs; } catch (IOException e) { // TODO 使用exceptioncode throw new HammerException("exception when read config file " + finalFilePath + " with argu " + filePath, e); } } private String toFinalFilePath(String filePath) { String result = filePath; // 表示传入不是文件地址字符串,不是完整的地址 if (!result.endsWith(suffix)) { result = result + suffix; if (!result.startsWith("/")) { result = prefix + result; } } if (result.startsWith("/")) { result = result.substring(1); } return result; } /** * {@inheritDoc} */ @Override public Collection getAllConfigs() { return new ArrayList<>(configs.values()); } /** * {@inheritDoc} */ @Override public TplExecuteConfigs getConfigs(String filePath) { if (devMode) { return readConfig(filePath); } else { return configs.get(toFinalFilePath(filePath)); } } private TplExecuteConfigs getConfigs(Class type) { if (devMode) { return readConfig(type); } else { return configs.get(getNamespace(type)); } } /** * {@inheritDoc} */ @Override public TplExecuteConfig getConfig(TplExecuteId executeId) { if (executeId instanceof TplExecuteIdMapperImpl) { TplExecuteConfigs configs = getConfigs(((TplExecuteIdMapperImpl) executeId).getMapper()); if (configs == null) { // TODO 使用exceptioncode throw new HammerException( "configs with type->" + ((TplExecuteIdMapperImpl) executeId).getMapper().getName() + ",namespace->" + executeId.getNamespace() + " not find"); } TplExecuteConfig config = configs.getConfig(executeId.getName()); if (config == null) { // TODO 使用exceptioncode throw new HammerException("executeId " + executeId.getName() + " not find with type->" + executeId.getNamespace() + ",namespace->" + executeId.getNamespace()); } return config; } else if (executeId instanceof TplExecuteIdFileImpl) { return getConfig(executeId.getId()); } else { throw new HammerException("Unsupported TplExecuteId type -> " + executeId.getClass().getName()); } } /** * {@inheritDoc} */ @Override public TplExecuteConfig getConfig(String executeId) { executeId = org.apache.commons.lang3.StringUtils.substringBeforeLast(executeId, COUNT_SUFFIX); String[] result = getFilePathAndexecuteId(executeId); String filePath = null; String eId = null; if (result.length == 1) { filePath = getFilePath(executeId); eId = executeId; } else { filePath = result[0]; eId = result[1]; } TplExecuteConfigs configs = getConfigs(filePath); if (configs == null) { // TODO 使用exceptioncode throw new HammerException("file " + filePath + " not find"); } TplExecuteConfig config = configs.getConfig(eId); if (config == null) { // TODO 使用exceptioncode throw new HammerException("executeId " + eId + " not find in " + filePath); } return config; } private String[] getFilePathAndexecuteId(String executeId) { String[] result = executeId.split(ID_SIGN); return result; } private String getFilePath(String executeId) { String file = executIdFileMap.get(executeId); if (MULTI_SAME_EXECUTEID.equals(file)) { // TODO 使用exceptioncode throw new HammerException("duplicated executeId[" + executeId + "], you will use full executeId like dir/file" + ID_SIGN + executeId); } return file; } /** * 返回devMode * * @return devMode */ public boolean isDevMode() { return devMode; } /** * 返回suffix * * @return suffix */ public String getSuffix() { return suffix; } /** * 返回prefix * * @return prefix */ public String getPrefix() { return prefix; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy