提交 c2d07424 编写于 作者: sq3536's avatar sq3536

init

上级 4f6069f5
*volumes
*target
.settings
*node_modules
*bin
*.project
*.classpath
*.factorypath
.history
.vscode
.idea
**.iml
*.jar
*.log
.DS_Store
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
</parent>
<packaging>pom</packaging>
<artifactId>ibiz-boot-starter-parent</artifactId>
<groupId>net.ibizsys.plugin</groupId>
<version>2.4.0-SNAPSHOT</version>
<name>iBiz Boot Starter Parent</name>
<description>iBiz Boot Starter Parent</description>
<properties>
<revision>2.4.0-SNAPSHOT</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<ibiz-boot-starter.version>2.4.0-SNAPSHOT</ibiz-boot-starter.version>
<ibiz.cloud.version>8.1.0.132</ibiz.cloud.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
<spring-cloud-starter-bootstrap.version>3.0.1</spring-cloud-starter-bootstrap.version>
<fastjson.version>1.2.83</fastjson.version>
<zalando-problem-spring-web.version>0.23.0</zalando-problem-spring-web.version>
<maven.deploy.skip>false</maven.deploy.skip>
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-cloud</artifactId>
<version>${ibiz.cloud.version}</version>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-redis</artifactId>
<version>${ibiz.cloud.version}</version>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-mybatisplus-spring-boot-starter</artifactId>
<version>${ibiz.cloud.version}</version>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-zookeeper</artifactId>
<version>${ibiz.cloud.version}</version>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-poi</artifactId>
<version>${ibiz.cloud.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>problem-spring-web</artifactId>
<version>${zalando-problem-spring-web.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>${spring-cloud-starter-bootstrap.version}</version>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-boot-starter</artifactId>
<version>${ibiz-boot-starter.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<distributionManagement>
<repository>
<id>ibizmvnrepository</id>
<url>http://172.16.240.220:8081/repository/releases</url>
</repository>
<snapshotRepository>
<id>ibizmvnrepository</id>
<url>http://172.16.240.220:8081/repository/snapshots</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>ibizmvnrepository</id>
<name>ibizmvnrepository</name>
<url>http://172.16.240.220:8081/repository/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ibiz-boot-starter</artifactId>
<groupId>net.ibizsys.plugin</groupId>
<version>2.4.0-SNAPSHOT</version>
<name>iBiz Boot Starter</name>
<description>iBiz Boot Starter</description>
<parent>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-boot-starter-parent</artifactId>
<version>2.4.0-SNAPSHOT</version>
<relativePath>../ibiz-boot-starter-parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-cloud</artifactId>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-redis</artifactId>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-mybatisplus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-zookeeper</artifactId>
</dependency>
<dependency>
<groupId>net.ibizsys.plugin</groupId>
<artifactId>ibiz-plugin-poi</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- webservice -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-bootstrap</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.zalando</groupId>
<artifactId>problem-spring-web</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<configuration>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<configuration>
<!-- 更新元数据 -->
<updateReleaseInfo>true</updateReleaseInfo>
<skip>${maven.deploy.skip}</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.cache;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import net.ibizsys.central.plugin.boot.core.cache.cacheManager.CaffeineCacheManager;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
/**
* Caffeine缓存配置类
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnExpression("'${ibiz.cacheLevel:None}'.equals('L1')")
public class CaffeineCacheConfig {
/**
* Caffeine配置:设置过期时间
* @return
*/
@Bean
@Primary
public CacheManager cacheManager(CacheProperties cacheProperties) {
CaffeineCacheManager caffeineCacheManager=new CaffeineCacheManager();
String strCacheConfig = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(strCacheConfig)) {
caffeineCacheManager.setCaffeineCacheConfig(CaffeineSpec.parse(strCacheConfig));
}
return caffeineCacheManager;
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.cache;
import net.ibizsys.central.plugin.boot.core.cache.cache.Globs;
import net.ibizsys.central.plugin.boot.core.cache.cacheManager.LayeringCacheManager;
import net.ibizsys.central.plugin.boot.core.cache.listener.RedisMessageListener;
import net.ibizsys.central.plugin.boot.core.cache.redis.CustomJacksonSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;
import java.time.Duration;
/**
* 缓存配置类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnExpression("'${ibiz.cacheLevel:None}'.equals('L2')")
public class RedisCacheConfig {
@Value("${spring.cache.redis.time-to-live:3600}")
private long timeToLive;
/**
* 分层缓存管理器
* @param redisConnectionFactory
* @param cacheProperties
* @return
*/
@Bean
@Primary
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory , CacheProperties cacheProperties){
LayeringCacheManager layeringCacheManager=new LayeringCacheManager(redisCacheWriter(redisConnectionFactory),redisCacheConfiguration(),redisTemplate(redisConnectionFactory));
String strCacheConfig = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(strCacheConfig)) {
layeringCacheManager.setCaffeineCacheConfig(CaffeineSpec.parse(strCacheConfig));
}
return layeringCacheManager;
}
/**
* redis配置:设置过期时间及序列化方式
* @return
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration(){
CustomJacksonSerializer jackson2JsonRedisSerializer = new CustomJacksonSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(timeToLive))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
return configuration;
}
/**
* 创建redis缓存
* @param connectionFactory
* @return
*/
@Bean
public RedisCacheWriter redisCacheWriter(RedisConnectionFactory connectionFactory){
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
return redisCacheWriter;
}
/**
* 发送redis广播
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
CustomJacksonSerializer jacksonSerial = new CustomJacksonSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jacksonSerial.setObjectMapper(om);
template.setValueSerializer(jacksonSerial);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSerial);
template.afterPropertiesSet();
return template;
}
/**
* 监听redis指定频道
* @param redisConnectionFactory
* @param cacheManager
* @param redisTemplate
* @return
*/
@Bean
RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, CacheManager cacheManager , RedisTemplate redisTemplate) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
MessageListenerAdapter messageListener=new RedisMessageListener(cacheManager,redisTemplate);
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListener, Globs.RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());
container.addMessageListener(messageListener, Globs.RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());
container.addMessageListener(messageListener, Globs.RedisChannelTopic.REDIS_CACHE_DYNAMICMODEL_TOPIC.getChannelTopic());
return container;
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.cache.cache;
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.cache.caffeine.CaffeineCache;
import javax.validation.constraints.NotNull;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 自定义的Caffeine缓存
*/
public class CusCaffeineCache extends CaffeineCache {
public CusCaffeineCache(String name, Cache<Object, Object> cache) {
super(name,cache);
}
public CusCaffeineCache(String name, Cache<Object, Object> cache, boolean allowNullValues) {
super(name,cache,allowNullValues);
}
@Override
public void evict(@NotNull Object key) {
if (key instanceof String && ((String) key).startsWith("glob:")) {
String globPattern = ((String)key).split("glob:")[1];
// 将Glob匹配转换成正则匹配
String regexPattern = Globs.toUnixRegexPattern(globPattern);
// String regexPattern = Globs.toWindowsRegexPattern(globPattern);
Cache<Object,Object> cache = super.getNativeCache();
Set<Object> keySet = cache.asMap().keySet();
keySet = keySet.stream().filter(o->o.toString().matches(regexPattern)).collect(Collectors.toSet());
cache.invalidateAll(keySet);
}else{
super.evict(key);
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import javax.validation.constraints.NotNull;
/**
* 自定义的redis缓存
*/
public class CusRedisCache extends RedisCache {
public CusRedisCache(String name, RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(name, redisCacheWriter, configuration);
}
@Override
public void evict(@NotNull Object key) {
if (key instanceof String && ((String) key).startsWith("glob:")) {
String globPattern = ((String)key).split("glob:")[1];
byte[] globPatternBytes = super.getCacheConfiguration().getConversionService().convert(globPattern,byte[].class);
if(globPatternBytes!=null){
super.getNativeCache().clean(super.getName(),globPatternBytes);
}
}else{
super.evict(key);
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.cache;
import org.springframework.data.redis.listener.ChannelTopic;
import java.util.regex.PatternSyntaxException;
/**
* Copy from class sun.nio.fs.Globs
*/
public class Globs {
private Globs() { }
private static final String regexMetaChars = ".^$+{[]|()";
private static final String globMetaChars = "\\*?[{";
private static boolean isRegexMeta(char c) {
return regexMetaChars.indexOf(c) != -1;
}
private static boolean isGlobMeta(char c) {
return globMetaChars.indexOf(c) != -1;
}
private static char EOL = 0; //TBD
private static char next(String glob, int i) {
if (i < glob.length()) {
return glob.charAt(i);
}
return EOL;
}
/**
* Creates a regex pattern from the given glob expression.
*
* @throws PatternSyntaxException
*/
private static String toRegexPattern(String globPattern, boolean isDos) {
boolean inGroup = false;
StringBuilder regex = new StringBuilder("^");
int i = 0;
while (i < globPattern.length()) {
char c = globPattern.charAt(i++);
switch (c) {
case '\\':
// escape special characters
if (i == globPattern.length()) {
throw new PatternSyntaxException("No character to escape",
globPattern, i - 1);
}
char next = globPattern.charAt(i++);
if (isGlobMeta(next) || isRegexMeta(next)) {
regex.append('\\');
}
regex.append(next);
break;
case '/':
if (isDos) {
regex.append("\\\\");
} else {
regex.append(c);
}
break;
case '[':
// don't match name separator in class
if (isDos) {
regex.append("[[^\\\\]&&[");
} else {
regex.append("[[^/]&&[");
}
if (next(globPattern, i) == '^') {
// escape the regex negation char if it appears
regex.append("\\^");
i++;
} else {
// negation
if (next(globPattern, i) == '!') {
regex.append('^');
i++;
}
// hyphen allowed at start
if (next(globPattern, i) == '-') {
regex.append('-');
i++;
}
}
boolean hasRangeStart = false;
char last = 0;
while (i < globPattern.length()) {
c = globPattern.charAt(i++);
if (c == ']') {
break;
}
if (c == '/' || (isDos && c == '\\')) {
throw new PatternSyntaxException("Explicit 'name separator' in class",
globPattern, i - 1);
}
// TBD: how to specify ']' in a class?
if (c == '\\' || c == '[' ||
c == '&' && next(globPattern, i) == '&') {
// escape '\', '[' or "&&" for regex class
regex.append('\\');
}
regex.append(c);
if (c == '-') {
if (!hasRangeStart) {
throw new PatternSyntaxException("Invalid range",
globPattern, i - 1);
}
if ((c = next(globPattern, i++)) == EOL || c == ']') {
break;
}
if (c < last) {
throw new PatternSyntaxException("Invalid range",
globPattern, i - 3);
}
regex.append(c);
hasRangeStart = false;
} else {
hasRangeStart = true;
last = c;
}
}
if (c != ']') {
throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
}
regex.append("]]");
break;
case '{':
if (inGroup) {
throw new PatternSyntaxException("Cannot nest groups",
globPattern, i - 1);
}
regex.append("(?:(?:");
inGroup = true;
break;
case '}':
if (inGroup) {
regex.append("))");
inGroup = false;
} else {
regex.append('}');
}
break;
case ',':
if (inGroup) {
regex.append(")|(?:");
} else {
regex.append(',');
}
break;
case '*':
if (next(globPattern, i) == '*') {
// crosses directory boundaries
regex.append(".*");
i++;
} else {
// within directory boundary
if (isDos) {
regex.append("[^\\\\]*");
} else {
regex.append("[^/]*");
}
}
break;
case '?':
if (isDos) {
regex.append("[^\\\\]");
} else {
regex.append("[^/]");
}
break;
default:
if (isRegexMeta(c)) {
regex.append('\\');
}
regex.append(c);
}
}
if (inGroup) {
throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
}
return regex.append('$').toString();
}
public static String toUnixRegexPattern(String globPattern) {
return toRegexPattern(globPattern, false);
}
public static String toWindowsRegexPattern(String globPattern) {
return toRegexPattern(globPattern, true);
}
/**
* redis频道
*/
public enum RedisChannelTopic {
REDIS_CACHE_DELETE_TOPIC("redis:cache:delete:topic1", "删除redis缓存消息频道"),
REDIS_CACHE_CLEAR_TOPIC("redis:cache:clear:topic2", "清空redis缓存消息频道"),
REDIS_CACHE_DYNAMICMODEL_TOPIC("redis:cache:dynamicmodel:topic3", "动态模型频道");
String channelTopic;
String label;
RedisChannelTopic(String channelTopic, String label) {
this.channelTopic = channelTopic;
this.label = label;
}
public ChannelTopic getChannelTopic() {
return new ChannelTopic(channelTopic);
}
public static RedisChannelTopic getChannelTopicEnum(String channelTopic) {
for (RedisChannelTopic awardTypeEnum : RedisChannelTopic.values()) {
if (awardTypeEnum.getChannelTopicStr().equals(channelTopic)) {
return awardTypeEnum;
}
}
return null;
}
public String getChannelTopicStr() {
return channelTopic;
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.cache;
import lombok.extern.slf4j.Slf4j;
import net.ibizsys.central.plugin.boot.core.cache.listener.RedisPublisher;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import org.springframework.cache.support.NullValue;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* 缓存分层类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@Slf4j
public class LayeringCache extends AbstractValueAdaptingCache {
/**
* 缓存的名称
*/
private String cacheName;
/**
* Caffeine缓存
*/
private CaffeineCache caffeineCache;
/**
* redis缓存
*/
private RedisCache redisCache;
/**
* redis消息发布
*/
RedisOperations<? extends Object, ? extends Object> redisOperations;
public LayeringCache(String cacheName , CaffeineCache caffeineCache, RedisCache redisCache, RedisOperations redisOperations) {
super(true);
this.cacheName = cacheName;
this.caffeineCache = caffeineCache;
this.redisCache = redisCache;
this.redisOperations=redisOperations;
}
@Override
public String getName() {
return this.cacheName;
}
@Override
public Object getNativeCache() {
return this;
}
@Override
public ValueWrapper get(Object key) {
ValueWrapper wrapper = caffeineCache.get(key);
Object value = ObjectUtils.isEmpty(wrapper) ? null : wrapper.get();
log.debug("查询一级缓存 key:{} ", key, value);
if (ObjectUtils.isEmpty(value)) {
wrapper = redisCache.get(key);
value = ObjectUtils.isEmpty(wrapper) ? null : wrapper.get();
log.debug("查询二级缓存 key:{} ", key);
if (!ObjectUtils.isEmpty(value)) {
caffeineCache.put(key, value);
log.debug("查询二级缓存,并将数据放到一级缓存。 key:{} ", key);
}
}
return wrapper;
}
@Override
public <T> T get(Object key, Class<T> type) {
T value = caffeineCache.get(key, type);
log.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key, type);
caffeineCache.put(key, value);
log.debug("查询二级缓存,并将数据放到一级缓存。 key:{}", key);
}
return value;
}
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
T value = (T) caffeineCache.getNativeCache().get(key, k -> getSecondCacheValue(k, valueLoader));
if(value==null) {
value = (T) getSecondCacheValue(key, valueLoader);
}
if (value instanceof NullValue) {
return null;
}
return value;
}
@Override
public void put(Object key, Object value) {
if(value!=null) {
caffeineCache.put(key, value);
redisCache.put(key, value);
}
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
caffeineCache.putIfAbsent(key, value);
return redisCache.putIfAbsent(key, value);
}
@Override
public void evict(Object key) {
redisCache.evict(key); //清除redis中的二级缓存
caffeineCache.evict(key);//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", cacheName);
message.put("key", key);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, Globs.RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
log.debug(String.format("清除二级缓存数据[%s]", key));
}
@Override
public void clear() {
redisCache.clear(); //清除redis中的二级缓存
caffeineCache.clear();//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", cacheName);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, Globs.RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
@Override
protected Object lookup(Object key) {
Object value = caffeineCache.get(key);
log.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key);
log.debug("查询二级缓存 key:{}", key);
}
return value;
}
/**
* 获取caffeine缓存
* @return
*/
public CaffeineCache getFirstCache() {
return this.caffeineCache;
}
/**
* 获取redis缓存
* @return
*/
public RedisCache getSecondCache() {
return this.redisCache;
}
/**
* 查询二级缓存
* @param key
* @param valueLoader
* @return
*/
private <T> Object getSecondCacheValue(Object key, Callable<T> valueLoader) {
T value = redisCache.get(key, valueLoader);
log.debug("查询二级缓存 key:{}", key);
return toStoreValue(value);
}
}
package net.ibizsys.central.plugin.boot.core.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import lombok.Data;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* Caffeine本地缓存
*/
@Data
public class CaffeineCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private static final int default_expire_after_write = 1;
private static final int default_initial_capacity = 5;
private static final int default_maximum_size = 1_000;
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(default_expire_after_write, TimeUnit.HOURS)
.initialCapacity(default_initial_capacity)
.maximumSize(default_maximum_size);
/**
* 获取缓存对象
* @param cacheName
* @return
*/
@Override
public Cache getCache(String cacheName) {
Cache cache = this.cacheMap.get(cacheName);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(cacheName);
if (cache == null) {
cache = createCache(cacheName);
this.cacheMap.put(cacheName, cache);
}
}
}
return cache;
}
/**
* 创建缓存
* @param cacheName
* @return
*/
protected Cache createCache(String cacheName) {
return new CaffeineCache(cacheName, this.cacheBuilder.build(), true);
}
/**
* 获取缓存名
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineCacheConfig
*/
public void setCaffeineCacheConfig(CaffeineSpec caffeineCacheConfig) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineCacheConfig);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import lombok.Data;
import net.ibizsys.central.plugin.boot.core.cache.cache.CusCaffeineCache;
import net.ibizsys.central.plugin.boot.core.cache.cache.CusRedisCache;
import net.ibizsys.central.plugin.boot.core.cache.cache.LayeringCache;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* 缓存分层
* 1级缓存为caffeine
* 2级缓存为redis
*/
@Data
public class LayeringCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private static final int default_expire_after_write = 1;
private static final int default_initial_capacity = 5;
private static final int default_maximum_size = 1_000;
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(default_expire_after_write, TimeUnit.HOURS)
.initialCapacity(default_initial_capacity)
.maximumSize(default_maximum_size);
private RedisCacheWriter redisCacheWriter;
private RedisCacheConfiguration redisConfiguration;
private RedisTemplate<String, Object> redisTemplate;
public LayeringCacheManager(RedisCacheWriter redisCacheWriter , RedisCacheConfiguration redisConfiguration , RedisTemplate<String, Object> redisTemplate ){
this.redisCacheWriter=redisCacheWriter;
this.redisConfiguration=redisConfiguration;
this.redisTemplate= redisTemplate;
}
/**
* 获取缓存对象
* @param cacheName
* @return
*/
@Override
public Cache getCache(String cacheName) {
Cache cache = this.cacheMap.get(cacheName);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(cacheName);
if (cache == null) {
cache = createCache(cacheName);
this.cacheMap.put(cacheName, cache);
}
}
}
return cache;
}
/**
* 获取集合中的缓存
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 创建缓存
* @param cacheName
* @return
*/
protected Cache createCache(String cacheName) {
return new LayeringCache(cacheName,new CusCaffeineCache(cacheName, this.cacheBuilder.build(), true),new CusRedisCache(cacheName, redisCacheWriter, redisConfiguration),redisTemplate);
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineCacheConfig
*/
public void setCaffeineCacheConfig(CaffeineSpec caffeineCacheConfig) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineCacheConfig);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.listener;
import lombok.extern.slf4j.Slf4j;
import net.ibizsys.central.plugin.boot.core.cache.cache.Globs;
import net.ibizsys.central.plugin.boot.core.cache.cache.LayeringCache;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* redis消息的订阅者
*/
@Slf4j
public class RedisMessageListener extends MessageListenerAdapter {
private CacheManager cacheManager;
private RedisTemplate redisTemplate;
public RedisMessageListener(CacheManager cacheManager, RedisTemplate redisTemplate){
this.cacheManager=cacheManager;
this.redisTemplate=redisTemplate;
}
@Override
public void onMessage(Message message, byte[] pattern) {
Globs.RedisChannelTopic channelTopic = Globs.RedisChannelTopic.getChannelTopicEnum(new String(message.getChannel()));
Map<String, Object> map = null;
RedisSerializer serializer=redisTemplate.getValueSerializer();
Object result=serializer.deserialize(message.getBody());
if(result instanceof Map){
map= (Map<String, Object>) result;
}
if(StringUtils.isEmpty(map)|| (!map.containsKey("cacheName"))){
log.debug("解析缓存数据失败,无法获取指定值!");
return ;
}
log.debug("redis消息订阅者接收到频道【{}】发布的消息。消息内容:{}", channelTopic.getChannelTopicStr(), result.toString());
String cacheName = (String) map.get("cacheName");
Cache cache = cacheManager.getCache(cacheName);// 根据缓存名称获取多级缓存
if (cache != null && cache instanceof LayeringCache) { // 判断缓存是否是多级缓存
switch (channelTopic) {
case REDIS_CACHE_DELETE_TOPIC: // 获取一级缓存,并删除一级缓存数据
Object cacheKey = map.get("key");
if(!ObjectUtils.isEmpty(cacheKey)){
((LayeringCache) cache).getFirstCache().evict(cacheKey);
((LayeringCache) cache).getSecondCache().evict(cacheKey);
log.debug("同步删除缓存{}数据,key:{},", cacheName, cacheKey.toString());
}
else{
log.debug("同步删除缓存失败,{}缓存键值为空!",cacheName);
}
break;
case REDIS_CACHE_CLEAR_TOPIC:// 获取一级缓存,并删除一级缓存数据
((LayeringCache) cache).getFirstCache().clear();
((LayeringCache) cache).getSecondCache().clear();
log.debug("同步清除缓存{}数据", cacheName);
break;
default:
log.debug("接收到没有定义的订阅消息频道数据");
break;
}
}
}
}
package net.ibizsys.central.plugin.boot.core.cache.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.listener.ChannelTopic;
/**
* redis消息的发布者
*/
public class RedisPublisher {
private static final Logger logger = LoggerFactory.getLogger(RedisPublisher.class);
RedisOperations<? extends Object, ? extends Object> redisOperations;
/**
* 频道名称
*/
ChannelTopic channelTopic;
/**
* @param redisOperations Redis客户端
* @param channelTopic 频道名称
*/
public RedisPublisher(RedisOperations<? extends Object, ? extends Object> redisOperations, ChannelTopic channelTopic) {
this.channelTopic = channelTopic;
this.redisOperations = redisOperations;
}
/**
* 发布消息到频道(Channel)
*
* @param message 消息内容
*/
public void publisher(Object message) {
redisOperations.convertAndSend(channelTopic.toString(), message);
logger.debug("redis消息发布者向频道【{}】发布了【{}】消息", channelTopic.toString(), message.toString());
}
}
package net.ibizsys.central.plugin.boot.core.cache.redis;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CustomJacksonSerializer<T> extends Jackson2JsonRedisSerializer<T> {
public static final String DEFAULT_PACKAGE ="[\\w+\\.]+\\.AuthenticationUser";
public static final String CLASSNAME_EX="_$$_";
public static final String CLASSNAME_EX_PATTEN="(_\\$\\$_)(\\w+)";
public CustomJacksonSerializer(Class type) {
super(type);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
String serializerContent = new String(bytes, DEFAULT_CHARSET);
Matcher matcher = Pattern.compile(DEFAULT_PACKAGE).matcher(serializerContent);
if(serializerContent.contains(CLASSNAME_EX)){
serializerContent=serializerContent.replaceAll(CLASSNAME_EX_PATTEN,"");
}
return super.deserialize(serializerContent.getBytes());
}
}
package net.ibizsys.central.plugin.boot.core.dict;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.util.TypeUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Catalog
{
private String code;
private String name;
@JSONField(name = "items")
@JsonProperty("items")
private List<Option> options = new ArrayList<>();
public Option findCodeItem(Object value)
{
return findCodeItem(value,this.options);
}
public Option findCodeItem(Object value, List<Option> options){
for(Option codeItem : options){
if(value != null && codeItem.getValue() != null && value.equals(codeItem.getValue()))
return codeItem;
else if (!ObjectUtils.isEmpty(codeItem.getChildren()))
{
Option rt=findCodeItem(value,codeItem.getChildren());
if(rt!=null)
return rt;
}
}
return null;
}
private Map<String, Object> advancedSettings;
public Catalog putAdvancedSettings(String settings)
{
try
{
if(!StringUtils.isEmpty(settings))
advancedSettings= JSON.parseObject(settings, Map.class);
}catch (Exception ex){}
return this;
}
@JsonIgnore
@JSONField(serialize = false)
public String getUrl() {
return getSetting("url",null);
}
@JsonIgnore
@JSONField(serialize = false)
public String getRequestMethod() {
return getSetting("requestMethod","GET");
}
@JsonIgnore
@JSONField(serialize = false)
public String getRequestBody() {
return getSetting("requestBody","{}");
}
@JsonIgnore
@JSONField(serialize = false)
public String getNodeProp() {
return getSetting("nodeProp","");
}
@JsonIgnore
@JSONField(serialize = false)
public String getValueProp() {
return getSetting("valueProp","value");
}
@JsonIgnore
@JSONField(serialize = false)
public String getLabelProp() {
return getSetting("labelProp","label");
}
@JsonIgnore
@JSONField(serialize = false)
public String getParentProp() {
return getSetting("parentProp","parent");
}
@JsonIgnore
@JSONField(serialize = false)
public String getChildrenProp() {
return getSetting("childrenProp","children");
}
@JsonIgnore
@JSONField(serialize = false)
public String getDisabledProp() {
return getSetting("disabledProp","disabled");
}
@JsonIgnore
@JSONField(serialize = false)
public String getFilterProp() {
return getSetting("filterProp","filter");
}
@JsonIgnore
@JSONField(serialize = false)
public String getExpiredProp() {
return getSetting("expiredProp","expired");
}
@JsonIgnore
@JSONField(serialize = false)
public String getIconClassProp() {
return getSetting("iconClassProp","iconClass");
}
public Catalog setNodes(List<Map> nodes)
{
return setNodes(nodes,null,null);
}
public Catalog setNodes(List<Map> nodes, String filter, String subCode)
{
Map<String, List<Option>> map = new LinkedHashMap<>();
Option subOption=null;
for(Map item:unfoldList(nodes,null))
{
Map<String, Object> extension = new HashMap<>();
if(!StringUtils.isEmpty(item.get("extension")))
extension = JSONObject.parseObject(item.get("extension").toString(), Map.class);
String pid= getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),"_root"));
if(StringUtils.isEmpty(pid))pid="_root";
List<Option> list=null;
if(!map.containsKey(pid))
{
list=new ArrayList<>();
map.put(pid,list);
}
else
list=map.get(pid);
Option option=new Option().setValue(getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null)))
.setId(getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null)))
.setDisabled(getBooleanValue(item.get(this.getDisabledProp()),false)|| getBooleanValue(item.get(this.getExpiredProp()),false))
.setFilter(getStringValue(item.get(this.getFilterProp()),null)).setIconClass(getStringValue(item.get(this.getIconClassProp()),null))
.setLabel(getStringValue(item.get(this.getLabelProp()), getStringValue(item.get("text"),"")))
.setParent(getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),""))).setExtension(extension);
if(option.getValue().equals(subCode))
subOption=option;
if(StringUtils.isEmpty(filter)||option.getFilterSet().contains(filter))
list.add(option);
}
List<Option> codeItemTreeList = loop(map, (StringUtils.isEmpty(subCode))?"_root":subCode);
if(subOption!=null)
{
subOption.setChildren(codeItemTreeList).setParent("");
this.getOptions().add(subOption.setParent(null));
}
else
this.setOptions(codeItemTreeList);
return this;
}
private List<Map> unfoldList(List<Map> nodes, String parent)
{
List<Map> unfoldList = new ArrayList<>();
for(Map item:nodes)
{
if((!StringUtils.isEmpty(parent))&& StringUtils.isEmpty(getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),null))))
item.put(this.getParentProp(),parent);
String value = getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null));
unfoldList.add(item);
Object child=item.get(this.getChildrenProp());
if(!ObjectUtils.isEmpty(child))
{
if(child instanceof List && ((List) child).get(0) instanceof Map)
unfoldList.addAll(unfoldList((List)child,value));
item.remove(this.getChildrenProp());
}
}
return unfoldList;
}
private List<Option> loop(Map<String, List<Option>> listCodeItem, Object parentValue) {
List<Option> trees = new ArrayList<Option>();
if(listCodeItem.containsKey(parentValue)) {
for (Option codeItem : listCodeItem.get(parentValue)) {
List<Option> childCodeItem = loop(listCodeItem, codeItem.getValue());
if (childCodeItem.size() > 0)
codeItem.setChildren(childCodeItem);
trees.add(codeItem);
}
}
return trees;
}
private String getSetting(String key,String defaultValue)
{
return advancedSettings!=null&&advancedSettings.get(key)!=null?advancedSettings.get(key).toString():defaultValue;
}
public static <V> V getValue(Object objValue,Class<V> clazz,Object defaultValue)
{
if(objValue==null) return defaultValue==null?null:(V)defaultValue;
return TypeUtils.castToJavaBean(objValue,clazz);
}
public static String getStringValue(Object objValue,String defaultValue)
{
return getValue(objValue,String.class,defaultValue);
}
public static Boolean getBooleanValue(Object objValue,Boolean defaultValue)
{
return getValue(objValue,Boolean.class,defaultValue);
}
}
package net.ibizsys.central.plugin.boot.core.dict;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class CodeItem
{
private String id;
private Object value;
private String label;
@JsonIgnore
@JSONField(serialize = false)
private List<CodeItem> children;
private String iconClass;
private String filter;
private Boolean disabled;
@JSONField(name = "pvalue")
@JsonProperty("pvalue")
private String parent;
private Map<String, Object> extension;
@JSONField(name = "text")
@JsonProperty("text")
public String getText()
{
return label;
}
@JsonIgnore
@JSONField(serialize = false)
public Set<String> getFilterSet()
{
Set<String> set=new HashSet<>();
if(!StringUtils.isEmpty(filter))
for(String str:filter.split(";|,"))
set.add(str);
return set;
}
}
package net.ibizsys.central.plugin.boot.core.dict;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.util.TypeUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class CodeList
{
@JSONField(name = "srfkey")
@JsonProperty("srfkey")
private String code;
private String name;
@JSONField(name = "emptytext")
@JsonProperty("emptytext")
public String getEmptytext()
{
return "";
}
@JSONField(name = "items")
@JsonProperty("items")
private List<CodeItem> options = new ArrayList<>();
public CodeItem findCodeItem(Object value){
for(CodeItem codeItem : options){
if(value != null && codeItem.getValue() != null && value.equals(codeItem.getValue()))
return codeItem;
}
return null;
}
public CodeItem findChildren(Object value){
CodeItem resultCodeItem = this.findCodeItem(value);
List<CodeItem> children = new ArrayList<>();
for(CodeItem codeItem : options){
if(value != null && resultCodeItem.getValue() != null && codeItem.getParent() != null && codeItem.getParent().equals(resultCodeItem.getValue()))
children.add(codeItem);
}
resultCodeItem.setChildren(children);
return resultCodeItem;
}
private Map<String, Object> advancedSettings;
public CodeList putAdvancedSettings(String settings)
{
try
{
if(!StringUtils.isEmpty(settings))
advancedSettings= JSON.parseObject(settings, Map.class);
}catch (Exception ex){}
return this;
}
@JsonIgnore
@JSONField(serialize = false)
public String getUrl() {
return getSetting("url",null);
}
@JsonIgnore
@JSONField(serialize = false)
public String getRequestMethod() {
return getSetting("requestMethod","GET");
}
@JsonIgnore
@JSONField(serialize = false)
public String getRequestBody() {
return getSetting("requestBody","{}");
}
@JsonIgnore
@JSONField(serialize = false)
public String getNodeProp() {
return getSetting("nodeProp","");
}
@JsonIgnore
@JSONField(serialize = false)
public String getValueProp() {
return getSetting("valueProp","value");
}
@JsonIgnore
@JSONField(serialize = false)
public String getLabelProp() {
return getSetting("labelProp","label");
}
@JsonIgnore
@JSONField(serialize = false)
public String getParentProp() {
return getSetting("parentProp","parent");
}
@JsonIgnore
@JSONField(serialize = false)
public String getChildrenProp() {
return getSetting("childrenProp","children");
}
@JsonIgnore
@JSONField(serialize = false)
public String getDisabledProp() {
return getSetting("disabledProp","disabled");
}
@JsonIgnore
@JSONField(serialize = false)
public String getFilterProp() {
return getSetting("filterProp","filter");
}
@JsonIgnore
@JSONField(serialize = false)
public String getExpiredProp() {
return getSetting("expiredProp","expired");
}
@JsonIgnore
@JSONField(serialize = false)
public String getIconClassProp() {
return getSetting("iconClassProp","iconClass");
}
public CodeList setNodes(List<Map> nodes, String filter, String subCode)
{
Map<String, List<CodeItem>> map = new LinkedHashMap<>();
List<CodeItem> alllist = new ArrayList<>();
CodeItem subOption=null;
for(Map item:unfoldList(nodes,null))
{
Map<String, Object> extension = new HashMap<>();
if(!StringUtils.isEmpty(item.get("extension")))
extension = JSONObject.parseObject(item.get("extension").toString(), Map.class);
String pid= getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),"_root"));
if(StringUtils.isEmpty(pid))pid="_root";
List<CodeItem> list=null;
if(!map.containsKey(pid))
{
list=new ArrayList<>();
map.put(pid,list);
}
else
list=map.get(pid);
CodeItem option=new CodeItem().setValue(getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null)))
.setId(getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null)))
.setDisabled(getBooleanValue(item.get(this.getDisabledProp()),false)|| getBooleanValue(item.get(this.getExpiredProp()),false))
.setFilter(getStringValue(item.get(this.getFilterProp()),null)).setIconClass(getStringValue(item.get(this.getIconClassProp()),null))
.setLabel(getStringValue(item.get(this.getLabelProp()), getStringValue(item.get("text"),"")))
.setParent(getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),""))).setExtension(extension);
if(option.getValue().equals(subCode))
subOption=option;
if(StringUtils.isEmpty(filter)||option.getFilterSet().contains(filter)) {
alllist.add(option);
list.add(option);
}
}
if(subOption!=null)
{
List<CodeItem> codeItemTreeList = loop(map, (StringUtils.isEmpty(subCode))?"_root":subCode);
codeItemTreeList.add(0,subOption.setParent(null));
this.setOptions(codeItemTreeList);
}
else
this.setOptions(alllist);
return this;
}
private List<Map> unfoldList(List<Map> nodes, String parent)
{
List<Map> unfoldList = new ArrayList<>();
for(Map item:nodes)
{
if((!StringUtils.isEmpty(parent))&& StringUtils.isEmpty(getStringValue(item.get(this.getParentProp()), getStringValue(item.get("pvalue"),null))))
item.put(this.getParentProp(),parent);
String value = getStringValue(item.get(this.getValueProp()), getStringValue(item.get("id"),null));
unfoldList.add(item);
Object child=item.get(this.getChildrenProp());
if(!ObjectUtils.isEmpty(child))
{
if(child instanceof List && ((List) child).get(0) instanceof Map)
unfoldList.addAll(unfoldList((List)child,value));
item.remove(this.getChildrenProp());
}
}
return unfoldList;
}
private List<CodeItem> loop(Map<String, List<CodeItem>> listCodeItem, Object parentValue) {
List<CodeItem> trees = new ArrayList<CodeItem>();
if(listCodeItem.containsKey(parentValue)) {
for (CodeItem codeItem : listCodeItem.get(parentValue)) {
trees.add(codeItem);
List<CodeItem> childCodeItem = loop(listCodeItem, codeItem.getValue());
if (childCodeItem.size() > 0)
trees.addAll(childCodeItem);
}
}
return trees;
}
private String getSetting(String key,String defaultValue)
{
return advancedSettings!=null&&advancedSettings.get(key)!=null?advancedSettings.get(key).toString():defaultValue;
}
public static <V> V getValue(Object objValue,Class<V> clazz,Object defaultValue)
{
if(objValue==null) return defaultValue==null?null:(V)defaultValue;
return TypeUtils.castToJavaBean(objValue,clazz);
}
public static String getStringValue(Object objValue,String defaultValue)
{
return getValue(objValue,String.class,defaultValue);
}
public static Boolean getBooleanValue(Object objValue,Boolean defaultValue)
{
return getValue(objValue,Boolean.class,defaultValue);
}
}
package net.ibizsys.central.plugin.boot.core.dict;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Option
{
private String id;
private Object value;
private String label;
private List<Option> children;
private String iconClass;
private String filter;
private Boolean disabled;
@JsonIgnore
@JSONField(serialize = false)
private String parent;
private Map<String, Object> extension;
@JsonIgnore
@JSONField(serialize = false)
public Set<String> getFilterSet()
{
Set<String> set=new HashSet<>();
if(!StringUtils.isEmpty(filter))
for(String str:filter.split(";|,"))
set.add(str);
return set;
}
}
package net.ibizsys.central.plugin.boot.core.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
public class FileItem
{
private String id;
private String name;
private String fileid;
private String filename;
private long size;
private String ext;
}
package net.ibizsys.central.plugin.boot.core.errors;
import org.zalando.problem.AbstractThrowableProblem;
import org.zalando.problem.Status;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
public class BadRequestAlertException extends AbstractThrowableProblem {
private final String entityName;
private final String errorKey;
public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) {
this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey);
}
public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) {
super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey));
this.entityName = entityName;
this.errorKey = errorKey;
}
public String getEntityName() {
return entityName;
}
public String getErrorKey() {
return errorKey;
}
private static Map<String, Object> getAlertParameters(String entityName, String errorKey) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("message", "error." + errorKey);
parameters.put("params", entityName);
return parameters;
}
}
package net.ibizsys.central.plugin.boot.core.errors;
import org.zalando.problem.AbstractThrowableProblem;
import java.util.HashMap;
import java.util.Map;
import static org.zalando.problem.Status.BAD_REQUEST;
public class CustomParameterizedException extends AbstractThrowableProblem {
private static final long serialVersionUID = 1L;
private static final String PARAM = "param";
public CustomParameterizedException(String message, String... params) {
this(message, toParamMap(params));
}
public CustomParameterizedException(String message, Map<String, Object> paramMap) {
super(ErrorConstants.PARAMETERIZED_TYPE, "处理发生异常", BAD_REQUEST, null, null, null, toProblemParameters(message, paramMap));
}
public static Map<String, Object> toParamMap(String... params) {
Map<String, Object> paramMap = new HashMap<>();
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
paramMap.put(PARAM + i, params[i]);
}
}
return paramMap;
}
public static Map<String, Object> toProblemParameters(String message, Map<String, Object> paramMap) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("message", message);
parameters.put("params", paramMap);
return parameters;
}
}
package net.ibizsys.central.plugin.boot.core.errors;
import java.net.URI;
public final class ErrorConstants {
public static final String ERR_CONCURRENCY_FAILURE = "处理请求发生错误";
public static final String ERR_VALIDATION = "数据校验发生错误";
public static final String PROBLEM_BASE_URL = "";
public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message");
public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation");
public static final URI PARAMETERIZED_TYPE = URI.create(PROBLEM_BASE_URL + "/parameterized");
private ErrorConstants() {
}
}
package net.ibizsys.central.plugin.boot.core.errors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.zalando.problem.DefaultProblem;
import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;
import org.zalando.problem.spring.web.advice.validation.ConstraintViolationProblem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling {
@Override
public ResponseEntity<Problem> process(@Nullable ResponseEntity<Problem> entity, NativeWebRequest request) {
if (entity == null || entity.getBody() == null) {
return entity;
}
Problem problem = entity.getBody();
if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) {
return entity;
}
ProblemBuilder builder = Problem.builder()
.withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType())
.withStatus(problem.getStatus())
.withTitle(problem.getTitle())
.with("path", request.getNativeRequest(HttpServletRequest.class).getRequestURI());
if (problem instanceof ConstraintViolationProblem) {
builder
.with("violations", ((ConstraintViolationProblem) problem).getViolations())
.with("message", ErrorConstants.ERR_VALIDATION);
return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
} else {
builder
.withCause(((DefaultProblem) problem).getCause())
.withDetail(problem.getDetail())
.withInstance(problem.getInstance());
problem.getParameters().forEach(builder::with);
if (!problem.getParameters().containsKey("message") && problem.getStatus() != null) {
builder.with("message", "error.http." + problem.getStatus().getStatusCode());
}
return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
}
}
@Override
public ResponseEntity<Problem> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) {
BindingResult result = ex.getBindingResult();
List<FieldErrorVM> fieldErrors = result.getFieldErrors().stream()
.map(f -> new FieldErrorVM(f.getObjectName(), f.getField(), f.getDefaultMessage()))
.collect(Collectors.toList());
Problem problem = Problem.builder()
.withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE)
.withTitle(ErrorConstants.ERR_VALIDATION)
.withStatus(defaultConstraintViolationStatus())
.with("message", ErrorConstants.ERR_VALIDATION )
.with("fieldErrors", fieldErrors)
.build();
return create(ex, problem, request);
}
@ExceptionHandler(BadRequestAlertException.class)
public ResponseEntity<Problem> handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) {
return create(ex, request, createFailureAlert(ex.getEntityName(), ex.getErrorKey(), ex.getMessage()));
}
@ExceptionHandler(ConcurrencyFailureException.class)
public ResponseEntity<Problem> handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.withStatus(Status.CONFLICT)
.with("message", ErrorConstants.ERR_CONCURRENCY_FAILURE)
.build();
return create(ex, problem, request);
}
@ExceptionHandler(DataAccessException.class)
public ResponseEntity<Problem> handlerDataAccessFailure(DataAccessException ex, NativeWebRequest request){
Problem problem = Problem.builder()
.withStatus(Status.INTERNAL_SERVER_ERROR)
.with("message", ex.getMessage())
.build();
return create(ex, problem, request,createFailureAlert(ex.getClass().getSimpleName(), ex.getClass().getSimpleName(), ex.getMessage()));
}
public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) {
HttpHeaders headers = new HttpHeaders();
headers.add("X-ibz-error", errorKey);
headers.add("X-ibz-params", entityName);
return headers;
}
/**
* 上传文件大小超出限制异常
*/
@Value("${spring.servlet.multipart.max-file-size}")
private String maxFileSize;
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity<Problem> handlerMaxUploadFile(MaxUploadSizeExceededException ex, NativeWebRequest request){
Problem problem = Problem.builder()
.withStatus(Status.BAD_REQUEST)
.withDetail("上传文件不能大于"+maxFileSize)
.with("message", "上传文件不能大于"+maxFileSize)
.with("exmessage",""+ex.getMessage())
.build();
return create(ex, problem, request);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Problem> handlerTest(Exception ex, NativeWebRequest request){
Problem problem = Problem.builder()
.withStatus(Status.INTERNAL_SERVER_ERROR)
.withDetail("内部服务器异常")
.with("message", "内部服务器异常")
.with("exmessage",""+ex.getMessage())
.build();
return create(ex, problem, request);
}
}
package net.ibizsys.central.plugin.boot.core.errors;
import java.io.Serializable;
public class FieldErrorVM implements Serializable {
private static final long serialVersionUID = 1L;
private final String objectName;
private final String field;
private final String message;
public FieldErrorVM(String dto, String field, String message) {
this.objectName = dto;
this.field = field;
this.message = message;
}
public String getObjectName() {
return objectName;
}
public String getField() {
return field;
}
public String getMessage() {
return message;
}
}
package net.ibizsys.central.plugin.boot.core.errors;
import org.zalando.problem.AbstractThrowableProblem;
import org.zalando.problem.Status;
public class InternalServerErrorException extends AbstractThrowableProblem {
public InternalServerErrorException(String message) {
super(ErrorConstants.DEFAULT_TYPE, message, Status.INTERNAL_SERVER_ERROR);
}
}
package net.ibizsys.central.plugin.boot.core.helper;
import org.springframework.beans.BeanUtils;
public class CachedBeanCopier {
public static void copy(Object srcObj, Object destObj) {
copy(srcObj,destObj,false);
}
public static void copy(Object srcObj, Object destObj,boolean useConverter) {
if(srcObj==null||destObj==null) {
return;
}
BeanUtils.copyProperties(srcObj, destObj);
}
}
package net.ibizsys.central.plugin.boot.core.helper;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.util.TypeUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.central.plugin.boot.core.filter.BaseFilter;
import org.springframework.data.annotation.Id;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
/**
* 实体对象属性缓存类
*/
public class FieldCache {
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public static class FieldItem{
private String codeName;
private String fieldName;
private String columnName;
private String jsonName;
private String logicName;
private Field field;
}
private static Hashtable<String, Hashtable<String,FieldItem>> cacheMap = new Hashtable<>();
private static Hashtable<String, List<FieldItem>> cacheList = new Hashtable<>();
private static Hashtable<String, FieldItem> cacheDEKeyField = new Hashtable<>();
private static Object objLock1=new Object();
/**
* 将实体对象中的属性存入缓存中
* @param
* @return
*/
public static <T> Hashtable<String,FieldItem> getFieldMap(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0) {
className=className.substring(0, className.lastIndexOf("_$"));
}
if(cacheMap.containsKey(className)) {
return cacheMap.get(className);
}
synchronized (objLock1) {
if(cacheMap.containsKey(className)) {
return cacheMap.get(className);
}
Hashtable<String,FieldItem> result = new Hashtable<String,FieldItem>();
List<FieldItem> list = new ArrayList<>();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
FieldItem item=new FieldItem().setCodeName(field.getName()).setFieldName(field.getName()).setColumnName(field.getName()).setJsonName(field.getName()).setLogicName(field.getName()).setField(field);
JSONField jsField=field.getAnnotation(JSONField.class);
if(!ObjectUtils.isEmpty(jsField)) {
if(!StringUtils.isEmpty(jsField.name()))
item.setJsonName(jsField.name());
}
else
{
JsonProperty jsonProperty=field.getAnnotation(JsonProperty.class);
if((!ObjectUtils.isEmpty(jsonProperty))&&(!StringUtils.isEmpty(jsonProperty.value())))
item.setJsonName(jsonProperty.value());
}
ApiModelProperty apiModelProperty=field.getAnnotation(ApiModelProperty.class);
if(!ObjectUtils.isEmpty(apiModelProperty)) {
if(!StringUtils.isEmpty(apiModelProperty.value()))
item.setFieldName(apiModelProperty.value()).setColumnName(apiModelProperty.value());
if(!StringUtils.isEmpty(apiModelProperty.notes()))
item.setLogicName(apiModelProperty.notes());
}
if(!cacheDEKeyField.containsKey(className))
{
if(!ObjectUtils.isEmpty(field.getAnnotation(Id.class)))
cacheDEKeyField.put(className,item);
}
list.add(item);
result.put(item.getCodeName(),item);
result.put(item.getFieldName(),item);
result.put(item.getColumnName(),item);
result.put(item.getJsonName(),item);
result.put(item.getCodeName().toLowerCase(),item);
result.put(item.getFieldName().toLowerCase(),item);
result.put(item.getColumnName().toLowerCase(),item);
result.put(item.getJsonName().toLowerCase(),item);
}
cacheMap.put(className, result);
cacheList.put(className,list);
return result;
}
}
public static Hashtable<String,FieldItem> getFieldMap(String className) {
if(className.indexOf("_$")>0) {
className=className.substring(0, className.lastIndexOf("_$"));
}
if(cacheMap.containsKey(className)) {
return cacheMap.get(className);
}
Class clazz = null;
try {
clazz = Class.forName(className);
return getFieldMap(clazz);
}
catch (Exception ex) {
cacheMap.put(className, new Hashtable<String,FieldItem>());
return cacheMap.get(className);
}
}
/**
* 从缓存中查询实体对象主键
* @param
* @return
*/
public static <T> String getKeyField(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0) {
className=className.substring(0, className.lastIndexOf("_$"));
}
getFieldMap(className);
if(cacheDEKeyField.containsKey(className)) {
return cacheDEKeyField.get(className).getCodeName();
}
return "";
}
public static <T> String getFieldRealName(Class<T> clazz,String fieldname) {
FieldItem field=getField(clazz,fieldname);
if(field!=null) {
return field.getCodeName();
}
return "";
}
public static <T> FieldItem getField(Class<T> clazz,String fieldname) {
Hashtable<String,FieldItem> fields= getFieldMap(clazz);
if(fields.containsKey(fieldname)) {
return fields.get(fieldname);
}
else if(fields.containsKey(fieldname.toLowerCase())) {
return fields.get(fieldname.toLowerCase());
}
else if(fields.containsKey(fieldname.toLowerCase().replace("_",""))) {
return fields.get(fieldname.toLowerCase().replace("_",""));
}
else {
return null;
}
}
public static <T> Object fieldValueOf(Class<T> clazz,String fieldname,Object fieldValue) {
if(fieldValue==null)
return null;
Object resultValue=fieldValue;
FieldItem item=getField(clazz,fieldname);
if(item!=null) {
Class<?> type=item.getField().getType();
resultValue = TypeUtils.castToJavaBean(fieldValue,type);
}
return resultValue;
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.helper;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* 单复数转换类
* 2018年12月30日
*/
public class Inflector {
private static final Pattern UNDERSCORE_PATTERN_1 = Pattern.compile("([A-Z]+)([A-Z][a-z])");
private static final Pattern UNDERSCORE_PATTERN_2 = Pattern.compile("([a-z\\d])([A-Z])");
private static List<RuleAndReplacement> plurals = new ArrayList<RuleAndReplacement>();
private static List<RuleAndReplacement> singulars = new ArrayList<RuleAndReplacement>();
private static List<String> uncountables = new ArrayList<String>();
private static Inflector instance;
private Inflector() {
initialize();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// 单数转复数
System.out.println(Inflector.getInstance().pluralize("water"));
System.out.println(Inflector.getInstance().pluralize("box"));
System.out.println(Inflector.getInstance().pluralize("tomato"));
// 复数转单数
System.out.println(Inflector.getInstance().singularize("apples"));
}
private void initialize() {
plural("$", "s");
plural("s$", "s");
plural("(ax|test)is$", "$1es");
plural("(octop|vir)us$", "$1i");
plural("(alias|status)$", "$1es");
plural("(bu)s$", "$1es");
plural("(buffal|tomat)o$", "$1oes");
plural("([ti])um$", "$1a");
plural("sis$", "ses");
plural("(?:([^f])fe|([lr])f)$", "$1$2ves");
plural("(hive)$", "$1s");
plural("([^aeiouy]|qu)y$", "$1ies");
plural("([^aeiouy]|qu)ies$", "$1y");
plural("(x|ch|ss|sh)$", "$1es");
plural("(matr|vert|ind)ix|ex$", "$1ices");
plural("([m|l])ouse$", "$1ice");
plural("(ox)$", "$1es");
plural("(quiz)$", "$1zes");
singular("s$", "");
singular("(n)ews$", "$1ews");
singular("([ti])a$", "$1um");
singular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
singular("(^analy)ses$", "$1sis");
singular("([^f])ves$", "$1fe");
singular("(hive)s$", "$1");
singular("(tive)s$", "$1");
singular("([lr])ves$", "$1f");
singular("([^aeiouy]|qu)ies$", "$1y");
singular("(s)eries$", "$1eries");
singular("(m)ovies$", "$1ovie");
singular("(x|ch|ss|sh)es$", "$1");
singular("([m|l])ice$", "$1ouse");
singular("(bus)es$", "$1");
singular("(o)es$", "$1");
singular("(shoe)s$", "$1");
singular("(cris|ax|test)es$", "$1is");
singular("([octop|vir])i$", "$1us");
singular("(alias|status)es$", "$1");
singular("^(ox)es", "$1");
singular("(vert|ind)ices$", "$1ex");
singular("(matr)ices$", "$1ix");
singular("(quiz)zes$", "$1");
irregular("person", "people");
irregular("man", "men");
irregular("child", "children");
irregular("sex", "sexes");
irregular("move", "moves");
uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep" });
}
public static Inflector getInstance() {
if (instance == null) {
instance = new Inflector();
}
return instance;
}
public String underscore(String camelCasedWord) {
String underscoredWord = UNDERSCORE_PATTERN_1.matcher(camelCasedWord).replaceAll("$1_$2");
underscoredWord = UNDERSCORE_PATTERN_2.matcher(underscoredWord).replaceAll("$1_$2");
underscoredWord = underscoredWord.replace('-', '_').toLowerCase();
return underscoredWord;
}
public String pluralize(String word) {
if (uncountables.contains(word.toLowerCase())) {
return word;
}
return replaceWithFirstRule(word, plurals);
}
public String singularize(String word) {
if (uncountables.contains(word.toLowerCase())) {
return word;
}
return replaceWithFirstRule(word, singulars);
}
private String replaceWithFirstRule(String word, List<RuleAndReplacement> ruleAndReplacements) {
for (RuleAndReplacement rar : ruleAndReplacements) {
String rule = rar.getRule();
String replacement = rar.getReplacement();
// Return if we find a match.
Matcher matcher = Pattern.compile(rule, Pattern.CASE_INSENSITIVE).matcher(word);
if (matcher.find()) {
return matcher.replaceAll(replacement);
}
}
return word;
}
public String tableize(String className) {
return pluralize(underscore(className));
}
public String tableize(Class<?> klass) {
String className = klass.getName().replace(klass.getPackage().getName() + ".", "");
return tableize(className);
}
public static void plural(String rule, String replacement) {
plurals.add(0, new RuleAndReplacement(rule, replacement));
}
public static void singular(String rule, String replacement) {
singulars.add(0, new RuleAndReplacement(rule, replacement));
}
public static void irregular(String singular, String plural) {
plural(singular, plural);
singular(plural, singular);
}
public static void uncountable(String... words) {
for (String word : words) {
uncountables.add(word);
}
}
}
class RuleAndReplacement {
private String rule;
private String replacement;
public RuleAndReplacement(String rule, String replacement) {
this.rule = rule;
this.replacement = replacement;
}
public String getReplacement() {
return replacement;
}
public void setReplacement(String replacement) {
this.replacement = replacement;
}
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule;
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.helper;
import org.springframework.core.convert.converter.Converter;
import java.sql.Timestamp;
import java.time.*;
import java.util.Date;
/**
* <p>JSR310DateConverters class.</p>
*/
public final class JSR310DateConverters {
private JSR310DateConverters() {
}
public static class TimestampToDateConverter implements Converter<Timestamp, Date> {
public static final TimestampToDateConverter INSTANCE = new TimestampToDateConverter();
private TimestampToDateConverter() {
}
@Override
public Date convert(Timestamp source) {
return source == null ? null : new Date(source.getTime());
}
}
public static class DateToTimestampConverter implements Converter<Date, Timestamp> {
public static final DateToTimestampConverter INSTANCE = new DateToTimestampConverter();
private DateToTimestampConverter() {
}
@Override
public Timestamp convert(Date source) {
return source == null ? null : new Timestamp(source.getTime());
}
}
public static class LocalDateToDateConverter implements Converter<LocalDate, Date> {
public static final LocalDateToDateConverter INSTANCE = new LocalDateToDateConverter();
private LocalDateToDateConverter() {
}
@Override
public Date convert(LocalDate source) {
return source == null ? null : Date.from(source.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
}
public static class DateToLocalDateConverter implements Converter<Date, LocalDate> {
public static final DateToLocalDateConverter INSTANCE = new DateToLocalDateConverter();
private DateToLocalDateConverter() {
}
@Override
public LocalDate convert(Date source) {
return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault())
.toLocalDate();
}
}
public static class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
public static final ZonedDateTimeToDateConverter INSTANCE = new ZonedDateTimeToDateConverter();
private ZonedDateTimeToDateConverter() {
}
@Override
public Date convert(ZonedDateTime source) {
return source == null ? null : Date.from(source.toInstant());
}
}
public static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
public static final DateToZonedDateTimeConverter INSTANCE = new DateToZonedDateTimeConverter();
private DateToZonedDateTimeConverter() {
}
@Override
public ZonedDateTime convert(Date source) {
return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
public static class LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
public static final LocalDateTimeToDateConverter INSTANCE = new LocalDateTimeToDateConverter();
private LocalDateTimeToDateConverter() {
}
@Override
public Date convert(LocalDateTime source) {
return source == null ? null : Date.from(source.atZone(ZoneId.systemDefault()).toInstant());
}
}
public static class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
public static final DateToLocalDateTimeConverter INSTANCE = new DateToLocalDateTimeConverter();
private DateToLocalDateTimeConverter() {
}
@Override
public LocalDateTime convert(Date source) {
return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
public static class DurationToLongConverter implements Converter<Duration, Long> {
public static final DurationToLongConverter INSTANCE = new DurationToLongConverter();
private DurationToLongConverter() {
}
@Override
public Long convert(Duration source) {
return source == null ? null : source.toNanos();
}
}
public static class LongToDurationConverter implements Converter<Long, Duration> {
public static final LongToDurationConverter INSTANCE = new LongToDurationConverter();
private LongToDurationConverter() {
}
@Override
public Duration convert(Long source) {
return source == null ? null : Duration.ofNanos(source);
}
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.helper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import net.ibizsys.central.dataentity.IDataEntityRuntime;
import net.ibizsys.central.dataentity.ds.IDEDataQueryCodeRuntime;
import net.ibizsys.central.plugin.boot.core.filter.BaseFilter;
import net.ibizsys.central.util.ISearchContext;
import net.ibizsys.model.dataentity.defield.IPSDEField;
import net.ibizsys.model.dataentity.ds.IPSDEDataQueryCodeExp;
import net.ibizsys.runtime.dataentity.defield.DEFTypes;
import net.ibizsys.runtime.security.UserContext;
import net.ibizsys.runtime.util.*;
import org.springframework.util.ObjectUtils;
import java.util.List;
import java.util.function.Consumer;
public class QueryHelper {
public static <T> QueryWrapper<T> getQueryWrapper(BaseFilter filter)
{
QueryWrapper query=Wrappers.query();
calcSearchCondItems(query,Conditions.AND,filter.getSearchConds());
return query;
}
protected static <T> void calcSearchCondItems(QueryWrapper<T> query, String groupMode, List<ISearchCond> items) {
int i = 0;
for (ISearchCond iSearchCond : items) {
if (i > 0) {
if (groupMode.equals(Conditions.OR)) {
query.or();
}
}
switch (iSearchCond.getCondType()) {
case ISearchCond.CONDTYPE_GROUP:
searchCondGroup((ISearchGroupCond) iSearchCond,query);
break;
case ISearchCond.CONDTYPE_DEFIELD:
searchDEField((ISearchFieldCond) iSearchCond,query);
break;
case ISearchCond.CONDTYPE_CUSTOM:
query.apply(((ISearchCustomCond) iSearchCond).getCustomCond());
break;
}
i++;
}
}
protected static <T> void searchCondGroup(ISearchGroupCond cond,QueryWrapper<T> query) {
List<ISearchCond> items = cond.getSearchConds();
if (!ObjectUtils.isEmpty(items)) {
query.and(new Consumer<QueryWrapper<T>>() {
@Override
public void accept(QueryWrapper<T> objectQueryWrapper) {
switch (cond.getCondOp()) {
case Conditions.AND:
objectQueryWrapper.and(new Consumer<QueryWrapper<T>>() {
@Override
public void accept(QueryWrapper<T> subQuery) {
calcSearchCondItems(subQuery, Conditions.AND, items);
}
});
break;
case Conditions.OR:
objectQueryWrapper.or(new Consumer<QueryWrapper<T>>() {
@Override
public void accept(QueryWrapper<T> subQuery) {
calcSearchCondItems(subQuery, Conditions.OR, items);
}
});
break;
}
}
});
}
}
protected static <T> void searchDEField(ISearchFieldCond cond,QueryWrapper<T> query) {
String column = cond.getFieldName();
Object val = cond.getValue();
switch (cond.getCondOp()) {
// 等于
case Conditions.EQ:
query.eq(column, val);
break;
// 不等于
case Conditions.NOTEQ:
query.ne(column, val);
break;
// 大于
case Conditions.GT:
query.gt(column, val);
break;
// 大于等于
case Conditions.GTANDEQ:
query.ge(column, val);
break;
// 小于
case Conditions.LT:
query.lt(column, val);
break;
// 小于等于
case Conditions.LTANDEQ:
query.le(column, val);
break;
// 为空
case Conditions.ISNULL:
query.isNull(column);
break;
// 不为空
case Conditions.ISNOTNULL:
query.isNotNull(column);
break;
// 文本包含
case Conditions.LIKE:
case Conditions.USERLIKE:
query.like(column, val);
break;
// 值在范围中
case Conditions.IN:
query.in(column, val);
break;
// 值不在范围中
case Conditions.NOTIN:
query.notIn(column, val);
break;
// 文本左包含
case Conditions.LEFTLIKE:
query.likeRight(column, val);
break;
// 文本右包含
case Conditions.RIGHTLIKE:
query.likeLeft(column, val);
break;
}
}
}
package net.ibizsys.central.plugin.boot.core.helper;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextHolder implements ApplicationContextAware
{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
assertApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
assertApplicationContext();
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> requiredType) {
assertApplicationContext();
return applicationContext.getBean(requiredType);
}
private static void assertApplicationContext() {
if (SpringContextHolder.applicationContext == null) {
throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
}
}
}
\ No newline at end of file
package net.ibizsys.central.plugin.boot.core.helper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
@Slf4j
public class UniqueNameGenerator extends AnnotationBeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
//全限定类名
String beanName = definition.getBeanClassName();
return beanName;
}
}
package net.ibizsys.central.plugin.boot.core.runtime;
import net.ibizsys.central.SystemGateway;
import net.ibizsys.central.database.ISysDBSchemeRuntime;
import net.ibizsys.central.database.SysDBSchemeRuntime;
import net.ibizsys.central.dataentity.DataEntityRuntime;
import net.ibizsys.central.dataentity.IDataEntityRuntime;
import net.ibizsys.central.dataentity.service.IDEService;
import net.ibizsys.model.IPSSystemService;
import net.ibizsys.model.PSModelServiceImpl;
import net.ibizsys.model.dataentity.IPSDataEntity;
import org.springframework.context.annotation.Primary;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class BootSystemRuntime extends net.ibizsys.central.cloud.core.ServiceSystemRuntime implements IBootSystemRuntime {
private static IBootSystemRuntime instance = null;
public static IBootSystemRuntime getInstance() {
return getInstance(false);
}
private static Map<String, IBootService> localDEServiceMap = new ConcurrentHashMap();
public static synchronized void addLocalDEServiceMap(String dataEntityid,IBootService service)
{
if(localDEServiceMap.containsKey(dataEntityid)&&service.getBaseService().getClass().getAnnotation(Primary.class)==null)
return;
localDEServiceMap.put(dataEntityid,service);
}
public static IBootSystemRuntime getInstance(boolean bTryMode) {
if(BootSystemRuntime.instance != null || bTryMode) {
return BootSystemRuntime.instance;
}
throw new RuntimeException("核心系统运行时实例不存在");
}
public static void setInstance(IBootSystemRuntime instance) {
BootSystemRuntime.instance = instance;
}
@Override
protected void onStart() throws Exception {
super.onStart();
if(getInstance(true) == null) {
setInstance(this);
}
}
@Override
public IDEService getDEService(IDataEntityRuntime iDataEntityRuntime) {
IBootService service= localDEServiceMap.get(iDataEntityRuntime.getId());
if(service==null)
return super.getDEService(iDataEntityRuntime);
if(service.getSystemRuntime()==null)
service.setSystemRuntime(this);
return service;
}
public boolean isEnableDEService(IPSDataEntity iPSDataEntity) {
return this.localDEServiceMap.containsKey(iPSDataEntity.getId());
}
@Override
protected IDataEntityRuntime createDefaultDataEntityRuntime() {
return new DataEntityRuntime();
}
@Override
protected ISysDBSchemeRuntime createDefaultSysDBSchemeRuntime() {
return new SysDBSchemeRuntime();
}
@Override
public String getName() {
return "iBizBoot";
}
@Override
public void registerDEServiceObj(String strDataEntityId, String strDEServiceObj) {
super.registerDEServiceObj(strDataEntityId,strDEServiceObj);
}
}
package net.ibizsys.central.plugin.boot.core.runtime;
import net.ibizsys.central.dataentity.IDataEntityRuntimeContext;
import net.ibizsys.central.dataentity.service.IDEService;
import net.ibizsys.central.plugin.boot.core.domain.BaseData;
import net.ibizsys.central.plugin.boot.core.filter.BaseFilter;
import net.ibizsys.central.plugin.boot.core.helper.StringAdvUtils;
import net.ibizsys.central.plugin.boot.core.service.IBaseService;
import net.ibizsys.central.util.EntityDTO;
import net.ibizsys.central.util.IEntityDTO;
import net.ibizsys.central.util.ISearchContextDTO;
import net.ibizsys.central.util.SearchContextDTO;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.model.dataentity.ds.IPSDEDataSet;
import net.ibizsys.model.dataentity.service.IPSDEMethodDTO;
import org.springframework.util.Assert;
import java.lang.reflect.*;
public interface IBootService<T extends BaseData, F extends BaseFilter> extends IDEService {
IBootSystemRuntime getSystemRuntime();
void setSystemRuntime(IBootSystemRuntime systemRuntime);
IBaseService getBaseService();
default IDataEntityRuntimeContext getDataEntityRuntimeContext() {
return null;
}
default void setDataEntityRuntimeContext(IDataEntityRuntimeContext dataEntityRuntimeContext) { }
}
package net.ibizsys.central.plugin.boot.core.runtime;
public interface IBootSystemRuntime extends net.ibizsys.central.cloud.core.IServiceSystemRuntime {
default void registerDEServiceObj(String strDataEntityId, String strDEServiceObj) {
}
}
package net.ibizsys.central.plugin.boot.core.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.ibizsys.central.dataentity.IDataEntityRuntime;
import net.ibizsys.central.dataentity.IDataEntityRuntimeContext;
import net.ibizsys.central.plugin.boot.core.domain.BaseData;
import net.ibizsys.central.plugin.boot.core.filter.BaseFilter;
import net.ibizsys.central.plugin.boot.core.runtime.IBootService;
import net.ibizsys.central.plugin.boot.core.runtime.IBootSystemRuntime;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.model.dataentity.ds.IPSDEDataSet;
import org.springframework.data.domain.Page;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public interface IMPService<T extends BaseData, F extends BaseFilter, M extends BaseMapper<T>> extends IBaseService<T,F>{
default M getBaseMapper(){
return null;
}
default List<T> list(QueryWrapper<T> queryWrapper) {
return this.getBaseMapper().selectList(queryWrapper);
}
default Integer count(QueryWrapper<T> queryWrapper) {
return this.getBaseMapper().selectCount(queryWrapper);
}
default T getOne(QueryWrapper<T> queryWrapper) {
return this.getBaseMapper().selectOne(queryWrapper);
}
default <K extends Serializable> T getById(K key) {
return this.getBaseMapper().selectById(key);
}
}
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册