Merge remote-tracking branch 'origin/develop' into wh/expression_utils

# Conflicts:
#	pom.xml
#	spring-boot-nebula-dependencies/pom.xml
#	spring-boot-nebula-web-common/src/main/java/com/nebula/web/common/utils/ExpressionUtil.java
This commit is contained in:
weihu 2024-06-01 22:19:49 +08:00
commit 3349fa1a44
89 changed files with 3203 additions and 1883 deletions

View File

@ -4,9 +4,11 @@ on:
push:
branches:
- master
- develop
pull_request:
branches:
- master
- develop
jobs:
junit:

View File

@ -0,0 +1,17 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<profiles version="13">
<profile kind="CodeFormatterProfile" name="'ShardingSphere Apache Current'" version="13">
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8" />
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8" />
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8" />
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="true" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4" />
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200" />
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space" />
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="1" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false" />
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1" />
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="160" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="10" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="106" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="106" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="106" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent" value="16|5|80" />
</profile>
</profiles>

141
pom.xml
View File

@ -1,13 +1,15 @@
<?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"
<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>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula</artifactId>
<packaging>pom</packaging>
<version>${revision}</version>
<packaging>pom</packaging>
<name>spring-boot-nebula</name>
<description>spring-boot-common</description>
<modules>
<module>spring-boot-nebula-web</module>
@ -22,29 +24,15 @@
<module>spring-boot-nebula-all</module>
</modules>
<name>spring-boot-nebula</name>
<description>spring-boot-common</description>
<url>https://github.com/weihubeats/spring-boot-common</url>
<properties>
<revision>0.0.01</revision>
<flatten-maven-plugin.version>1.2.7</flatten-maven-plugin.version>
<maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
@ -57,35 +45,6 @@
</dependencies>
</dependencyManagement>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>weihubeats</name>
<email>weihu@apche.org</email>
<organization>https://weihubeats.blog.csdn.net/</organization>
</developer>
</developers>
<scm>
<connection>scm:git@github.com:weihubeats/spring-boot-common.git</connection>
<developerConnection>scm:git@github.com:weihubeats/spring-boot-common.git</developerConnection>
<url>git@github.com:weihubeats/spring-boot-common.git</url>
</scm>
<issueManagement>
<system>Github Issue</system>
<url>https://github.com/weihubeats/spring-boot-common/issues</url>
</issueManagement>
<build>
<plugins>
<plugin>
@ -118,10 +77,10 @@
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
@ -143,10 +102,10 @@
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
@ -158,10 +117,10 @@
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
@ -177,32 +136,100 @@
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
<phase>process-resources</phase>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
<phase>clean</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless-maven-plugin.version}</version>
<configuration>
<java>
<eclipse>
<file>${maven.multiModuleProjectDirectory}/dev-support/spotless_nebula_formatter.xml</file>
</eclipse>
<licenseHeader>
<file>${maven.multiModuleProjectDirectory}/dev-support/license-header</file>
</licenseHeader>
</java>
<pom>
<sortPom>
<encoding>UTF-8</encoding>
<nrOfIndentSpace>4</nrOfIndentSpace>
<keepBlankLines>true</keepBlankLines>
<indentBlankLines>false</indentBlankLines>
<indentSchemaLocation>true</indentSchemaLocation>
<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>
<sortModules>false</sortModules>
<sortExecutions>false</sortExecutions>
<predefinedSortOrder>custom_1</predefinedSortOrder>
<expandEmptyElements>false</expandEmptyElements>
<sortProperties>false</sortProperties>
</sortPom>
</pom>
</configuration>
<executions>
<execution>
<goals>
<goal>apply</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
<url>https://github.com/weihubeats/spring-boot-common</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>weihubeats</name>
<email>weihu@apche.org</email>
<organization>https://weihubeats.blog.csdn.net/</organization>
</developer>
</developers>
<scm>
<connection>scm:git@github.com:weihubeats/spring-boot-common.git</connection>
<developerConnection>scm:git@github.com:weihubeats/spring-boot-common.git</developerConnection>
<url>git@github.com:weihubeats/spring-boot-common.git</url>
</scm>
<issueManagement>
<system>Github Issue</system>
<url>https://github.com/weihubeats/spring-boot-common/issues</url>
</issueManagement>
<distributionManagement>
<snapshotRepository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
</project>

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -10,7 +9,6 @@
</parent>
<artifactId>spring-boot-nebula-aggregate</artifactId>
<dependencies>
@ -36,4 +34,4 @@
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.annotation;
import java.lang.annotation.Documented;

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.annotation;
import java.lang.annotation.Documented;

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.annotation;
import com.nebula.aggregate.core.AbstractOldObj;
@ -17,17 +34,17 @@ import org.springframework.stereotype.Component;
@Slf4j
@Component
public class CreateOldObjAspect {
@AfterReturning(pointcut = "@annotation(com.nebula.aggregate.annotation.AggregateCreate) || " +
"@annotation(com.nebula.aggregate.annotation.CreateOldObj)", returning = "returnVal")
"@annotation(com.nebula.aggregate.annotation.CreateOldObj)", returning = "returnVal")
public void handleRequestMethod(JoinPoint pjp, Object returnVal) {
if (returnVal instanceof AbstractOldObj) {
((AbstractOldObj) returnVal).setOldObject(copy(returnVal));
}
}
public Object copy(Object oldObject) {
return JsonUtil.json2JavaBean(JsonUtil.toJSONString(oldObject), oldObject.getClass());
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.core;
/**
@ -7,4 +24,3 @@ package com.nebula.aggregate.core;
*/
public abstract class AbstractAggregate<T> extends AbstractOldObj<T> {
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.core;
import org.javers.core.metamodel.annotation.DiffIgnore;
@ -8,17 +25,16 @@ import org.javers.core.metamodel.annotation.DiffIgnore;
* @description:
*/
public abstract class AbstractOldObj<T> {
@DiffIgnore
private T oldObject;
public void setOldObject(T oldObject) {
this.oldObject = oldObject;
}
public T getOld() {
return oldObject;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aggregate.core;
import com.google.common.collect.Lists;
@ -41,17 +58,17 @@ import org.javers.core.metamodel.annotation.Id;
*/
@Slf4j
public class AggregateDiff {
private static final ConcurrentHashMap<String, List<String>> PROPERTIES_CACHE = new ConcurrentHashMap<>();
private static final Javers javers = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE).build();
private final Diff diff;
public AggregateDiff(Object oldVersion, Object currentVersion) {
this.diff = javers.compare(oldVersion, currentVersion);
}
/**
* 构建diff
*
@ -61,15 +78,15 @@ public class AggregateDiff {
public <T extends AbstractAggregate<T>> AggregateDiff(T currentVersion) {
this.diff = javers.compare(currentVersion.getOld(), currentVersion);
}
public boolean hasChanges() {
return diff.hasChanges();
}
public boolean propertyHasChange(String propertyName) {
return propertyHasChange(Lists.newArrayList(propertyName));
}
/**
* 判断两个对象是否有变化
* <p>
@ -79,7 +96,7 @@ public class AggregateDiff {
Diff objectDiff = javers.compare(oldObject, newObject);
return !objectDiff.getChanges().isEmpty();
}
/**
* 判断对象里面的属性值是否发生了变化,list需要单独判断,对象也需要单独判断
*
@ -89,7 +106,7 @@ public class AggregateDiff {
public boolean propertyHasChange(List<String> propertyNameList) {
return propertyNameList.stream().anyMatch(s -> !diff.getPropertyChanges(s).isEmpty());
}
/**
* 判断对象里面的属性值是否发生了变化
*
@ -102,7 +119,7 @@ public class AggregateDiff {
public final <T, R> boolean propertyHasChange(PropertyFunc<T, R>... function) {
return Arrays.stream(function).anyMatch(s -> !diff.getPropertyChanges(ReflectionUtils.getFieldName(s)).isEmpty());
}
/**
* 对象变化
*
@ -112,9 +129,9 @@ public class AggregateDiff {
* @param <T>
*/
public <T> void objectChangeFunction(Consumer<T> addConsume,
Consumer<T> updateConsume,
Consumer<T> deleteConsume,
Class<T> clazz) {
Consumer<T> updateConsume,
Consumer<T> deleteConsume,
Class<T> clazz) {
Changes changes = this.diff.getChanges();
for (Change change : changes) {
if ((change instanceof NewObject && Objects.nonNull(addConsume))) {
@ -131,7 +148,7 @@ public class AggregateDiff {
}
}
}
/**
* @param oldList 旧list
* @param newList 新list
@ -143,27 +160,27 @@ public class AggregateDiff {
*/
@SuppressWarnings("unchecked")
public static <T> void listChangeFunction(List<T> oldList,
List<T> newList,
Class<T> clazz,
Consumer<List<T>> addConsume,
Consumer<List<T>> updateConsume,
Consumer<List<T>> removeConsume) {
List<T> newList,
Class<T> clazz,
Consumer<List<T>> addConsume,
Consumer<List<T>> updateConsume,
Consumer<List<T>> removeConsume) {
initNegativeId(clazz, newList);
Diff listDiff = javers.compareCollections(oldList, newList, clazz);
Map<String, T> addMap = new HashMap<>();
Map<String, T> removeMap = new HashMap<>();
Map<String, T> updateMap = new HashMap<>();
for (Change change : listDiff.getChanges()) {
if ((change instanceof NewObject)) {
addMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
}
if ((change instanceof ObjectRemoved)) {
removeMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
}
if ((change instanceof PropertyChange)) {
if (change.getAffectedLocalId() != null) {
updateMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
@ -180,7 +197,7 @@ public class AggregateDiff {
removeConsume.accept((new ArrayList<>(removeMap.values())));
}
}
/**
* id初始化负数
*
@ -199,11 +216,11 @@ public class AggregateDiff {
}
}
}
public static <T> void initNegativeId(Class<T> clazz, Collection<T> list) {
initNegativeId(clazz, list, "id");
}
/**
* map 里面的key @id 的值,需要用到long类型 需要自己强转
*
@ -217,27 +234,27 @@ public class AggregateDiff {
*/
@SuppressWarnings("unchecked")
public static <T> void collectionChangeFunction(Collection<T> oldList,
Collection<T> newList,
Class<T> clazz,
Consumer<Map<String, T>> addConsume,
Consumer<Map<String, T>> updateConsume,
Consumer<Map<String, T>> removeConsume) {
Collection<T> newList,
Class<T> clazz,
Consumer<Map<String, T>> addConsume,
Consumer<Map<String, T>> updateConsume,
Consumer<Map<String, T>> removeConsume) {
Diff listDiff = javers.compareCollections(oldList, newList, clazz);
Map<String, T> addMap = new HashMap<>();
Map<String, T> removeMap = new HashMap<>();
Map<String, T> updateMap = new HashMap<>();
for (Change change : listDiff.getChanges()) {
if ((change instanceof NewObject)) {
addMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
}
if ((change instanceof ObjectRemoved)) {
removeMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
}
if ((change instanceof PropertyChange)) {
if (change.getAffectedLocalId() != null) {
updateMap.put(change.getAffectedLocalId().toString(), (T) change.getAffectedObject().get());
@ -254,7 +271,7 @@ public class AggregateDiff {
removeConsume.accept(removeMap);
}
}
/**
* 获取需要比较的简单属性
*
@ -283,7 +300,7 @@ public class AggregateDiff {
return properties;
});
}
/**
* 用于Long和Integer类型的比较
*
@ -291,16 +308,16 @@ public class AggregateDiff {
*/
@SuppressWarnings("unchecked")
public static <T> void simpleListChangeFunction(Collection<T> oldList,
Collection<T> newList,
Class<T> clazz,
Consumer<List<T>> addConsume,
Consumer<List<T>> removeConsume) {
Collection<T> newList,
Class<T> clazz,
Consumer<List<T>> addConsume,
Consumer<List<T>> removeConsume) {
Diff listDiff = javers.compareCollections(oldList, newList, clazz);
List<T> addList = new ArrayList<>();
List<T> removeList = new ArrayList<>();
for (Change change : listDiff.getChanges()) {
if (change instanceof ListChange && change.getAffectedLocalId() == null) {
for (ContainerElementChange containerElementChange : ((ListChange) change).getChanges()) {

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -16,13 +15,13 @@
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula-web</artifactId>
</dependency>
<dependency>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula-web</artifactId>
</dependency>
<dependency>
<groupId>io.github.weihubeats</groupId>
@ -33,9 +32,7 @@
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula-distribute-lock</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -16,9 +15,9 @@
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -35,4 +34,4 @@
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.aop.base;
import lombok.NonNull;
@ -27,72 +44,73 @@ import java.lang.reflect.Proxy;
* @description:
*/
public class NebulaBaseAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
private final Advice advice;
private final Pointcut pointcut;
private final Class<? extends Annotation> annotation;
public NebulaBaseAnnotationAdvisor(@NonNull MethodInterceptor advice,
@NonNull Class<? extends Annotation> annotation) {
@NonNull Class<? extends Annotation> annotation) {
this.advice = advice;
this.annotation = annotation;
this.pointcut = buildPointcut();
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public Advice getAdvice() {
return this.advice;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.advice instanceof BeanFactoryAware) {
((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
}
}
private Pointcut buildPointcut() {
Pointcut cpc = new AnnotationMatchingPointcut(annotation, true);
Pointcut mpc = new AnnotationMethodPoint(annotation);
return new ComposablePointcut(cpc).union(mpc);
}
/**
* In order to be compatible with the spring lower than 5.0
*/
private static class AnnotationMethodPoint implements Pointcut {
private final Class<? extends Annotation> annotationType;
public AnnotationMethodPoint(Class<? extends Annotation> annotationType) {
Assert.notNull(annotationType, "Annotation type must not be null");
this.annotationType = annotationType;
}
@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
@Override
public MethodMatcher getMethodMatcher() {
return new AnnotationMethodMatcher(annotationType);
}
private static class AnnotationMethodMatcher extends StaticMethodMatcher {
private final Class<? extends Annotation> annotationType;
public AnnotationMethodMatcher(Class<? extends Annotation> annotationType) {
this.annotationType = annotationType;
}
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (matchesMethod(method)) {
@ -106,7 +124,7 @@ public class NebulaBaseAnnotationAdvisor extends AbstractPointcutAdvisor impleme
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
return (specificMethod != method && matchesMethod(specificMethod));
}
private boolean matchesMethod(Method method) {
return AnnotatedElementUtils.hasAnnotation(method, this.annotationType);
}

View File

@ -1,17 +1,15 @@
<?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"
<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>
<artifactId>spring-boot-nebula</artifactId>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-nebula-common</artifactId>
<dependencies>
<dependency>
@ -29,17 +27,17 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
@ -50,12 +48,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
@ -66,8 +64,6 @@
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.exception;
import java.io.PrintWriter;
@ -11,7 +28,7 @@ import java.lang.reflect.UndeclaredThrowableException;
* @description:
*/
public class ExceptionUtil {
public static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw)) {
@ -19,7 +36,7 @@ public class ExceptionUtil {
return sw.toString();
}
}
/**
* 将CheckedException转换为UncheckedException.
*
@ -28,7 +45,7 @@ public class ExceptionUtil {
*/
public static RuntimeException unchecked(Throwable e) {
if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
|| e instanceof NoSuchMethodException) {
|| e instanceof NoSuchMethodException) {
return new IllegalArgumentException(e);
} else if (e instanceof InvocationTargetException) {
return new RuntimeException(((InvocationTargetException) e).getTargetException());
@ -38,7 +55,7 @@ public class ExceptionUtil {
return new RuntimeException(e);
}
}
/**
* 代理异常解包
*
@ -57,7 +74,7 @@ public class ExceptionUtil {
}
}
}
/**
* 获取根异常
*
@ -69,9 +86,9 @@ public class ExceptionUtil {
if (cause == null) {
return throwable;
}
Throwable t = throwable;
// defend against (malicious?) circularity
for (int i = 0; i < 1000; i++) {
cause = t.getCause();
@ -82,7 +99,7 @@ public class ExceptionUtil {
}
return throwable;
}
/**
* 构建异常
*
@ -103,5 +120,5 @@ public class ExceptionUtil {
return message;
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.nio.charset.Charset;
@ -9,16 +26,16 @@ import java.nio.charset.StandardCharsets;
* @description:
*/
public class CharUtil {
// ---------------------------------------------------------------- simple
/**
* Converts (signed) byte to (unsigned) char.
*/
public static char toChar(final byte b) {
return (char) (b & 0xFF);
}
/**
* Converts char array into byte array by stripping the high byte of each character.
*/
@ -29,7 +46,7 @@ public class CharUtil {
}
return barr;
}
/**
* Converts char sequence into byte array.
*
@ -42,7 +59,7 @@ public class CharUtil {
}
return barr;
}
/**
* Converts byte array to char array by simply extending bytes to chars.
*/
@ -53,9 +70,9 @@ public class CharUtil {
}
return carr;
}
// ---------------------------------------------------------------- ascii
/**
* Returns ASCII value of a char. In case of overload, 0x3F is returned.
*/
@ -66,7 +83,7 @@ public class CharUtil {
return 0x3F;
}
}
/**
* Converts char array into {@link #toAscii(char) ASCII} array.
*/
@ -77,7 +94,7 @@ public class CharUtil {
}
return barr;
}
/**
* Converts char sequence into ASCII byte array.
*/
@ -89,9 +106,9 @@ public class CharUtil {
}
return barr;
}
// ---------------------------------------------------------------- raw arrays
/**
* Converts char array into byte array by replacing each character with two bytes.
*/
@ -104,7 +121,7 @@ public class CharUtil {
}
return barr;
}
public static char[] toRawCharArray(final byte[] barr) {
int carrLen = barr.length >> 1;
if (carrLen << 1 < barr.length) {
@ -115,7 +132,7 @@ public class CharUtil {
while (i < barr.length) {
char c = (char) (barr[i] << 8);
i++;
if (i != barr.length) {
c += barr[i] & 0xFF;
i++;
@ -124,39 +141,39 @@ public class CharUtil {
}
return carr;
}
// ---------------------------------------------------------------- encoding
/**
* Converts char array to byte array using default Jodd encoding.
*/
public static byte[] toByteArray(final char[] carr) {
return new String(carr).getBytes(StandardCharsets.UTF_8);
}
/**
* Converts char array to byte array using provided encoding.
*/
public static byte[] toByteArray(final char[] carr, final Charset charset) {
return new String(carr).getBytes(charset);
}
/**
* Converts byte array of default Jodd encoding to char array.
*/
public static char[] toCharArray(final byte[] barr) {
return new String(barr).toCharArray();
}
/**
* Converts byte array of specific encoding to char array.
*/
public static char[] toCharArray(final byte[] barr, final Charset charset) {
return new String(barr, charset).toCharArray();
}
// ---------------------------------------------------------------- find
/**
* Match if one character equals to any of the given character.
*
@ -171,7 +188,7 @@ public class CharUtil {
}
return false;
}
/**
* Finds index of the first character in given array the matches any from the
* given set of characters.
@ -186,7 +203,7 @@ public class CharUtil {
}
return -1;
}
/**
* Finds index of the first character in given array the matches any from the
* given set of characters.
@ -201,7 +218,7 @@ public class CharUtil {
}
return -1;
}
/**
* Finds index of the first character in given array the differs from the
* given set of characters.
@ -216,7 +233,7 @@ public class CharUtil {
}
return -1;
}
/**
* Finds index of the first character in given array the differs from the
* given set of characters.
@ -231,9 +248,9 @@ public class CharUtil {
}
return -1;
}
// ---------------------------------------------------------------- is
/**
* Returns <code>true</code> if character is a white space ({@code <= ' '}).
* White space definition is taken from String class (see: <code>trim()</code>).
@ -242,7 +259,7 @@ public class CharUtil {
public static boolean isWhitespace(final char c) {
return c <= ' ';
}
/**
* Returns <code>true</code> if specified character is lowercase ASCII.
* If user uses only ASCIIs, it is much much faster.
@ -250,7 +267,7 @@ public class CharUtil {
public static boolean isLowercaseAlpha(final char c) {
return (c >= 'a') && (c <= 'z');
}
/**
* Returns <code>true</code> if specified character is uppercase ASCII.
* If user uses only ASCIIs, it is much much faster.
@ -258,21 +275,21 @@ public class CharUtil {
public static boolean isUppercaseAlpha(final char c) {
return (c >= 'A') && (c <= 'Z');
}
public static boolean isAlphaOrDigit(final char c) {
return isDigit(c) || isAlpha(c);
}
public static boolean isWordChar(final char c) {
return isDigit(c) || isAlpha(c) || (c == '_');
}
public static boolean isPropertyNameChar(final char c) {
return isDigit(c) || isAlpha(c) || (c == '_') || (c == '.') || (c == '[') || (c == ']');
}
// ---------------------------------------------------------------- RFC
/**
* Indicates whether the given character is in the {@code ALPHA} set.
*
@ -281,7 +298,7 @@ public class CharUtil {
public static boolean isAlpha(final char c) {
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
}
/**
* Indicates whether the given character is in the {@code DIGIT} set.
*
@ -290,14 +307,14 @@ public class CharUtil {
public static boolean isDigit(final char c) {
return c >= '0' && c <= '9';
}
/**
* Indicates whether the given character is the hexadecimal digit.
*/
public static boolean isHexDigit(final char c) {
return (c >= '0' && c <= '9') || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));
}
/**
* Indicates whether the given character is in the <i>gen-delims</i> set.
*
@ -317,7 +334,7 @@ public class CharUtil {
return false;
}
}
/**
* Indicates whether the given character is in the <i>sub-delims</i> set.
*
@ -341,7 +358,7 @@ public class CharUtil {
return false;
}
}
/**
* Indicates whether the given character is in the <i>reserved</i> set.
*
@ -350,7 +367,7 @@ public class CharUtil {
public static boolean isReserved(final char c) {
return isGenericDelimiter(c) || isSubDelimiter(c);
}
/**
* Indicates whether the given character is in the <i>unreserved</i> set.
*
@ -359,7 +376,7 @@ public class CharUtil {
public static boolean isUnreserved(final char c) {
return isAlpha(c) || isDigit(c) || c == '-' || c == '.' || c == '_' || c == '~';
}
/**
* Indicates whether the given character is in the <i>pchar</i> set.
*
@ -368,9 +385,9 @@ public class CharUtil {
public static boolean isPchar(final char c) {
return isUnreserved(c) || isSubDelimiter(c) || c == ':' || c == '@';
}
// ---------------------------------------------------------------- conversions
/**
* Uppers lowercase ASCII char.
*/
@ -380,7 +397,7 @@ public class CharUtil {
}
return c;
}
/**
* Lowers uppercase ASCII char.
*/
@ -390,7 +407,7 @@ public class CharUtil {
}
return c;
}
/**
* Converts hex char to int value.
*/
@ -425,14 +442,14 @@ public class CharUtil {
throw new IllegalArgumentException("Not a hex: " + c);
}
}
/**
* Converts integer digit to heck char.
*/
public static char int2hex(final int i) {
return HEX_CHARS[i];
}
public static final char[] HEX_CHARS = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.lang.reflect.Array;
@ -10,12 +27,12 @@ import java.util.Arrays;
*/
@FunctionalInterface
public interface ClassLoaderStrategy {
/**
* Loads class with given name and optionally provided class loader.
*/
Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException;
/**
* Default Jodd class loader strategy.
* Loads a class with a given name dynamically, more reliable then <code>Class.forName</code>.
@ -28,37 +45,37 @@ public interface ClassLoaderStrategy {
* </ul>
*/
class DefaultClassLoaderStrategy implements ClassLoaderStrategy {
/**
* List of primitive type names.
*/
public static final String[] PRIMITIVE_TYPE_NAMES = new String[] {
"boolean", "byte", "char", "double", "float", "int", "long", "short",
public static final String[] PRIMITIVE_TYPE_NAMES = new String[]{
"boolean", "byte", "char", "double", "float", "int", "long", "short",
};
/**
* List of primitive types that matches names list.
*/
public static final Class[] PRIMITIVE_TYPES = new Class[] {
boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class,
public static final Class[] PRIMITIVE_TYPES = new Class[]{
boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class,
};
/**
* List of primitive bytecode characters that matches names list.
*/
public static final char[] PRIMITIVE_BYTECODE_NAME = new char[] {
'Z', 'B', 'C', 'D', 'F', 'I', 'J', 'S'
public static final char[] PRIMITIVE_BYTECODE_NAME = new char[]{
'Z', 'B', 'C', 'D', 'F', 'I', 'J', 'S'
};
// ---------------------------------------------------------------- flags
protected boolean loadArrayClassByComponentTypes = false;
/**
* Returns arrays class loading strategy.
*/
public boolean isLoadArrayClassByComponentTypes() {
return loadArrayClassByComponentTypes;
}
/**
* Defines arrays class loading strategy.
* If <code>false</code> (default), classes will be loaded by <code>Class.forName</code>.
@ -67,36 +84,36 @@ public interface ClassLoaderStrategy {
public void setLoadArrayClassByComponentTypes(final boolean loadArrayClassByComponentTypes) {
this.loadArrayClassByComponentTypes = loadArrayClassByComponentTypes;
}
// ---------------------------------------------------------------- names
/**
* Prepares classname for loading, respecting the arrays.
* Returns <code>null</code> if class name is not an array.
*/
public static String prepareArrayClassnameForLoading(String className) {
final int bracketCount = StringUtils.count(className, '[');
if (bracketCount == 0) {
// not an array
return null;
}
final String brackets = StringUtils.repeat('[', bracketCount);
final int bracketIndex = className.indexOf('[');
className = className.substring(0, bracketIndex);
final int primitiveNdx = getPrimitiveClassNameIndex(className);
if (primitiveNdx >= 0) {
className = String.valueOf(PRIMITIVE_BYTECODE_NAME[primitiveNdx]);
return brackets + className;
} else {
return brackets + 'L' + className + ';';
}
}
/**
* Detects if provided class name is a primitive type.
* Returns >= 0 number if so.
@ -108,16 +125,16 @@ public interface ClassLoaderStrategy {
}
return Arrays.binarySearch(PRIMITIVE_TYPE_NAMES, className);
}
// ---------------------------------------------------------------- load
/**
* Loads class by name.
*/
@Override
public Class loadClass(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
final String arrayClassName = prepareArrayClassnameForLoading(className);
if ((className.indexOf('.') == -1) && (arrayClassName == null)) {
// maybe a primitive
final int primitiveNdx = getPrimitiveClassNameIndex(className);
@ -125,40 +142,40 @@ public interface ClassLoaderStrategy {
return PRIMITIVE_TYPES[primitiveNdx];
}
}
// try #1 - using provided class loader
if (classLoader != null) {
final Class klass = loadClass(className, arrayClassName, classLoader);
if (klass != null) {
return klass;
}
}
// try #2 - using thread class loader
final ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) {
final Class klass = loadClass(className, arrayClassName, currentThreadClassLoader);
if (klass != null) {
return klass;
}
}
// try #3 - using caller classloader, similar as Class.forName()
//Class callerClass = ReflectUtil.getCallerClass(2);
// Class callerClass = ReflectUtil.getCallerClass(2);
final Class callerClass = ClassUtil.getCallerClass();
final ClassLoader callerClassLoader = callerClass.getClassLoader();
if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) {
final Class klass = loadClass(className, arrayClassName, callerClassLoader);
if (klass != null) {
return klass;
}
}
// try #4 - everything failed, try alternative array loader
if (arrayClassName != null) {
try {
@ -166,10 +183,10 @@ public interface ClassLoaderStrategy {
} catch (final ClassNotFoundException ignore) {
}
}
throw new ClassNotFoundException("Class not found: " + className);
}
/**
* Loads a class using provided class loader.
* If class is an array, it will be first loaded using the <code>Class.forName</code>!
@ -188,43 +205,43 @@ public interface ClassLoaderStrategy {
} catch (final ClassNotFoundException ignore) {
}
}
try {
return classLoader.loadClass(className);
} catch (final ClassNotFoundException ignore) {
}
return null;
}
/**
* Loads array class using component type.
*/
protected Class loadArrayClassByComponentType(final String className,
final ClassLoader classLoader) throws ClassNotFoundException {
final ClassLoader classLoader) throws ClassNotFoundException {
final int ndx = className.indexOf('[');
final int multi = StringUtils.count(className, '[');
final String componentTypeName = className.substring(0, ndx);
final Class componentType = loadClass(componentTypeName, classLoader);
if (multi == 1) {
return Array.newInstance(componentType, 0).getClass();
}
final int[] multiSizes;
if (multi == 2) {
multiSizes = new int[] {0, 0};
multiSizes = new int[]{0, 0};
} else if (multi == 3) {
multiSizes = new int[] {0, 0, 0};
multiSizes = new int[]{0, 0, 0};
} else {
multiSizes = (int[]) Array.newInstance(int.class, multi);
}
return Array.newInstance(componentType, multiSizes).getClass();
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.nebula.base.utils.io.IOUtil;
@ -16,11 +33,11 @@ import java.util.jar.Manifest;
* @description:
*/
public class ClassLoaderUtil {
public static ClassLoaderStrategy classLoaderStrategy = new ClassLoaderStrategy.DefaultClassLoaderStrategy();
// ---------------------------------------------------------------- default class loader
/**
* Returns default class loader. By default, it is {@link #getContextClassLoader() threads context class loader}.
* If this one is <code>null</code>, then class loader of the <b>caller class</b> is returned.
@ -33,7 +50,7 @@ public class ClassLoaderUtil {
}
return cl;
}
/**
* Returns thread context class loader.
*/
@ -42,10 +59,10 @@ public class ClassLoaderUtil {
return Thread.currentThread().getContextClassLoader();
} else {
return AccessController.doPrivileged(
(PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader());
(PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader());
}
}
/**
* Returns system class loader.
*/
@ -54,20 +71,20 @@ public class ClassLoaderUtil {
return ClassLoader.getSystemClassLoader();
} else {
return AccessController.doPrivileged(
(PrivilegedAction<ClassLoader>) ClassLoader::getSystemClassLoader);
(PrivilegedAction<ClassLoader>) ClassLoader::getSystemClassLoader);
}
}
// ---------------------------------------------------------------- classpath
private static final String[] MANIFESTS = {"Manifest.mf", "manifest.mf", "MANIFEST.MF"};
/**
* Returns classpath item manifest or <code>null</code> if not found.
*/
public static Manifest getClasspathItemManifest(final File classpathItem) {
Manifest manifest = null;
if (classpathItem.isFile()) {
FileInputStream fis = null;
try {
@ -101,10 +118,10 @@ public class ClassLoaderUtil {
}
}
}
return manifest;
}
/**
* Returns base folder for classpath item. If item is a (jar) file,
* its parent is returned. If item is a directory, its name is returned.
@ -118,16 +135,16 @@ public class ClassLoaderUtil {
}
return base;
}
// ---------------------------------------------------------------- class stream
/**
* Opens a class of the specified name for reading using class classloader.
*/
public static InputStream getClassAsStream(final Class clazz) throws IOException {
return ResourcesUtil.getResourceAsStream(ClassUtil.convertClassNameToFileName(clazz), clazz.getClassLoader());
}
/**
* Opens a class of the specified name for reading. No specific classloader is used
* for loading class.
@ -135,17 +152,17 @@ public class ClassLoaderUtil {
public static InputStream getClassAsStream(final String className) throws IOException {
return ResourcesUtil.getResourceAsStream(ClassUtil.convertClassNameToFileName(className));
}
/**
* Opens a class of the specified name for reading using provided class loader.
*/
public static InputStream getClassAsStream(final String className,
final ClassLoader classLoader) throws IOException {
final ClassLoader classLoader) throws IOException {
return ResourcesUtil.getResourceAsStream(ClassUtil.convertClassNameToFileName(className), classLoader);
}
// ---------------------------------------------------------------- load class
/**
* Loads a class using default class loader strategy.
*
@ -154,7 +171,7 @@ public class ClassLoaderUtil {
public static Class loadClass(final String className) throws ClassNotFoundException {
return classLoaderStrategy.loadClass(className, null);
}
/**
* Loads a class using default class loader strategy.
*
@ -163,9 +180,9 @@ public class ClassLoaderUtil {
public static Class loadClass(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
return classLoaderStrategy.loadClass(className, classLoader);
}
// ---------------------------------------------------------------- class location
/**
* Returns location of the class. If class is not in a jar, it's classpath
* is returned; otherwise the jar location.
@ -173,5 +190,5 @@ public class ClassLoaderUtil {
public static String classLocation(final Class clazz) {
return clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.lang.reflect.Field;
@ -13,7 +30,7 @@ import org.apache.commons.lang3.RandomUtils;
* @description:
*/
public class DataUtils {
/**
* 判断对象是否Empty(null或元素为0)<br>
* 实用于对如下对象做判断:String Collection及其子类 Map及其子类
@ -55,7 +72,7 @@ public class DataUtils {
}
return false;
}
/**
* 判断对象是否为NotEmpty(!null或元素>0)<br>
* 实用于对如下对象做判断:String Collection及其子类 Map及其子类
@ -66,7 +83,7 @@ public class DataUtils {
public static boolean isNotEmpty(Object pObj) {
return !isEmpty(pObj);
}
/**
* 判断对象是否全部不为null
*/
@ -78,7 +95,7 @@ public class DataUtils {
}
return true;
}
public static boolean isAllEmpty(Object... objects) {
for (Object object : objects) {
if (isNotEmpty(object)) {
@ -87,7 +104,7 @@ public class DataUtils {
}
return true;
}
public static boolean isAnyIsEmpty(Object... objects) {
for (Object object : objects) {
if (isEmpty(object)) {
@ -96,7 +113,7 @@ public class DataUtils {
}
return false;
}
public static boolean isAnyNotEmpty(Object... objects) {
for (Object object : objects) {
if (isNotEmpty(object)) {
@ -105,7 +122,7 @@ public class DataUtils {
}
return false;
}
/**
* 得到默认值
*
@ -117,7 +134,7 @@ public class DataUtils {
public static <T> T getDefaultValue(T value, T defaultValue) {
return getDefaultValue(value, defaultValue, a -> a);
}
/**
* 得到默认值, 如果原值不为空可以处理
*
@ -129,10 +146,10 @@ public class DataUtils {
*/
public static <T, S> T getDefaultValue(S value, T defaultValue, Function<S, T> function) {
return isNotEmpty(value)
? function.apply(value)
: defaultValue;
? function.apply(value)
: defaultValue;
}
/**
* 得到默认值, 如果原值不为空可以处理
*
@ -145,13 +162,13 @@ public class DataUtils {
public static <T, S> T getDefaultValueSafety(S value, T defaultValue, Function<S, T> function) {
try {
return isNotEmpty(value)
? function.apply(value)
: defaultValue;
? function.apply(value)
: defaultValue;
} catch (Exception e) {
return defaultValue;
}
}
/**
* 得到值, 如果原值不为空可以处理
*
@ -167,7 +184,7 @@ public class DataUtils {
return defaultValue;
}
}
public static boolean tryParseLong(String value) {
try {
Long.parseLong(value);
@ -176,7 +193,7 @@ public class DataUtils {
return false;
}
}
public static boolean isAllNotNull(Object... objects) {
for (Object object : objects) {
if (isEmpty(object)) {
@ -185,7 +202,7 @@ public class DataUtils {
}
return true;
}
/**
* 检查一个对象的所有属性是不是都为空
*
@ -202,7 +219,7 @@ public class DataUtils {
}
return true;
}
public static long randomLongId() {
return -RandomUtils.nextLong(0, 99999999999999L);
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.nebula.base.utils.io.IOUtil;
@ -15,11 +32,11 @@ import java.security.MessageDigest;
* @description:
*/
public interface DigestEngine {
class JavaDigestEngine implements DigestEngine {
private final MessageDigest messageDigest;
JavaDigestEngine(final String algorithm) {
try {
this.messageDigest = MessageDigest.getInstance(algorithm);
@ -27,37 +44,36 @@ public interface DigestEngine {
throw new RuntimeException(e);
}
}
@Override
public byte[] digest(final byte[] byteArray) {
messageDigest.update(byteArray);
return messageDigest.digest();
}
@Override
public byte[] digest(final File file) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
DigestInputStream dis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DigestInputStream(bis, messageDigest);
while (dis.read() != -1) {
}
}
finally {
} finally {
IOUtil.close(dis);
IOUtil.close(bis);
IOUtil.close(fis);
}
return messageDigest.digest();
}
}
/**
* Creates new MD2 digest.
*/
@ -94,41 +110,41 @@ public interface DigestEngine {
public static DigestEngine sha512() {
return new JavaDigestEngine("SHA-512");
}
/**
* Returns byte-hash of input byte array.
*/
public byte[] digest(byte[] input);
/**
* Returns byte-hash of input string.
*/
public default byte[] digest(final String input) {
return digest(input.getBytes(StandardCharsets.UTF_8));
}
/**
* Returns digest of a file. Implementations may not read the whole
* file into the memory.
*/
public byte[] digest(final File file) throws IOException;
/**
* Returns string hash of input byte array.
*/
public default String digestString(final byte[] byteArray) {
return StringUtils.toHexString(digest(byteArray));
}
/**
* Returns string hash of input string.
*/
public default String digestString(final String input) {
return StringUtils.toHexString(digest(input));
}
public default String digestString(final File file) throws IOException {
return StringUtils.toHexString(digest(file));
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.fasterxml.jackson.databind.module.SimpleModule;
@ -16,8 +33,7 @@ import java.time.LocalTime;
* java 8 时间默认序列化
*/
public class JacksonTimeModule extends SimpleModule {
public JacksonTimeModule() {
super(PackageVersion.VERSION);
this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(TimeUtil.DATETIME_FORMAT));
@ -27,6 +43,5 @@ public class JacksonTimeModule extends SimpleModule {
this.addSerializer(LocalDate.class, new LocalDateSerializer(TimeUtil.DATE_FORMAT));
this.addSerializer(LocalTime.class, new LocalTimeSerializer(TimeUtil.TIME_FORMAT));
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
@ -22,7 +39,7 @@ import java.util.*;
*/
@Slf4j
public class JsonUtil {
/**
* 将对象序列化成json字符串
*
@ -33,23 +50,21 @@ public class JsonUtil {
public static <T> String toJSONString(T value) {
try {
return getInstance().writeValueAsString(value);
}
catch (Exception e) {
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
public static <T> String toJSONString(ObjectMapper objectMapper, T value) {
try {
return objectMapper.writeValueAsString(value);
}
catch (Exception e) {
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* 对象转 JsonNode
* @param entity
@ -60,7 +75,7 @@ public class JsonUtil {
public static <T> JsonNode obj2JsonNode(T entity) throws Exception {
return getInstance().valueToTree(entity);
}
/**
* 将对象序列化成 json byte 数组
*
@ -70,12 +85,11 @@ public class JsonUtil {
public static byte[] toJsonAsBytes(Object object) {
try {
return getInstance().writeValueAsBytes(object);
}
catch (JsonProcessingException e) {
} catch (JsonProcessingException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json反序列化成对象
*
@ -87,13 +101,12 @@ public class JsonUtil {
public static <T> T json2JavaBean(String content, Class<T> valueType) {
try {
return getInstance().readValue(content, valueType);
}
catch (Exception e) {
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* 将json反序列化成对象
*
@ -105,12 +118,11 @@ public class JsonUtil {
public static <T> T json2JavaBean(String content, TypeReference<T> typeReference) {
try {
return getInstance().readValue(content, typeReference);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json byte 数组反序列化成对象
*
@ -122,13 +134,11 @@ public class JsonUtil {
public static <T> T json2JavaBean(byte[] bytes, Class<T> valueType) {
try {
return getInstance().readValue(bytes, valueType);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json反序列化成对象
*
@ -140,12 +150,11 @@ public class JsonUtil {
public static <T> T json2JavaBean(byte[] bytes, TypeReference<T> typeReference) {
try {
return getInstance().readValue(bytes, typeReference);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json反序列化成对象
*
@ -157,12 +166,11 @@ public class JsonUtil {
public static <T> T json2JavaBean(InputStream in, Class<T> valueType) {
try {
return getInstance().readValue(in, valueType);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json反序列化成对象
*
@ -174,12 +182,11 @@ public class JsonUtil {
public static <T> T json2JavaBean(InputStream in, TypeReference<T> typeReference) {
try {
return getInstance().readValue(in, typeReference);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
public static <T> List<T> json2Array(String json, Class<T> valueTypeRef) {
List<T> objectList = Collections.emptyList();
if (DataUtils.isEmpty(json)) {
@ -188,26 +195,23 @@ public class JsonUtil {
JavaType javaType = getInstance().getTypeFactory().constructParametricType(List.class, valueTypeRef);
try {
return getInstance().readValue(json, javaType);
}
catch (JsonProcessingException e) {
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
}
return objectList;
}
public static <T> List<T> jsonNode2Array(JsonNode jsonNode, Class<T> clazz) {
ObjectReader reader = getInstance().readerForListOf(clazz);
List<T> objectList = Collections.emptyList();
try {
return reader.readValue(jsonNode);
}
catch (IOException e) {
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return objectList;
}
/**
* json to Map
* @param content
@ -216,13 +220,12 @@ public class JsonUtil {
public static Map<String, Object> json2Map(String content) {
try {
return getInstance().readValue(content, Map.class);
}
catch (IOException e) {
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
public static <T> Map<String, T> json2Map(String content, Class<T> valueTypeRef) {
try {
Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
@ -232,17 +235,16 @@ public class JsonUtil {
result.put(entry.getKey(), toPojo(entry.getValue(), valueTypeRef));
}
return result;
}
catch (IOException e) {
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
public static <T> T toPojo(Map fromValue, Class<T> toValueType) {
return getInstance().convertValue(fromValue, toValueType);
}
/**
* 将json字符串转成 JsonNode
*
@ -252,12 +254,11 @@ public class JsonUtil {
public static JsonNode json2JsonNode(String jsonString) {
try {
return getInstance().readTree(jsonString);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* jsonNode to String
* @param jsonNode
@ -266,12 +267,11 @@ public class JsonUtil {
public static String jsonNodeToString(JsonNode jsonNode) {
try {
return getInstance().writeValueAsString(jsonNode);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json字节数组转成 JsonNode
*
@ -281,12 +281,11 @@ public class JsonUtil {
public static JsonNode byte2JsonNode(byte[] content) {
try {
return getInstance().readTree(content);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json字符串转成 JsonNode
*
@ -296,12 +295,11 @@ public class JsonUtil {
public static JsonNode json2JsonNode(InputStream in) {
try {
return getInstance().readTree(in);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json字符串转成 JsonNode
*
@ -311,12 +309,11 @@ public class JsonUtil {
public static JsonNode json2JsonNode(byte[] content) {
try {
return getInstance().readTree(content);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
/**
* 将json字符串转成 JsonNode
*
@ -326,60 +323,58 @@ public class JsonUtil {
public static JsonNode json2JsonNode(JsonParser jsonParser) {
try {
return getInstance().readTree(jsonParser);
}
catch (IOException e) {
} catch (IOException e) {
throw ExceptionUtil.unchecked(e);
}
}
public static ObjectMapper getInstance() {
return JacksonHolder.INSTANCE;
}
private static class JacksonHolder {
private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
}
public static class JacksonObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 4288193147502386170L;
private static final Locale CHINA = Locale.CHINA;
public JacksonObjectMapper() {
super();
//设置地点为中国
// 设置地点为中国
super.setLocale(CHINA);
super.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//去掉默认的时间戳格式
// 去掉默认的时间戳格式
super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//设置为中国上海时区
// 设置为中国上海时区
super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
//序列化时日期的统一格式
// 序列化时日期的统一格式
super.setDateFormat(new SimpleDateFormat(TimeUtil.YYYYMMddHHmmss, Locale.CHINA));
//序列化处理
// 序列化处理
super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
super.findAndRegisterModules();
//失败处理
// 失败处理
super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//单引号处理
// 单引号处理
super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
//反序列化时属性不存在的兼容处理
// 反序列化时属性不存在的兼容处理
super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//日期格式化
// 日期格式化
super.registerModule(new JacksonTimeModule());
super.findAndRegisterModules();
}
@Override
public ObjectMapper copy() {
return super.copy();
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.util.regex.Pattern;
@ -14,85 +31,84 @@ import lombok.ToString;
@Getter
@ToString
public enum PatternEnum {
/**
* 英文字母 数字和下划线
*/
GENERAL(Pattern.compile("^\\w+$")),
/**
* 数字
*/
NUMBERS(Pattern.compile("\\d+")),
/**
* 小写字母
*/
LOWER_CASE(Pattern.compile("[a-z]+")),
/**
* 小写字母
*/
UPPER_CASE(Pattern.compile("[A-Z]+")),
/**
* 英文字母
*/
WORD(Pattern.compile("[a-zA-Z]+")),
/**
* 单个汉字
*/
CHINESE(Pattern.compile("[\u4E00-\u9FFF]")),
/**
* 汉字
*/
CHINESE_WORD(Pattern.compile("[\u4E00-\u9FFF]+")),
/**
* 电话
*/
MOBILE(Pattern.compile("(?:0|86|\\+86)?1[3456789]\\d{9}")),
/**
* 身份证18位
*/
CITIZEN_ID(Pattern.compile("[1-9]\\d{5}[1-2]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}(\\d|X|x)")),
/**
* 邮箱
*/
MAIL(Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*")),
/**
* emoji表情
*/
EMOJI(Pattern.compile("[\\x{10000}-\\x{10ffff}\ud800-\udfff]")),
/**
* emoji表情编码格式
*/
EMOJI_DECODE(Pattern.compile("\\[\\[EMOJI:(.*?)\\]\\]")),
/**
* 正则分组符号格式
*/
GROUP_VAR(Pattern.compile("\\$(\\d+)")),
/**
* 特殊符号(~!@#$%^&*()_+|<>,.?/:;'[]{}\)
*/
SPEC_SYMBOL(Pattern.compile("[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+"));
/**
* 正则表达式
*/
private Pattern pattern;
public boolean isMatch(String input) {
return pattern.matcher(input).matches();
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.io.Serializable;
@ -9,5 +26,5 @@ import java.util.function.Function;
* @description:
*/
public interface PropertyFunc<T, R> extends Function<T, R>, Serializable {
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.beans.BeanInfo;
@ -20,12 +37,11 @@ import org.slf4j.LoggerFactory;
* @description:
*/
public class ReflectionUtils {
private static final String METHOD = "writeReplace";
private static final Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);
/**
* 获取 Function
* @param func
@ -46,7 +62,7 @@ public class ReflectionUtils {
throw new RuntimeException(e);
}
}
private static String resolveFieldName(String getMethodName) {
if (getMethodName.startsWith("get")) {
getMethodName = getMethodName.substring(3);
@ -56,14 +72,14 @@ public class ReflectionUtils {
// 小写第一个字母
return firstToLowerCase(getMethodName);
}
private static String firstToLowerCase(String param) {
if (DataUtils.isEmpty(param)) {
return "";
}
return param.substring(0, 1).toLowerCase() + param.substring(1);
}
/**
* class 是否存在属性
* @param fieldName 属性名
@ -72,9 +88,9 @@ public class ReflectionUtils {
*/
public static <T> boolean isExistFieldName(String fieldName, Class<T> clazz) {
boolean flag = false;
//获取这个类的所有属性
// 获取这个类的所有属性
Field[] fields = clazz.getDeclaredFields();
//循环遍历所有的fields
// 循环遍历所有的fields
for (Field field : fields) {
if (field.getName().equals(fieldName)) {
flag = true;
@ -83,12 +99,12 @@ public class ReflectionUtils {
}
return flag;
}
public static <T, V extends Annotation> boolean isExistFieldName(String fieldName, Class<T> clazz, Class<V> annotationClass) {
boolean flag = false;
//获取这个类的所有属性
// 获取这个类的所有属性
Field[] fields = clazz.getDeclaredFields();
//循环遍历所有的fields
// 循环遍历所有的fields
for (Field field : fields) {
if (field.getName().equals(fieldName) && Objects.nonNull(field.getAnnotation(annotationClass))) {
flag = true;
@ -97,8 +113,7 @@ public class ReflectionUtils {
}
return flag;
}
/**
* 获取指定属性
*
@ -117,7 +132,7 @@ public class ReflectionUtils {
return null;
}
}
/**
* 设置属性值
*
@ -134,7 +149,7 @@ public class ReflectionUtils {
logger.error("setPropertyValue exception", e);
}
}
/**
* 获取构造器
* @param clazzPath
@ -147,7 +162,7 @@ public class ReflectionUtils {
Class<?> operationClazz = Class.forName(clazzPath);
return operationClazz.getDeclaredConstructor(parameterTypes);
}
/**
* 根据Getter方法拿到字段名
*/
@ -163,5 +178,5 @@ public class ReflectionUtils {
}
return Optional.empty();
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.util.ArrayList;
@ -15,7 +32,7 @@ import java.util.regex.Pattern;
* @description:
*/
public class RegexUtils {
/**
* 给定内容是否匹配正则表达式
*
@ -26,7 +43,7 @@ public class RegexUtils {
public static boolean isMatch(String regex, String content) {
return DataUtils.isEmpty(regex) || !DataUtils.isEmpty(content) && isMatch(Pattern.compile(regex), content);
}
/**
* 给定内容是否匹配正则
*
@ -37,7 +54,7 @@ public class RegexUtils {
public static boolean isMatch(Pattern pattern, String content) {
return DataUtils.isEmpty(pattern) || !DataUtils.isEmpty(content) && pattern.matcher(content).matches();
}
/**
* 删除匹配正则表达式的全部内容
*
@ -51,7 +68,7 @@ public class RegexUtils {
}
return deleteAll(Pattern.compile(regex), content);
}
/**
* 删除匹配正则表达式的全部内容
*
@ -65,7 +82,7 @@ public class RegexUtils {
}
return pattern.matcher(content).replaceAll(StringUtils.EMPTY);
}
/**
* 取得内容中匹配的所有结果
*
@ -76,7 +93,7 @@ public class RegexUtils {
public static List<String> findAll(String regex, String content) {
return findAll(regex, content, new ArrayList<>());
}
/**
* 取得内容中匹配的所有结果
*
@ -87,7 +104,7 @@ public class RegexUtils {
public static List<String> findAll(Pattern pattern, String content) {
return findAll(pattern, content, new ArrayList<>());
}
/**
* 取得内容中匹配的所有结果
*
@ -103,7 +120,7 @@ public class RegexUtils {
}
return findAll(Pattern.compile(regex), content, 0, collection);
}
/**
* 取得内容中匹配的所有结果
*
@ -116,7 +133,7 @@ public class RegexUtils {
public static <T extends Collection<String>> T findAll(Pattern pattern, String content, T collection) {
return findAll(pattern, content, 0, collection);
}
/**
* 取得内容中匹配的所有结果
*
@ -131,7 +148,7 @@ public class RegexUtils {
Pattern pattern = Pattern.compile(regex);
return findAll(pattern, content, group, collection);
}
/**
* 取得内容中匹配的所有结果
*
@ -155,7 +172,7 @@ public class RegexUtils {
}
return collection;
}
/**
* 替换内容中匹配的所有结果
*
@ -167,7 +184,7 @@ public class RegexUtils {
public static String replaceAll(String regex, String content, String replacementTemplate) {
return replaceAll(content, Pattern.compile(regex), replacementTemplate);
}
/**
* 替换内容中匹配的所有结果
*
@ -200,7 +217,7 @@ public class RegexUtils {
matcher.appendTail(sb);
return sb.toString();
}
/**
* 替换内容中匹配的所有结果
*
@ -214,7 +231,7 @@ public class RegexUtils {
Pattern pattern = Pattern.compile(regex);
return replaceAll(content, pattern, function, group);
}
/**
* 替换内容中匹配的所有结果
*
@ -238,7 +255,7 @@ public class RegexUtils {
matcher.appendTail(sb);
return sb.toString();
}
/**
* 替换内容中匹配的所有结果
*
@ -250,7 +267,7 @@ public class RegexUtils {
public static String replaceAll(String content, Pattern pattern, Function<String, String> function) {
return replaceAll(content, pattern, function, 0);
}
/**
* 将星号字符转为可正则匹配的字段, * 表示任何长度的[0-9][a-z][A-Z]
*
@ -264,20 +281,20 @@ public class RegexUtils {
* @return 符合正则规则的字段
*/
public static String asteriskMatching(String str) {
var firstIndex = str.indexOf("*");
var lastIndexOf = str.lastIndexOf("*");
var length = str.length() - 1;
int fuzzyLength = lastIndexOf - firstIndex + 1;
//todo 后续再重构兼容星不连续类型字段
// todo 后续再重构兼容星不连续类型字段
if (fuzzyLength == length + 1) {
throw new RuntimeException("暂时不兼容该类型字段");
}
String fuzzyPattern = "(\\\\w)*";
var patterStr = str.replaceAll("\\*".repeat(Math.max(0, fuzzyLength)), fuzzyPattern);
return "^" + patterStr + "$";
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.nebula.base.utils.io.IOUtil;
@ -12,9 +29,9 @@ import java.net.URLConnection;
* @description:
*/
public class ResourcesUtil {
// ---------------------------------------------------------------- get resource
/**
* Retrieves given resource as URL.
* @see #getResourceUrl(String, ClassLoader)
@ -22,7 +39,7 @@ public class ResourcesUtil {
public static URL getResourceUrl(final String resourceName) {
return getResourceUrl(resourceName, null);
}
/**
* Retrieves given resource as URL. Resource is always absolute and may
* starts with a slash character.
@ -35,13 +52,13 @@ public class ResourcesUtil {
* </ul>
*/
public static URL getResourceUrl(String resourceName, final ClassLoader classLoader) {
if (resourceName.startsWith("/")) {
resourceName = resourceName.substring(1);
}
URL resourceUrl;
// try #1 - using provided class loader
if (classLoader != null) {
resourceUrl = classLoader.getResource(resourceName);
@ -49,7 +66,7 @@ public class ResourcesUtil {
return resourceUrl;
}
}
// try #2 - using thread class loader
final ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) {
@ -58,36 +75,35 @@ public class ResourcesUtil {
return resourceUrl;
}
}
// try #3 - using caller classloader, similar as Class.forName()
final Class callerClass = ClassUtil.getCallerClass(2);
final ClassLoader callerClassLoader = callerClass.getClassLoader();
if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) {
resourceUrl = callerClassLoader.getResource(resourceName);
if (resourceUrl != null) {
return resourceUrl;
}
}
return null;
}
// ---------------------------------------------------------------- get resource string
public static String getResourceAsString(final String resourceName) throws IOException {
final InputStream inputStream = getResourceAsStream(resourceName);
try {
final char[] data = IOUtil.readChars(inputStream);
return new String(data);
}
finally {
} finally {
IOUtil.close(inputStream);
}
}
// ---------------------------------------------------------------- get resource stream
/**
* Opens a resource of the specified name for reading.
* @see #getResourceAsStream(String, ClassLoader)
@ -95,7 +111,7 @@ public class ResourcesUtil {
public static InputStream getResourceAsStream(final String resourceName) throws IOException {
return getResourceAsStream(resourceName, null);
}
/**
* Opens a resource of the specified name for reading.
* @see #getResourceUrl(String, ClassLoader)
@ -107,7 +123,7 @@ public class ResourcesUtil {
}
return null;
}
/**
* Opens a resource of the specified name for reading. Controls caching,
* that is important when the same jar is reloaded using custom classloader.
@ -121,6 +137,5 @@ public class ResourcesUtil {
}
return null;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
/**
@ -6,7 +23,7 @@ package com.nebula.base.utils;
* @description:
*/
public interface StringPool {
String AMPERSAND = "&";
String AND = "and";
String AT = "@";
@ -71,5 +88,5 @@ public interface StringPool {
String GET = "GET";
String POST = "POST";
String DOTDOT = "..";
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import com.google.common.base.Joiner;
@ -26,7 +43,7 @@ import org.slf4j.helpers.FormattingTuple;
* @description:
*/
public class StringUtils {
public static final String SPACE = " ";
public static final String TAB = " ";
public static final String DOT = ".";
@ -45,7 +62,7 @@ public class StringUtils {
public static final String BRACKET_START = "[";
public static final String BRACKET_END = "]";
public static final String COLON = ":";
/**
* 将var2参数替换成var1中出现的{}
* <pre>
@ -62,11 +79,11 @@ public class StringUtils {
public static String stringFormat(String var1, Object... var2) {
return MessageFormatter.arrayFormat(var1, var2).getMessage();
}
public static boolean startsWithIgnoreCase(String str, String prefix) {
return str != null && prefix != null && str.length() >= prefix.length() && str.regionMatches(true, 0, prefix, 0, prefix.length());
}
/**
* 判断字符串是否为整数
*
@ -77,7 +94,7 @@ public class StringUtils {
Pattern pattern = Pattern.compile("^[0-9]*$");
return pattern.matcher(str).matches();
}
/**
* EMOJI encode
*
@ -99,7 +116,7 @@ public class StringUtils {
}
throw new RuntimeException("emoji filter error");
}
/**
* EMOJI decode
*
@ -121,29 +138,29 @@ public class StringUtils {
}
throw new RuntimeException("emoji decode error");
}
public static String[] splitc(final String src, final char[] delimiters) {
if ((delimiters.length == 0) || (src.isEmpty())) {
return new String[] {src};
return new String[]{src};
}
final char[] srcc = src.toCharArray();
final int maxparts = srcc.length + 1;
final int[] start = new int[maxparts];
final int[] end = new int[maxparts];
int count = 0;
start[0] = 0;
int s = 0, e;
if (CharUtil.equalsOne(srcc[0], delimiters)) { // string starts with delimiter
if (CharUtil.equalsOne(srcc[0], delimiters)) { // string starts with delimiter
end[0] = 0;
count++;
s = CharUtil.findFirstDiff(srcc, 1, delimiters);
if (s == -1) { // nothing after delimiters
return new String[] {EMPTY, EMPTY};
if (s == -1) { // nothing after delimiters
return new String[]{EMPTY, EMPTY};
}
start[1] = s; // new start
start[1] = s; // new start
}
while (true) {
// find new end
@ -153,7 +170,7 @@ public class StringUtils {
break;
}
end[count] = e;
// find new start
count++;
s = CharUtil.findFirstDiff(srcc, e, delimiters);
@ -170,29 +187,29 @@ public class StringUtils {
}
return result;
}
public static String[] splitc(final String src, final char delimiter) {
if (src.isEmpty()) {
return new String[] {EMPTY};
return new String[]{EMPTY};
}
final char[] srcc = src.toCharArray();
final int maxparts = srcc.length + 1;
final int[] start = new int[maxparts];
final int[] end = new int[maxparts];
int count = 0;
start[0] = 0;
int s = 0, e;
if (srcc[0] == delimiter) { // string starts with delimiter
if (srcc[0] == delimiter) { // string starts with delimiter
end[0] = 0;
count++;
s = CharUtil.findFirstDiff(srcc, 1, delimiter);
if (s == -1) { // nothing after delimiters
return new String[] {EMPTY, EMPTY};
if (s == -1) { // nothing after delimiters
return new String[]{EMPTY, EMPTY};
}
start[1] = s; // new start
start[1] = s; // new start
}
while (true) {
// find new end
@ -202,7 +219,7 @@ public class StringUtils {
break;
}
end[count] = e;
// find new start
count++;
s = CharUtil.findFirstDiff(srcc, e, delimiter);
@ -219,32 +236,33 @@ public class StringUtils {
}
return result;
}
public static String[] splitc(final String src, final String d) {
if ((d.isEmpty()) || (src.isEmpty())) {
return new String[] {src};
return new String[]{src};
}
return splitc(src, d.toCharArray());
}
public static class MessageFormatter {
static final char DELIM_START = '{';
static final char DELIM_STOP = '}';
static final String DELIM_STR = "{}";
private static final char ESCAPE_CHAR = '\\';
static Throwable getThrowableCandidate(Object[] argArray) {
if (argArray == null || argArray.length == 0) {
return null;
}
final Object lastEntry = argArray[argArray.length - 1];
if (lastEntry instanceof Throwable) {
return (Throwable) lastEntry;
}
return null;
}
public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
Throwable throwableCandidate = getThrowableCandidate(argArray);
Object[] args = argArray;
@ -253,7 +271,7 @@ public class StringUtils {
}
return arrayFormat(messagePattern, args, throwableCandidate);
}
private static Object[] trimmedCopy(Object[] argArray) {
if (argArray == null || argArray.length == 0) {
throw new IllegalStateException("non-sensical empty or null argument array");
@ -263,28 +281,28 @@ public class StringUtils {
System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
return trimmed;
}
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray,
Throwable throwable) {
Throwable throwable) {
if (messagePattern == null) {
return new FormattingTuple(null, argArray, throwable);
}
if (argArray == null) {
return new FormattingTuple(messagePattern);
}
int i = 0;
int j;
// use string builder for better multicore performance
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
int L;
for (L = 0; L < argArray.length; L++) {
j = messagePattern.indexOf(DELIM_STR, i);
if (j == -1) {
// no more variables
if (i == 0) { // this is a simple string
@ -321,9 +339,9 @@ public class StringUtils {
sbuf.append(messagePattern, i, messagePattern.length());
return new FormattingTuple(sbuf.toString(), argArray, throwable);
}
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
if (delimeterStartIndex == 0) {
return false;
}
@ -334,7 +352,7 @@ public class StringUtils {
return false;
}
}
final static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) {
if (delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) {
return true;
@ -342,7 +360,7 @@ public class StringUtils {
return false;
}
}
// special treatment of array values was suggested by 'lizongbo'
private static void deeplyAppendParameter(StringBuilder sbuf, Object o, Map<Object[], Object> seenMap) {
if (o == null) {
@ -375,7 +393,7 @@ public class StringUtils {
}
}
}
private static void safeObjectAppend(StringBuilder sbuf, Object o) {
try {
String oAsString = o.toString();
@ -386,9 +404,9 @@ public class StringUtils {
t.printStackTrace();
sbuf.append("[FAILED toString()]");
}
}
private static void objectArrayAppend(StringBuilder sbuf, Object[] a, Map<Object[], Object> seenMap) {
sbuf.append('[');
if (!seenMap.containsKey(a)) {
@ -406,7 +424,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) {
sbuf.append('[');
final int len = a.length;
@ -417,7 +435,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void byteArrayAppend(StringBuilder sbuf, byte[] a) {
sbuf.append('[');
final int len = a.length;
@ -428,7 +446,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void charArrayAppend(StringBuilder sbuf, char[] a) {
sbuf.append('[');
final int len = a.length;
@ -439,7 +457,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void shortArrayAppend(StringBuilder sbuf, short[] a) {
sbuf.append('[');
final int len = a.length;
@ -450,7 +468,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void intArrayAppend(StringBuilder sbuf, int[] a) {
sbuf.append('[');
final int len = a.length;
@ -461,7 +479,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void longArrayAppend(StringBuilder sbuf, long[] a) {
sbuf.append('[');
final int len = a.length;
@ -472,7 +490,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void floatArrayAppend(StringBuilder sbuf, float[] a) {
sbuf.append('[');
final int len = a.length;
@ -483,7 +501,7 @@ public class StringUtils {
}
sbuf.append(']');
}
private static void doubleArrayAppend(StringBuilder sbuf, double[] a) {
sbuf.append('[');
final int len = a.length;
@ -495,16 +513,16 @@ public class StringUtils {
sbuf.append(']');
}
}
public static String emojiFilter(String str) {
if (str == null) {
return null;
}
String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
try {
@ -514,10 +532,10 @@ public class StringUtils {
}
}
matcher.appendTail(sb);
return sb.toString();
}
public static String parseCurrency(String currency) {
if (DataUtils.isEmpty(currency)) {
return "";
@ -535,7 +553,7 @@ public class StringUtils {
return null;
}
}
public static String getExceptionStackTrace(Exception e) {
try {
StringWriter sw = new StringWriter();
@ -546,11 +564,11 @@ public class StringUtils {
return "bad get Error StackTrace From Exception";
}
}
public static List<String> split(String str, String reg) {
return Arrays.stream(str.split(reg)).collect(Collectors.toList());
}
/**
* 逗号字符串 变成 long 的list
*/
@ -559,12 +577,12 @@ public class StringUtils {
return Lists.newArrayList();
}
return Splitter.on(",").omitEmptyStrings()
.trimResults().splitToList(str.trim())
.stream()
.filter(NumberUtils::isDigits)
.map(Long::parseLong).collect(Collectors.toList());
.trimResults().splitToList(str.trim())
.stream()
.filter(NumberUtils::isDigits)
.map(Long::parseLong).collect(Collectors.toList());
}
/**
* 逗号字符串 变成 Integer 的list
*/
@ -573,12 +591,12 @@ public class StringUtils {
return Lists.newArrayList();
}
return Splitter.on(",").omitEmptyStrings()
.trimResults().splitToList(str.trim())
.stream()
.filter(NumberUtils::isDigits)
.map(Integer::parseInt).collect(Collectors.toList());
.trimResults().splitToList(str.trim())
.stream()
.filter(NumberUtils::isDigits)
.map(Integer::parseInt).collect(Collectors.toList());
}
/**
*
*/
@ -588,11 +606,11 @@ public class StringUtils {
}
return Splitter.on(",").omitEmptyStrings().trimResults().splitToList(str.trim());
}
public static <T> String joinCollection(Collection<T> originList) {
return Joiner.on(",").join(originList);
}
/**
* 解析 xml 节点数据
*
@ -605,7 +623,7 @@ public class StringUtils {
public static String parsXmlNode(String str, String key) {
return parsXmlNode(str, key, 0);
}
/**
* 解析 xml节点
*
@ -633,7 +651,7 @@ public class StringUtils {
}
return "";
}
/**
* 判断首字符是否为韩文
*
@ -646,16 +664,16 @@ public class StringUtils {
}
char c = s.charAt(0);
return (c > 0x3130 && c < 0x318F)
|| (c >= 0xAC00 && c <= 0xD7A3);
|| (c >= 0xAC00 && c <= 0xD7A3);
}
/**
* 去除字符串所有空格
*/
public static String trimAnySpace(String str) {
return str.replaceAll("\\s*", "");
}
/**
* 首字母小写
*/
@ -667,7 +685,7 @@ public class StringUtils {
chars[0] += 32;
return String.valueOf(chars);
}
/**
* 首字母大写
*/
@ -679,11 +697,11 @@ public class StringUtils {
cs[0] -= 32;
return String.valueOf(cs);
}
public static boolean equalsIgnoreCase(final CharSequence str1, final CharSequence str2) {
return org.apache.commons.lang3.StringUtils.equalsIgnoreCase(str1, str2);
}
/**
* 判断所有字符串是否都相等null和1个也是返回true
* <p>
@ -708,30 +726,30 @@ public class StringUtils {
}
return true;
}
public static <T extends CharSequence> T defaultIfEmpty(final T str, final T defaultStr) {
return org.apache.commons.lang3.StringUtils.defaultIfEmpty(str, defaultStr);
}
public static <T extends CharSequence> T nullIfEmpty(final T str) {
return org.apache.commons.lang3.StringUtils.defaultIfEmpty(str, null);
}
public static String substringAfter(final String str, final String separator) {
return org.apache.commons.lang3.StringUtils.substringAfter(str, separator);
}
public static String toString(final Object value) {
if (value == null) {
return null;
}
return value.toString();
}
public static int indexOfChars(final String string, final String chars) {
return indexOfChars(string, chars, 0);
}
public static int indexOfChars(final String string, final String chars, int startindex) {
final int stringLen = string.length();
final int charsLen = chars.length();
@ -748,7 +766,7 @@ public class StringUtils {
}
return -1;
}
public static String replace(final String s, final String sub, final String with) {
if (sub.isEmpty()) {
return s;
@ -764,21 +782,20 @@ public class StringUtils {
sb.append(s, c, i);
sb.append(with);
c = i + sub.length();
}
while ((i = s.indexOf(sub, c)) != -1);
} while ((i = s.indexOf(sub, c)) != -1);
if (c < length) {
sb.append(s, c, length);
}
return sb.toString();
}
public static boolean startsWithChar(final String s, final char c) {
if (s.isEmpty()) {
return false;
}
return s.charAt(0) == c;
}
public static boolean containsOnlyDigitsAndSigns(final CharSequence string) {
final int size = string.length();
for (int i = 0; i < size; i++) {
@ -789,7 +806,7 @@ public class StringUtils {
}
return true;
}
public static boolean containsOnlyDigits(final CharSequence string) {
final int size = string.length();
for (int i = 0; i < size; i++) {
@ -800,29 +817,29 @@ public class StringUtils {
}
return true;
}
public static String toHexString(final byte[] bytes) {
final char[] chars = new char[bytes.length * 2];
int i = 0;
for (final byte b : bytes) {
chars[i++] = CharUtil.int2hex((b & 0xF0) >> 4);
chars[i++] = CharUtil.int2hex(b & 0x0F);
}
return new String(chars);
}
public static String decapitalize(final String name) {
if (name.isEmpty()) {
return name;
}
if (name.length() > 1 &&
Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))) {
Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))) {
return name;
}
final char[] chars = name.toCharArray();
final char c = chars[0];
final char modifiedChar = Character.toLowerCase(c);
@ -832,11 +849,11 @@ public class StringUtils {
chars[0] = modifiedChar;
return new String(chars);
}
public static int count(final String source, final char c) {
return count(source, c, 0);
}
public static int count(final String source, final char c, final int start) {
int count = 0;
int j = start;
@ -850,7 +867,7 @@ public class StringUtils {
}
return count;
}
public static String repeat(final String source, int count) {
final StringBuilder result = new StringBuilder(source.length() * count);
while (count > 0) {
@ -859,7 +876,7 @@ public class StringUtils {
}
return result.toString();
}
public static String repeat(final char c, final int count) {
final char[] result = new char[count];
for (int i = 0; i < count; i++) {
@ -867,5 +884,5 @@ public class StringUtils {
}
return new String(result);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.io.File;
@ -12,39 +29,40 @@ import java.util.ArrayList;
* @description:
*/
public class SystemInfo {
// ---------------------------------------------------------------- host
/**
* Delegate host info to be resolved lazy.
* Android detection will initialize this class too and since {@code InetAddress.getLocalHost()}
* is forbidden in Android, we will get an exception.
*/
private static class HostInfoLazy {
private final String HOST_NAME;
private final String HOST_ADDRESS;
public HostInfoLazy() {
String hostName;
String hostAddress;
try {
final InetAddress localhost = InetAddress.getLocalHost();
hostName = localhost.getHostName();
hostAddress = localhost.getHostAddress();
} catch (final UnknownHostException uhex) {
hostName = "localhost";
hostAddress = "127.0.0.2";
}
this.HOST_NAME = hostName;
this.HOST_ADDRESS = hostAddress;
}
}
private static HostInfoLazy hostInfoLazy;
/**
* Returns host name.
*/
@ -54,7 +72,7 @@ public class SystemInfo {
}
return hostInfoLazy.HOST_NAME;
}
/**
* Returns host IP address.
*/
@ -64,9 +82,9 @@ public class SystemInfo {
}
return hostInfoLazy.HOST_ADDRESS;
}
// ---------------------------------------------------------------- JVM
private final String JAVA_VM_NAME = SystemUtil.get("java.vm.name");
private final String JAVA_VM_VERSION = SystemUtil.get("java.vm.version");
private final String JAVA_VM_VENDOR = SystemUtil.get("java.vm.vendor");
@ -74,49 +92,49 @@ public class SystemInfo {
private final String JAVA_VM_SPECIFICATION_NAME = SystemUtil.get("java.vm.specification.name");
private final String JAVA_VM_SPECIFICATION_VERSION = SystemUtil.get("java.vm.specification.version");
private final String JAVA_VM_SPECIFICATION_VENDOR = SystemUtil.get("java.vm.specification.vendor");
/**
* Returns JVM name.
*/
public final String getJvmName() {
return JAVA_VM_NAME;
}
/**
* Returns JVM version.
*/
public final String getJvmVersion() {
return JAVA_VM_VERSION;
}
/**
* Returns VM vendor.
*/
public final String getJvmVendor() {
return JAVA_VM_VENDOR;
}
/**
* Returns additional VM information.
*/
public final String getJvmInfo() {
return JAVA_VM_INFO;
}
public final String getJvmSpecificationName() {
return JAVA_VM_SPECIFICATION_NAME;
}
public final String getJvmSpecificationVersion() {
return JAVA_VM_SPECIFICATION_VERSION;
}
public final String getJvmSpecificationVendor() {
return JAVA_VM_SPECIFICATION_VENDOR;
}
// ---------------------------------------------------------------- JAVA
private final String JAVA_VERSION = SystemUtil.get("java.version");
private final int JAVA_VERSION_NUMBER = detectJavaVersionNumber();
private final String JAVA_VENDOR = SystemUtil.get("java.vendor");
@ -125,7 +143,7 @@ public class SystemInfo {
private final String JAVA_SPECIFICATION_NAME = SystemUtil.get("java.specification.name");
private final String JAVA_SPECIFICATION_VENDOR = SystemUtil.get("java.specification.vendor");
private final String[] JRE_PACKAGES = buildJrePackages(JAVA_VERSION_NUMBER);
/**
* Returns Java version string, as specified in system property.
* Returned string contain major version, minor version and revision.
@ -133,58 +151,58 @@ public class SystemInfo {
public String getJavaVersion() {
return JAVA_VERSION;
}
/**
* Returns unified Java version as an integer.
*/
public int getJavaVersionNumber() {
return JAVA_VERSION_NUMBER;
}
/**
* Returns Java vendor.
*/
public String getJavaVendor() {
return JAVA_VENDOR;
}
/**
* Returns Java vendor URL.
*/
public String getJavaVendorURL() {
return JAVA_VENDOR_URL;
}
/**
* Retrieves the version of the currently running JVM.
*/
public String getJavaSpecificationVersion() {
return JAVA_SPECIFICATION_VERSION;
}
public final String getJavaSpecificationName() {
return JAVA_SPECIFICATION_NAME;
}
public final String getJavaSpecificationVendor() {
return JAVA_SPECIFICATION_VENDOR;
}
// ---------------------------------------------------------------- packages
/**
* Returns list of packages, build into runtime jars.
*/
public String[] getJrePackages() {
return JRE_PACKAGES;
}
/**
* Builds a set of java core packages.
*/
private String[] buildJrePackages(final int javaVersionNumber) {
final ArrayList<String> packages = new ArrayList<>();
switch (javaVersionNumber) {
case 9:
case 8:
@ -228,21 +246,20 @@ public class SystemInfo {
packages.add("javax");
break;
}
return packages.toArray(new String[0]);
}
// ---------------------------------------------------------------- java checks
private int detectJavaVersionNumber() {
String javaVersion = JAVA_VERSION;
final int lastDashNdx = javaVersion.lastIndexOf('-');
if (lastDashNdx != -1) {
javaVersion = javaVersion.substring(0, lastDashNdx);
}
if (javaVersion.startsWith("1.")) {
// up to java 8
final int index = javaVersion.indexOf('.', 2);
@ -252,7 +269,7 @@ public class SystemInfo {
return Integer.parseInt(index == -1 ? javaVersion : javaVersion.substring(0, index));
}
}
/**
* Checks if the currently running JVM is at least compliant
* with provided JDK version.
@ -260,19 +277,18 @@ public class SystemInfo {
public boolean isAtLeastJavaVersion(final int version) {
return JAVA_VERSION_NUMBER >= version;
}
/**
* Checks if the currently running JVM is equal to provided version.
*/
public boolean isJavaVersion(final int version) {
return JAVA_VERSION_NUMBER == version;
}
private final String OS_VERSION = SystemUtil.get("os.version");
private final String OS_ARCH = SystemUtil.get("os.arch");
private final String OS_NAME = SystemUtil.get("os.name");
private final boolean IS_ANDROID = isAndroid0();
private final boolean IS_OS_AIX = matchOS("AIX");
private final boolean IS_OS_HP_UX = matchOS("HP-UX");
@ -290,31 +306,31 @@ public class SystemInfo {
private final boolean IS_OS_WINDOWS_ME = matchOS("Windows", "4.9");
private final boolean IS_OS_WINDOWS_NT = matchOS("Windows NT");
private final boolean IS_OS_WINDOWS_XP = matchOS("Windows", "5.1");
private final String FILE_SEPARATOR = SystemUtil.get("file.separator");
private final String LINE_SEPARATOR = SystemUtil.get("line.separator");
private final String PATH_SEPARATOR = SystemUtil.get("path.separator");
private final String FILE_ENCODING = SystemUtil.get("file.encoding");
public final String getOsArchitecture() {
return OS_ARCH;
}
public final String getOsName() {
return OS_NAME;
}
public final String getOsVersion() {
return OS_VERSION;
}
/**
* Returns <code>true</code> if system is android.
*/
public boolean isAndroid() {
return IS_ANDROID;
}
private static boolean isAndroid0() {
try {
Class.forName("android.app.Application", false, ClassLoaderUtil.getSystemClassLoader());
@ -323,165 +339,163 @@ public class SystemInfo {
return false;
}
}
public final boolean isAix() {
return IS_OS_AIX;
}
public final boolean isHpUx() {
return IS_OS_HP_UX;
}
public final boolean isIrix() {
return IS_OS_IRIX;
}
public final boolean isLinux() {
return IS_OS_LINUX;
}
public final boolean isMac() {
return IS_OS_MAC;
}
public final boolean isMacOsX() {
return IS_OS_MAC_OSX;
}
public final boolean isOs2() {
return IS_OS_OS2;
}
public final boolean isSolaris() {
return IS_OS_SOLARIS;
}
public final boolean isSunOS() {
return IS_OS_SUN_OS;
}
public final boolean isWindows() {
return IS_OS_WINDOWS;
}
public final boolean isWindows2000() {
return IS_OS_WINDOWS_2000;
}
public final boolean isWindows95() {
return IS_OS_WINDOWS_95;
}
public final boolean isWindows98() {
return IS_OS_WINDOWS_98;
}
public final boolean isWindowsME() {
return IS_OS_WINDOWS_ME;
}
public final boolean isWindowsNT() {
return IS_OS_WINDOWS_NT;
}
public final boolean isWindowsXP() {
return IS_OS_WINDOWS_XP;
}
// ---------------------------------------------------------------- file
public final String getFileSeparator() {
return FILE_SEPARATOR;
}
public final String getLineSeparator() {
return LINE_SEPARATOR;
}
public final String getPathSeparator() {
return PATH_SEPARATOR;
}
public final String getFileEncoding() {
return FILE_ENCODING;
}
// ---------------------------------------------------------------- util
private boolean matchOS(final String osNamePrefix) {
if (OS_NAME == null) {
return false;
}
return OS_NAME.startsWith(osNamePrefix);
}
private boolean matchOS(final String osNamePrefix, final String osVersionPrefix) {
if ((OS_NAME == null) || (OS_VERSION == null)) {
return false;
}
return OS_NAME.startsWith(osNamePrefix) && OS_VERSION.startsWith(osVersionPrefix);
}
// ---------------------------------------------------------------- runtime
private final Runtime runtime = Runtime.getRuntime();
/**
* Returns MAX memory.
*/
public final long getMaxMemory(){
public final long getMaxMemory() {
return runtime.maxMemory();
}
/**
* Returns TOTAL memory.
*/
public final long getTotalMemory(){
public final long getTotalMemory() {
return runtime.totalMemory();
}
/**
* Returns FREE memory.
*/
public final long getFreeMemory(){
public final long getFreeMemory() {
return runtime.freeMemory();
}
/**
* Returns usable memory.
*/
public final long getAvailableMemory(){
public final long getAvailableMemory() {
return runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory();
}
/**
* Returns used memory.
*/
public final long getUsedMemory(){
public final long getUsedMemory() {
return runtime.totalMemory() - runtime.freeMemory();
}
/**
* Returns PID of current Java process.
*/
public final long getCurrentPID() {
return Long.parseLong(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
}
/**
* Returns number of CPUs.
*/
public final long getCPUs() {
return runtime.availableProcessors();
}
// ---------------------------------------------------------------- user
private final String USER_NAME = SystemUtil.get("user.name");
private final String USER_HOME = nosep(SystemUtil.get("user.home"));
private final String USER_DIR = nosep(SystemUtil.get("user.dir"));
@ -490,46 +504,46 @@ public class SystemInfo {
private final String JAVA_IO_TMPDIR = SystemUtil.get("java.io.tmpdir");
private final String JAVA_HOME = nosep(SystemUtil.get("java.home"));
private final String[] SYSTEM_CLASS_PATH = StringUtils.splitc(SystemUtil.get("java.class.path"), File.pathSeparator);
public final String getUserName() {
return USER_NAME;
}
public final String getHomeDir() {
return USER_HOME;
}
public final String getWorkingDir() {
return USER_DIR;
}
public final String getTempDir() {
return JAVA_IO_TMPDIR;
}
public final String getUserLanguage() {
return USER_LANGUAGE;
}
public final String getUserCountry() {
return USER_COUNTRY;
}
public String getJavaHomeDir() {
return JAVA_HOME;
}
public String[] getSystemClasspath() {
return SYSTEM_CLASS_PATH;
}
// ---------------------------------------------------------------- util
protected String nosep(final String in) {
if (in.endsWith(File.separator)) {
return in.substring(0, in.length() - 1);
}
return in;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.security.AccessController;
@ -10,20 +27,20 @@ import java.util.Objects;
* @description:
*/
public class SystemUtil {
/**
* Returns system property or {@code null} if not set.
*/
public static String get(final String name) {
return get(name, null);
}
/**
* Returns system property. If key is not available, returns the default value.
*/
public static String get(final String name, final String defaultValue) {
Objects.requireNonNull(name);
String value = null;
try {
if (System.getSecurityManager() == null) {
@ -33,14 +50,14 @@ public class SystemUtil {
}
} catch (final Exception ignore) {
}
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Returns system property as boolean.
*/
@ -49,9 +66,9 @@ public class SystemUtil {
if (value == null) {
return defaultValue;
}
value = value.trim().toLowerCase();
switch (value) {
case "true":
case "yes":
@ -67,7 +84,7 @@ public class SystemUtil {
return defaultValue;
}
}
/**
* Returns system property as an int.
*/
@ -76,7 +93,7 @@ public class SystemUtil {
if (value == null) {
return defaultValue;
}
value = value.trim().toLowerCase();
try {
return Integer.parseInt(value);
@ -84,7 +101,7 @@ public class SystemUtil {
return defaultValue;
}
}
/**
* Returns system property as a long.
*/
@ -93,7 +110,7 @@ public class SystemUtil {
if (value == null) {
return defaultValue;
}
value = value.trim().toLowerCase();
try {
return Long.parseLong(value);
@ -101,7 +118,7 @@ public class SystemUtil {
return defaultValue;
}
}
/**
* 获取CPU核数
*
@ -110,16 +127,16 @@ public class SystemUtil {
public static int getCPU() {
return Runtime.getRuntime().availableProcessors();
}
// ---------------------------------------------------------------- infos
private static final SystemInfo systemInfo = new SystemInfo();
/**
* Returns system information.
*/
public static SystemInfo info() {
return systemInfo;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.util.concurrent.ThreadFactory;
@ -11,29 +28,28 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
public class ThreadFactoryImpl implements ThreadFactory {
private final AtomicLong threadIndex = new AtomicLong(0);
private final String threadNamePrefix;
private final boolean daemon;
public ThreadFactoryImpl(final String threadNamePrefix) {
this(threadNamePrefix, false);
}
public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon) {
this.threadNamePrefix = threadNamePrefix;
this.daemon = daemon;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet());
thread.setDaemon(daemon);
thread.setUncaughtExceptionHandler((t, e) ->
log.error("Thread has an uncaught exception, threadId={}, threadName={}",
thread.setUncaughtExceptionHandler((t, e) -> log.error("Thread has an uncaught exception, threadId={}, threadName={}",
t.getId(), t.getName(), e));
return thread;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.util.concurrent.ArrayBlockingQueue;
@ -14,14 +31,14 @@ import java.util.concurrent.TimeUnit;
* @description:
*/
public class ThreadPoolBuilder {
private static final RejectedExecutionHandler defaultRejectHandler = new ThreadPoolExecutor.AbortPolicy();
/**
* cpu核数
*/
private static final int CPU = SystemUtil.getCPU();
/**
* create io ThreadPoolExecutor
*
@ -30,7 +47,7 @@ public class ThreadPoolBuilder {
public static IOThreadPoolBuilder ioThreadPoolBuilder() {
return new IOThreadPoolBuilder();
}
/**
* create cpu ThreadPoolExecutor
*
@ -39,141 +56,141 @@ public class ThreadPoolBuilder {
public static CPUThreadPoolBuilder cpuThreadPoolBuilder() {
return new CPUThreadPoolBuilder();
}
/**
* IO 类型线程池
*/
public static class IOThreadPoolBuilder {
private ThreadFactory threadFactory;
private RejectedExecutionHandler rejectHandler;
private int queueSize = -1;
private int maximumPoolSize = CPU;
private int keepAliveTime = 120;
private boolean daemon = false;
private String threadNamePrefix;
public int getCorePooSize(int ioTime, int cpuTime) {
return CPU + (1 + (ioTime / cpuTime));
}
public IOThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
public IOThreadPoolBuilder setDaemon(boolean daemon) {
this.daemon = daemon;
return this;
}
public IOThreadPoolBuilder setRejectHandler(RejectedExecutionHandler rejectHandler) {
this.rejectHandler = rejectHandler;
return this;
}
public IOThreadPoolBuilder setQueueSize(int queueSize) {
this.queueSize = queueSize;
return this;
}
public IOThreadPoolBuilder setMaximumPoolSize(int maximumPoolSize) {
this.maximumPoolSize = maximumPoolSize;
return this;
}
public IOThreadPoolBuilder setKeepAliveTime(int keepAliveTime) {
this.keepAliveTime = keepAliveTime;
return this;
}
public ThreadPoolExecutor builder(int ioTime, int cpuTime) {
BlockingQueue<Runnable> queue;
if (rejectHandler == null) {
rejectHandler = defaultRejectHandler;
}
threadFactory = new ThreadFactoryImpl(this.threadNamePrefix, this.daemon);
queue = queueSize < 1 ? new LinkedBlockingQueue<>() : new ArrayBlockingQueue<>(queueSize);
return new ThreadPoolExecutor(getCorePooSize(ioTime, cpuTime), maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, queue, threadFactory, rejectHandler);
}
}
/**
* CPU 类型线程池
*/
public static class CPUThreadPoolBuilder {
private ThreadFactory threadFactory;
private RejectedExecutionHandler rejectHandler;
private int queueSize = -1;
private int maximumPoolSize = CPU;
private int keepAliveTime = 120;
private boolean daemon = false;
private String threadNamePrefix;
public int getCorePooSize() {
return CPU;
}
public CPUThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
public CPUThreadPoolBuilder setDaemon(boolean daemon) {
this.daemon = daemon;
return this;
}
public CPUThreadPoolBuilder setRejectHandler(RejectedExecutionHandler rejectHandler) {
this.rejectHandler = rejectHandler;
return this;
}
public CPUThreadPoolBuilder setQueueSize(int queueSize) {
this.queueSize = queueSize;
return this;
}
public CPUThreadPoolBuilder setMaximumPoolSize(int maximumPoolSize) {
this.maximumPoolSize = maximumPoolSize;
return this;
}
public CPUThreadPoolBuilder setKeepAliveTime(int keepAliveTime) {
this.keepAliveTime = keepAliveTime;
return this;
}
public ThreadPoolExecutor builder() {
if (rejectHandler == null) {
rejectHandler = defaultRejectHandler;
}
threadFactory = new ThreadFactoryImpl(this.threadNamePrefix, this.daemon);
BlockingQueue<Runnable> queue = queueSize < 1 ? new LinkedBlockingQueue<>() : new ArrayBlockingQueue<>(queueSize);
return new ThreadPoolExecutor(getCorePooSize(), maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, queue, threadFactory, rejectHandler);
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils;
import java.time.Instant;
@ -12,28 +29,28 @@ import java.time.format.DateTimeFormatter;
* @description:
*/
public class TimeUtil {
public static final String YYYYMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
public static final String YYYYMMdd = "yyyy-MM-dd";
public static final String HHmmss = "HH:mm:ss";
public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(YYYYMMddHHmmss);
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(YYYYMMdd);
public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(HHmmss);
public static LocalDateTime toLocalDateTime(long unixTime, Integer zoneOffset) {
Instant instant = Instant.ofEpochMilli(unixTime);
return LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), ZoneOffset.ofHours(zoneOffset));
}
public static LocalDateTime toLocalDateTime(long unixTime) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(unixTime), ZoneId.systemDefault());
}
public static LocalDateTime toLocalDateTime(Long unixTime) {
if (DataUtils.isEmpty(unixTime)) {
return null;

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils.io;
import java.io.BufferedInputStream;
@ -22,18 +39,18 @@ import java.nio.charset.StandardCharsets;
* @description:
*/
public class IOUtil {
/**
* Buffer size for various I/O operations.
*/
public static int ioBufferSize = 16384;
private static final int ZERO = 0;
private static final int NEGATIVE_ONE = -1;
private static final int ALL = -1;
// ---------------------------------------------------------------- silent close
/**
* Closes silently the closable object. If it is {@link Flushable}, it
* will be flushed first. No exception will be thrown if an I/O error occurs.
@ -46,16 +63,16 @@ public class IOUtil {
} catch (final IOException ignored) {
}
}
try {
closeable.close();
} catch (final IOException ignored) {
}
}
}
// ---------------------------------------------------------------- copy
/**
* Copies bytes from {@link Reader} to {@link Writer} using buffer.
* {@link Reader} and {@link Writer} don't have to be wrapped to buffered, since copying is already optimized.
@ -68,19 +85,19 @@ public class IOUtil {
public static int copy(final Reader input, final Writer output) throws IOException {
final int numToRead = bufferSize();
final char[] buffer = new char[numToRead];
int totalRead = ZERO;
int read;
while ((read = input.read(buffer, ZERO, numToRead)) >= ZERO) {
output.write(buffer, ZERO, read);
totalRead = totalRead + read;
}
output.flush();
return totalRead;
}
/**
* Copies bytes from {@link InputStream} to {@link OutputStream} using buffer.
* {@link InputStream} and {@link OutputStream} don't have to be wrapped to buffered,
@ -94,19 +111,19 @@ public class IOUtil {
public static int copy(final InputStream input, final OutputStream output) throws IOException {
final int numToRead = bufferSize();
final byte[] buffer = new byte[numToRead];
int totalRead = ZERO;
int read;
while ((read = input.read(buffer, ZERO, numToRead)) >= ZERO) {
output.write(buffer, ZERO, read);
totalRead = totalRead + read;
}
output.flush();
return totalRead;
}
/**
* Copies specified number of characters from {@link Reader} to {@link Writer} using buffer.
* {@link Reader} and {@link Writer} don't have to be wrapped to buffered, since copying is already optimized.
@ -121,28 +138,28 @@ public class IOUtil {
if (count == ALL) {
return copy(input, output);
}
int numToRead = count;
final char[] buffer = new char[numToRead];
int totalRead = ZERO;
int read;
while (numToRead > ZERO) {
read = input.read(buffer, ZERO, bufferSize(numToRead));
if (read == NEGATIVE_ONE) {
break;
}
output.write(buffer, ZERO, read);
numToRead = numToRead - read;
totalRead = totalRead + read;
}
output.flush();
return totalRead;
}
/**
* Copies specified number of bytes from {@link InputStream} to {@link OutputStream} using buffer.
* {@link InputStream} and {@link OutputStream} don't have to be wrapped to buffered, since copying is already optimized.
@ -157,30 +174,30 @@ public class IOUtil {
if (count == ALL) {
return copy(input, output);
}
int numToRead = count;
final byte[] buffer = new byte[numToRead];
int totalRead = ZERO;
int read;
while (numToRead > ZERO) {
read = input.read(buffer, ZERO, bufferSize(numToRead));
if (read == NEGATIVE_ONE) {
break;
}
output.write(buffer, ZERO, read);
numToRead = numToRead - read;
totalRead = totalRead + read;
}
output.flush();
return totalRead;
}
// ---------------------------------------------------------------- read bytes
/**
* Reads all available bytes from {@link InputStream} as a byte array.
* Uses {@link InputStream#available()} to determine the size of input stream.
@ -194,44 +211,44 @@ public class IOUtil {
public static byte[] readAvailableBytes(final InputStream input) throws IOException {
final int numToRead = input.available();
final byte[] buffer = new byte[numToRead];
int totalRead = ZERO;
int read;
while ((totalRead < numToRead) && (read = input.read(buffer, totalRead, numToRead - totalRead)) >= ZERO) {
totalRead = totalRead + read;
}
if (totalRead < numToRead) {
throw new IOException("Failed to completely read InputStream");
}
return buffer;
}
// ---------------------------------------------------------------- copy to OutputStream
/**
* @see #copy(Reader, OutputStream, Charset)
*/
public static <T extends OutputStream> T copy(final Reader input, final T output) throws IOException {
return copy(input, output, encoding());
}
/**
* @see #copy(Reader, OutputStream, Charset, int)
*/
public static <T extends OutputStream> T copy(final Reader input, final T output, final int count) throws IOException {
return copy(input, output, encoding(), count);
}
/**
* @see #copy(Reader, OutputStream, Charset, int)
*/
public static <T extends OutputStream> T copy(final Reader input, final T output, final Charset encoding) throws IOException {
return copy(input, output, encoding, ALL);
}
/**
* Copies {@link Reader} to {@link OutputStream} using buffer and specified encoding.
*
@ -243,14 +260,14 @@ public class IOUtil {
return output;
}
}
/**
* @see #copyToOutputStream(InputStream, int)
*/
public static ByteArrayOutputStream copyToOutputStream(final InputStream input) throws IOException {
return copyToOutputStream(input, ALL);
}
/**
* Copies {@link InputStream} to a new {@link ByteArrayOutputStream} using buffer and specified encoding.
*
@ -262,28 +279,28 @@ public class IOUtil {
return output;
}
}
/**
* @see #copyToOutputStream(Reader, Charset)
*/
public static ByteArrayOutputStream copyToOutputStream(final Reader input) throws IOException {
return copyToOutputStream(input, encoding());
}
/**
* @see #copyToOutputStream(Reader, Charset, int)
*/
public static ByteArrayOutputStream copyToOutputStream(final Reader input, final Charset encoding) throws IOException {
return copyToOutputStream(input, encoding, ALL);
}
/**
* @see #copyToOutputStream(Reader, Charset, int)
*/
public static ByteArrayOutputStream copyToOutputStream(final Reader input, final int count) throws IOException {
return copyToOutputStream(input, encoding(), count);
}
/**
* Copies {@link Reader} to a new {@link ByteArrayOutputStream} using buffer and specified encoding.
*
@ -295,30 +312,30 @@ public class IOUtil {
return output;
}
}
// ---------------------------------------------------------------- copy to Writer
/**
* @see #copy(InputStream, Writer, Charset)
*/
public static <T extends Writer> T copy(final InputStream input, final T output) throws IOException {
return copy(input, output, encoding());
}
/**
* @see #copy(InputStream, Writer, Charset, int)
*/
public static <T extends Writer> T copy(final InputStream input, final T output, final int count) throws IOException {
return copy(input, output, encoding(), count);
}
/**
* @see #copy(InputStream, Writer, Charset, int)
*/
public static <T extends Writer> T copy(final InputStream input, final T output, final Charset encoding) throws IOException {
return copy(input, output, encoding, ALL);
}
/**
* Copies {@link InputStream} to {@link Writer} using buffer and specified encoding.
*
@ -328,28 +345,28 @@ public class IOUtil {
copy(inputStreamReadeOf(input, encoding), output, count);
return output;
}
/**
* @see #copy(InputStream, Charset)
*/
public static CharArrayWriter copy(final InputStream input) throws IOException {
return copy(input, encoding());
}
/**
* @see #copy(InputStream, Charset, int)
*/
public static CharArrayWriter copy(final InputStream input, final int count) throws IOException {
return copy(input, encoding(), count);
}
/**
* @see #copy(InputStream, Charset, int)
*/
public static CharArrayWriter copy(final InputStream input, final Charset encoding) throws IOException {
return copy(input, encoding, ALL);
}
/**
* Copies {@link InputStream} to a new {@link CharArrayWriter} using buffer and specified encoding.
*
@ -361,14 +378,14 @@ public class IOUtil {
return output;
}
}
/**
* @see #copy(Reader, int)
*/
public static CharArrayWriter copy(final Reader input) throws IOException {
return copy(input, ALL);
}
/**
* Copies {@link Reader} to a new {@link CharArrayWriter} using buffer and specified encoding.
*
@ -380,97 +397,97 @@ public class IOUtil {
return output;
}
}
// ---------------------------------------------------------------- read bytes
/**
* @see #readBytes(InputStream, int)
*/
public static byte[] readBytes(final InputStream input) throws IOException {
return readBytes(input, ALL);
}
/**
* @see #copyToOutputStream(InputStream, int)
*/
public static byte[] readBytes(final InputStream input, final int count) throws IOException {
return copyToOutputStream(input, count).toByteArray();
}
/**
* @see #readBytes(Reader, Charset)
*/
public static byte[] readBytes(final Reader input) throws IOException {
return readBytes(input, encoding());
}
/**
* @see #readBytes(Reader, Charset, int)
*/
public static byte[] readBytes(final Reader input, final int count) throws IOException {
return readBytes(input, encoding(), count);
}
/**
* @see #readBytes(Reader, Charset, int)
*/
public static byte[] readBytes(final Reader input, final Charset encoding) throws IOException {
return readBytes(input, encoding, ALL);
}
/**
* @see #copyToOutputStream(Reader, Charset, int)
*/
public static byte[] readBytes(final Reader input, final Charset encoding, final int count) throws IOException {
return copyToOutputStream(input, encoding, count).toByteArray();
}
// ---------------------------------------------------------------- read chars
/**
* @see #readChars(Reader, int)
*/
public static char[] readChars(final Reader input) throws IOException {
return readChars(input, ALL);
}
/**
* @see #copy(Reader, int)
*/
public static char[] readChars(final Reader input, final int count) throws IOException {
return copy(input, count).toCharArray();
}
/**
* @see #readChars(InputStream, int)
*/
public static char[] readChars(final InputStream input) throws IOException {
return readChars(input, ALL);
}
/**
* @see #readChars(InputStream, Charset, int)
*/
public static char[] readChars(final InputStream input, final Charset encoding) throws IOException {
return readChars(input, encoding, ALL);
}
/**
* @see #readChars(InputStream, Charset, int)
*/
public static char[] readChars(final InputStream input, final int count) throws IOException {
return readChars(input, encoding(), count);
}
/**
* @see #copy(InputStream, Charset, int)
*/
public static char[] readChars(final InputStream input, final Charset encoding, final int count) throws IOException {
return copy(input, encoding, count).toCharArray();
}
// ---------------------------------------------------------------- compare content
/**
* Compares the content of two byte streams ({@link InputStream}s).
*
@ -495,7 +512,7 @@ public class IOUtil {
final int ch2 = input2.read();
return (ch2 == NEGATIVE_ONE);
}
/**
* Compares the content of two character streams ({@link Reader}s).
*
@ -509,7 +526,7 @@ public class IOUtil {
if (!(input2 instanceof BufferedReader)) {
input2 = new BufferedReader(input2);
}
int ch = input1.read();
while (ch != NEGATIVE_ONE) {
final int ch2 = input2.read();
@ -521,9 +538,9 @@ public class IOUtil {
final int ch2 = input2.read();
return (ch2 == NEGATIVE_ONE);
}
// ---------------------------------------------------------------- defaults
/**
* Returns default IO buffer size.
*
@ -532,7 +549,7 @@ public class IOUtil {
private static int bufferSize() {
return ioBufferSize;
}
/**
* Returns either count or default IO buffer size (whichever is smaller).
*
@ -543,16 +560,16 @@ public class IOUtil {
final int ioBufferSize = IOUtil.ioBufferSize;
return Math.min(count, ioBufferSize);
}
/**
* Returns default encoding.
*/
private static Charset encoding() {
return StandardCharsets.UTF_8;
}
// ---------------------------------------------------------------- wrappers
/**
* Returns new {@link CharArrayWriter} using default IO buffer size.
*
@ -561,18 +578,18 @@ public class IOUtil {
private static CharArrayWriter createFastCharArrayWriter() {
return new CharArrayWriter(bufferSize());
}
private static ByteArrayOutputStream createFastByteArrayOutputStream() {
return new ByteArrayOutputStream(bufferSize());
}
/**
* @see #inputStreamReadeOf(InputStream, Charset)
*/
public static InputStreamReader inputStreamReadeOf(final InputStream input) {
return inputStreamReadeOf(input, encoding());
}
/**
* Returns new {@link InputStreamReader} using specified {@link InputStream} and encoding.
*
@ -583,14 +600,14 @@ public class IOUtil {
public static InputStreamReader inputStreamReadeOf(final InputStream input, final Charset encoding) {
return new InputStreamReader(input, encoding);
}
/**
* @see #outputStreamWriterOf(OutputStream, Charset)
*/
public static OutputStreamWriter outputStreamWriterOf(final OutputStream output) {
return outputStreamWriterOf(output, encoding());
}
/**
* Returns new {@link OutputStreamWriter} using specified {@link OutputStream} and encoding.
*

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.base.utils.io;
import java.io.IOException;
@ -11,16 +28,16 @@ import java.nio.charset.StandardCharsets;
* @date : 2022/1/14 13:55
* @description:
*/
public class UnicodeInputStream extends InputStream{
public class UnicodeInputStream extends InputStream {
public static final int MAX_BOM_SIZE = 4;
private final PushbackInputStream internalInputStream;
private boolean initialized;
private int BOMSize = -1;
private Charset encoding;
private final Charset targetEncoding;
/**
* Creates new unicode stream. It works in two modes: detect mode and read mode.
* <p>
@ -35,7 +52,7 @@ public class UnicodeInputStream extends InputStream{
internalInputStream = new PushbackInputStream(in, MAX_BOM_SIZE);
this.targetEncoding = targetEncoding;
}
/**
* Returns detected UTF encoding or {@code null} if no UTF encoding has been detected (i.e. no BOM).
* If stream is not read yet, it will be {@link #init() initalized} first.
@ -50,13 +67,13 @@ public class UnicodeInputStream extends InputStream{
}
return encoding;
}
public static final byte[] BOM_UTF32_BE = new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0xFE, (byte) 0xFF};
public static final byte[] BOM_UTF32_LE = new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00};
public static final byte[] BOM_UTF8 = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
public static final byte[] BOM_UTF16_BE = new byte[]{(byte) 0xFE, (byte) 0xFF};
public static final byte[] BOM_UTF16_LE = new byte[]{(byte) 0xFF, (byte) 0xFE};
/**
* Detects and decodes encoding from BOM character.
* Reads ahead four bytes and check for BOM marks.
@ -67,15 +84,15 @@ public class UnicodeInputStream extends InputStream{
if (initialized) {
return;
}
if (targetEncoding == null) {
// DETECT MODE
final byte[] bom = new byte[MAX_BOM_SIZE];
final int n = internalInputStream.read(bom, 0, bom.length);
final int unread;
if ((bom[0] == BOM_UTF32_BE[0]) && (bom[1] == BOM_UTF32_BE[1]) && (bom[2] == BOM_UTF32_BE[2]) && (bom[3] == BOM_UTF32_BE[3])) {
encoding = Charset.forName("UTF-32BE");
unread = n - 4;
@ -95,20 +112,20 @@ public class UnicodeInputStream extends InputStream{
// BOM not found, unread all bytes
unread = n;
}
BOMSize = MAX_BOM_SIZE - unread;
if (unread > 0) {
internalInputStream.unread(bom, (n - unread), unread);
}
} else {
// READ MODE
byte[] bom = null;
final String targetEncodingName = targetEncoding.name();
switch (targetEncodingName) {
case "UTF-8":
bom = BOM_UTF8;
@ -131,11 +148,11 @@ public class UnicodeInputStream extends InputStream{
// no UTF encoding, no BOM
break;
}
if (bom != null) {
final byte[] fileBom = new byte[bom.length];
final int n = internalInputStream.read(fileBom, 0, bom.length);
boolean bomDetected = true;
for (int i = 0; i < n; i++) {
if (fileBom[i] != bom[i]) {
@ -143,16 +160,16 @@ public class UnicodeInputStream extends InputStream{
break;
}
}
if (!bomDetected) {
internalInputStream.unread(fileBom, 0, fileBom.length);
}
}
}
initialized = true;
}
/**
* Closes input stream. If stream was not used, encoding
* will be unavailable.
@ -161,7 +178,7 @@ public class UnicodeInputStream extends InputStream{
public void close() throws IOException {
internalInputStream.close();
}
/**
* Reads byte from the stream.
*/
@ -170,7 +187,7 @@ public class UnicodeInputStream extends InputStream{
init();
return internalInputStream.read();
}
/**
* Returns BOM size in bytes.
* Returns <code>-1</code> if BOM not found.
@ -178,5 +195,5 @@ public class UnicodeInputStream extends InputStream{
public int getBOMSize() {
return BOMSize;
}
}

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -11,8 +10,6 @@
<name>spring-boot-nebula-dependencies</name>
<description>spring boot 基础组件,快速构建spring boot项目</description>
<url>https://github.com/weihubeats/spring-boot-common</url>
<properties>
<revision>0.0.01</revision>
@ -29,6 +26,8 @@
<javers-core.version>6.6.5</javers-core.version>
<mybatis-plus-boot-starter.version>3.5.5</mybatis-plus-boot-starter.version>
<redission.version>3.17.3</redission.version>
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
</properties>
@ -116,38 +115,10 @@
<version>${redission.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>weihubeats</name>
<email>weihu@apche.org</email>
<organization>https://weihubeats.blog.csdn.net/</organization>
</developer>
</developers>
<scm>
<connection>scm:git@github.com:weihubeats/spring-boot-common.git</connection>
<developerConnection>scm:git@github.com:weihubeats/spring-boot-common.git</developerConnection>
<url>git@github.com:weihubeats/spring-boot-common.git</url>
</scm>
<issueManagement>
<system>Github Issue</system>
<url>https://github.com/weihubeats/spring-boot-common/issues</url>
</issueManagement>
<build>
<plugins>
<plugin>
@ -180,10 +151,10 @@
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
@ -205,10 +176,10 @@
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
@ -220,10 +191,10 @@
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
@ -239,33 +210,100 @@
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
<phase>process-resources</phase>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
<phase>clean</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless-maven-plugin.version}</version>
<configuration>
<java>
<eclipse>
<file>${maven.multiModuleProjectDirectory}/dev-support/spotless_nebula_formatter.xml</file>
</eclipse>
<licenseHeader>
<file>${maven.multiModuleProjectDirectory}/dev-support/license-header</file>
</licenseHeader>
</java>
<pom>
<sortPom>
<encoding>UTF-8</encoding>
<nrOfIndentSpace>4</nrOfIndentSpace>
<keepBlankLines>true</keepBlankLines>
<indentBlankLines>false</indentBlankLines>
<indentSchemaLocation>true</indentSchemaLocation>
<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>
<sortModules>false</sortModules>
<sortExecutions>false</sortExecutions>
<predefinedSortOrder>custom_1</predefinedSortOrder>
<expandEmptyElements>false</expandEmptyElements>
<sortProperties>false</sortProperties>
</sortPom>
</pom>
</configuration>
<executions>
<execution>
<goals>
<goal>apply</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
<url>https://github.com/weihubeats/spring-boot-common</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>weihubeats</name>
<email>weihu@apche.org</email>
<organization>https://weihubeats.blog.csdn.net/</organization>
</developer>
</developers>
<scm>
<connection>scm:git@github.com:weihubeats/spring-boot-common.git</connection>
<developerConnection>scm:git@github.com:weihubeats/spring-boot-common.git</developerConnection>
<url>git@github.com:weihubeats/spring-boot-common.git</url>
</scm>
<issueManagement>
<system>Github Issue</system>
<url>https://github.com/weihubeats/spring-boot-common/issues</url>
</issueManagement>
<distributionManagement>
<snapshotRepository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
</project>

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -41,4 +40,4 @@
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.annotation;
import java.lang.annotation.Documented;
@ -16,50 +33,50 @@ import java.util.concurrent.TimeUnit;
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NebulaDistributedLock {
/**
* 锁名字
*/
String lockName() default "";
/**
* 锁前缀
*/
String lockNamePre() default "";
/**
* 锁后缀
*/
String lockNamePost() default "";
/**
* 锁前后缀拼接分隔符
*/
String separator() default "_";
/**
* 是否使用公平锁
*/
boolean fairLock() default false;
/**
* 是否使用尝试锁
*/
boolean tryLock() default false;
/**
* 尝试锁最长等待时间
*/
long tryWaitTime() default 30L;
/**
* 锁超时时间超时自动释放锁
*/
long outTime() default 20L;
/**
* 时间单位 默认秒
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.aop;
import com.nebula.base.utils.DataUtils;
@ -20,16 +37,16 @@ import org.aopalliance.intercept.MethodInvocation;
*/
@Slf4j
public class NebulaDistributedLockAnnotationInterceptor implements MethodInterceptor {
private final NebulaDistributedLockTemplate lock;
public NebulaDistributedLockAnnotationInterceptor(NebulaDistributedLockTemplate lock) {
if (DataUtils.isEmpty(lock)) {
throw new RuntimeException("DistributedLockTemplate is null");
}
this.lock = lock;
}
@Nullable
@Override
public Object invoke(@Nonnull MethodInvocation methodInvocation) {
@ -43,11 +60,12 @@ public class NebulaDistributedLockAnnotationInterceptor implements MethodInterce
boolean fairLock = annotation.fairLock();
if (annotation.tryLock()) {
return lock.tryLock(new DistributedLock<>() {
@Override
public Object process() {
return proceed(methodInvocation);
}
@Override
public String lockName() {
return lockName;
@ -55,11 +73,12 @@ public class NebulaDistributedLockAnnotationInterceptor implements MethodInterce
}, annotation.tryWaitTime(), annotation.outTime(), annotation.timeUnit(), fairLock);
} else {
return lock.lock(new DistributedLock<>() {
@Override
public Object process() {
return proceed(methodInvocation);
}
@Override
public String lockName() {
return lockName;
@ -67,16 +86,16 @@ public class NebulaDistributedLockAnnotationInterceptor implements MethodInterce
}, annotation.outTime(), annotation.timeUnit(), fairLock);
}
}
public Object proceed(MethodInvocation methodInvocation) {
try {
return methodInvocation.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* 获取锁名字优先获取注解中锁名
*
@ -92,14 +111,14 @@ public class NebulaDistributedLockAnnotationInterceptor implements MethodInterce
String lockNamePre = nebulaDistributedLock.lockNamePre();
String lockNamePost = nebulaDistributedLock.lockNamePost();
String separator = nebulaDistributedLock.separator();
if (ExpressionUtil.isEl(lockNamePre)) {
lockNamePre = (String) ExpressionUtil.parse(lockNamePre, method, args);
}
if (ExpressionUtil.isEl(lockNamePost)) {
lockNamePost = Objects.requireNonNull(ExpressionUtil.parse(lockNamePost, method, args)).toString();
}
StringBuilder sb = new StringBuilder();
if (DataUtils.isNotEmpty(lockNamePre)) {
sb.append(lockNamePre);

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.autoconfigure;
import com.nebula.aop.base.NebulaBaseAnnotationAdvisor;
@ -18,18 +35,18 @@ import org.springframework.core.annotation.Order;
*/
@Configuration(proxyBeanMethods = false)
public class NebulaDistributedLockAutoConfiguration {
@Bean
public RedissonDistributedLockTemplate redissonDistributedLockTemplate(RedissonClient redissonClient) {
RedissonDistributedLockTemplate template = new RedissonDistributedLockTemplate(redissonClient);
return template;
}
@Bean
@Order(1)
public Advisor distributedLockAnnotationAdvisor(NebulaDistributedLockTemplate nebulaDistributedLockTemplate) {
NebulaDistributedLockAnnotationInterceptor advisor = new NebulaDistributedLockAnnotationInterceptor(nebulaDistributedLockTemplate);
return new NebulaBaseAnnotationAdvisor(advisor, NebulaDistributedLock.class);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.core;
/**
@ -6,11 +23,11 @@ package com.nebula.distribute.lock.core;
* @description:
*/
public interface DistributedLock<T> {
/**
* 分布式锁逻辑 代码块
*/
T process();
String lockName();
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.core;
import java.util.concurrent.TimeUnit;
@ -8,7 +25,7 @@ import java.util.concurrent.TimeUnit;
* @description:
*/
public interface NebulaDistributedLockTemplate {
/**
* 默认超时锁释放时间
*/
@ -16,12 +33,12 @@ public interface NebulaDistributedLockTemplate {
/**
* 默认尝试加锁时间
*/
long DEFAULT_TRY_OUT_TIME = 30;
long DEFAULT_TRY_OUT_TIME = 30;
/**
* 默认时间单位
*/
TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;
/**
* 加锁
* @param distributedLock
@ -30,7 +47,7 @@ public interface NebulaDistributedLockTemplate {
* @return
*/
<T> T lock(DistributedLock<T> distributedLock, boolean fairLock);
/**
*
* @param distributedLock
@ -41,7 +58,7 @@ public interface NebulaDistributedLockTemplate {
* @return
*/
<T> T lock(DistributedLock<T> distributedLock, long outTime, TimeUnit timeUnit, boolean fairLock);
/**
* 尝试加锁
* @param distributedLock
@ -50,7 +67,7 @@ public interface NebulaDistributedLockTemplate {
* @return
*/
<T> T tryLock(DistributedLock<T> distributedLock, boolean fairLock);
/**
*
* @param distributedLock
@ -62,6 +79,5 @@ public interface NebulaDistributedLockTemplate {
* @return
*/
<T> T tryLock(DistributedLock<T> distributedLock, long tryOutTime, long outTime, TimeUnit timeUnit, boolean fairLock);
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.core;
import com.nebula.distribute.lock.exception.DistributedLockException;
@ -15,14 +32,14 @@ import org.redisson.api.RedissonClient;
@Slf4j
@RequiredArgsConstructor
public class RedissonDistributedLockTemplate implements NebulaDistributedLockTemplate {
private final RedissonClient redisson;
@Override
public <T> T lock(DistributedLock<T> distributedLock, boolean fairLock) {
return lock(distributedLock, DEFAULT_OUT_TIME, DEFAULT_TIME_UNIT, fairLock);
}
@Override
public <T> T lock(DistributedLock<T> distributedLock, long outTime, TimeUnit timeUnit, boolean fairLock) {
RLock lock = getLock(distributedLock.lockName(), fairLock);
@ -35,15 +52,15 @@ public class RedissonDistributedLockTemplate implements NebulaDistributedLockTem
}
}
}
@Override
public <T> T tryLock(DistributedLock<T> distributedLock, boolean fairLock) {
return tryLock(distributedLock, DEFAULT_TRY_OUT_TIME, DEFAULT_OUT_TIME, DEFAULT_TIME_UNIT, fairLock);
}
@Override
public <T> T tryLock(DistributedLock<T> distributedLock, long tryOutTime, long outTime, TimeUnit timeUnit,
boolean fairLock) {
boolean fairLock) {
String lockName = distributedLock.lockName();
RLock lock = getLock(lockName, fairLock);
try {
@ -66,9 +83,9 @@ public class RedissonDistributedLockTemplate implements NebulaDistributedLockTem
}
throw new DistributedLockException("lock fail");
}
private RLock getLock(String lockName, boolean fairLock) {
return fairLock ? redisson.getFairLock(lockName) : redisson.getLock(lockName);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.exception;
/**
@ -6,7 +23,7 @@ package com.nebula.distribute.lock.exception;
* @description:
*/
public class DistributedLockException extends RuntimeException {
public DistributedLockException(String message) {
super(message);
}

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -30,4 +29,4 @@
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.mybatis.entity;
import java.time.LocalDateTime;
@ -10,7 +27,7 @@ import java.time.LocalDateTime;
public class BaseDO {
private Long id;
/**
* 创建时间
*/

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.mybatis.handler;
import java.math.BigDecimal;
@ -21,15 +38,16 @@ import org.apache.ibatis.type.TypeException;
@MappedJdbcTypes(JdbcType.ARRAY)
@MappedTypes({Integer[].class, String[].class, Boolean[].class, Double[].class, Long[].class, BigDecimal[].class})
public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
private static final String TYPE_NAME_VARCHAR = "varchar";
private static final String TYPE_NAME_INTEGER = "integer";
private static final String TYPE_NAME_BOOLEAN = "boolean";
private static final String TYPE_NAME_NUMERIC = "numeric";
private static final String TYPE_NAME_BIGINT = "bigint";
@Override
public void setNonNullParameter(
PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException {
PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException {
String typeName = null;
if (parameter instanceof Integer[]) {
typeName = TYPE_NAME_INTEGER;
@ -44,31 +62,31 @@ public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
} else if (parameter instanceof BigDecimal[]) {
typeName = TYPE_NAME_NUMERIC;
}
if (typeName == null) {
throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
}
Connection conn = ps.getConnection();
Array array = conn.createArrayOf(typeName, parameter);
ps.setArray(i, array);
}
@Override
public Object[] getNullableResult(ResultSet resultSet, String s) throws SQLException {
return getArray(resultSet.getArray(s));
}
@Override
public Object[] getNullableResult(ResultSet resultSet, int i) throws SQLException {
return getArray(resultSet.getArray(i));
}
@Override
public Object[] getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
return getArray(callableStatement.getArray(i));
}
private Object[] getArray(Array array) {
if (array == null) {
return null;
@ -79,5 +97,5 @@ public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
}
return null;
}
}

View File

@ -1,26 +1,25 @@
<?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"
<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>
<artifactId>spring-boot-nebula</artifactId>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-nebula-samples</artifactId>
<packaging>pom</packaging>
<modules>
<module>spring-boot-nebula-web-sample</module>
<module>spring-boot-nebula-distribute-lock-sample</module>
</modules>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<artifactId>spring-boot-nebula-samples</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
</project>
</project>

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -30,4 +29,4 @@
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.sample;
import java.util.TimeZone;
@ -10,7 +27,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
*/
@SpringBootApplication
public class DistributeLockApplication {
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
SpringApplication.run(DistributeLockApplication.class, args);

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.sample.config;
import com.nebula.base.utils.DataUtils;
@ -17,20 +34,19 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
public class RedissonConfig {
@Value("${redis.host}")
private String redisLoginHost;
@Value("${redis.port}")
private Integer redisLoginPort;
@Value("${redis.password}")
private String redisLoginPassword;
@Bean
public RedissonClient redissonClient() {
return createRedis(redisLoginHost, redisLoginPort, redisLoginPassword);
}
private RedissonClient createRedis(String redisHost, Integer redisPort, String redisPassword) {
Config config = new Config();
SingleServerConfig singleServerConfig = config.useSingleServer();

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.sample.controller;
import com.nebula.distribute.lock.sample.service.TestService;
@ -18,11 +35,10 @@ import org.springframework.web.bind.annotation.RestController;
public class TestController {
private final TestService testServcie;
@GetMapping("/test")
@NebulaResponseBody
public String test() throws Exception{
public String test() throws Exception {
testServcie.test();
return "小奏";
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.distribute.lock.sample.service;
import com.nebula.distribute.lock.annotation.NebulaDistributedLock;
@ -11,7 +28,7 @@ import org.springframework.stereotype.Service;
*/
@Service
public class TestService {
@NebulaDistributedLock(lockName = "wh-test")
public void test() {
System.out.println("处理器请求中");

View File

@ -1,3 +1,4 @@
<?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>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.sample;
import java.util.TimeZone;
@ -10,7 +27,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
*/
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
SpringApplication.run(WebApplication.class, args);

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.sample.controller;
import com.nebula.web.boot.annotation.NebulaResponseBody;
@ -13,7 +30,6 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping()
public class TestController {
@GetMapping("/test")
@NebulaResponseBody

View File

@ -1,6 +1,5 @@
<?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"
<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>
@ -16,9 +15,9 @@
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -28,7 +27,20 @@
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.common.autoconfigure;
import com.nebula.web.common.utils.NebulaSysWebUtils;
@ -19,9 +36,8 @@ public class NebulaWebCommonAutoConfiguration {
}
@Bean
public NebulaSysWebUtils nebulaSysWebUtils() {
public NebulaSysWebUtils nebulaSysWebUtils() {
return new NebulaSysWebUtils();
}
}

View File

@ -1,9 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.common.utils;
import com.nebula.base.utils.DataUtils;
import java.lang.reflect.Method;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@ -15,7 +31,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
* @description:
*/
public class ExpressionUtil {
/**
* el表达式解析
*
@ -28,8 +44,9 @@ public class ExpressionUtil {
if (DataUtils.isEmpty(expressionString)) {
return null;
}
//获取被拦截方法参数名列表
// 获取被拦截方法参数名列表
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
// SPEL解析
String[] paramNames = discoverer.getParameterNames(method);
if (paramNames == null || args == null || paramNames.length != args.length) {
throw new IllegalArgumentException("Method parameter names and argument values do not match.");
@ -42,7 +59,7 @@ public class ExpressionUtil {
}
return parser.parseExpression(expressionString).getValue(context);
}
public static boolean isEl(String param) {
return !StringUtils.isEmpty(param) && param.startsWith("#");
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.common.utils;
import java.util.Objects;
@ -13,41 +30,41 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "nebula")
@Data
public class NebulaSysWebUtils {
private static final String DEV = "dev";
private static final String TEST = "test";
private static final String STAGE = "stage";
private static final String PRD = "prd";
/**
* 开发环境
*/
@Value("${spring.profiles.active:dev}")
private String active;
/**
* 服务名
*/
@Value("${spring.application.name:unknown}")
private String applicationName;
public boolean isDev() {
return Objects.equals(active, DEV);
}
public boolean isTest() {
return Objects.equals(active, TEST);
}
public boolean isPrd() {
return Objects.equals(active, PRD);
}
public boolean isStage() {
return Objects.equals(active, STAGE);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.common.utils;
import org.springframework.beans.BeansException;
@ -10,32 +27,32 @@ import org.springframework.context.ApplicationContextAware;
* @description:
*/
public class SpringBeanUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtils.applicationContext = applicationContext;
}
private static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
public static boolean containsBean(Class clazz) {
return getApplicationContext().getBeanNamesForType(clazz).length > 0;
}
}

View File

@ -0,0 +1,53 @@
package com.nebula.web.common.utils;
import com.nebula.web.common.autoconfigure.NebulaWebCommonAutoConfiguration;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author : wh
* @date : 2024/3/28 09:45
* @description:
*/
@SpringBootTest(classes = SpringBeanUtilsTest.TestConfig.class)
public class SpringBeanUtilsTest {
@Test
public void getBean() {
Object bean = SpringBeanUtils.getBean("testBean");
assertTrue(bean instanceof TestBean);
TestBean bean1 = SpringBeanUtils.getBean(TestBean.class);
assertTrue(Objects.nonNull(bean1));
assertThrowsExactly(NoSuchBeanDefinitionException.class, () -> SpringBeanUtils.getBean(NoTestBean.class));
}
static final class TestBean {
}
static final class NoTestBean {
}
@Configuration
@EnableAutoConfiguration
@ImportAutoConfiguration({NebulaWebCommonAutoConfiguration.class})
public static class TestConfig {
@Bean
public TestBean testBean() {
return new TestBean();
}
}
}

View File

@ -1,29 +1,28 @@
<?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"
<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>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-nebula-web</artifactId>
<dependencies>
<dependency>
<groupId>io.github.weihubeats</groupId>
<artifactId>spring-boot-nebula-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
@ -34,8 +33,7 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.annotation;
import java.lang.annotation.Documented;
@ -15,7 +32,7 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GetTimestamp {
String name() default "";
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.annotation;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -14,12 +31,12 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NebulaResponseBody {
/**
* objectMapper
*
* @return
*/
Class<? extends ObjectMapper> objectMapper() default JsonUtil.JacksonObjectMapper.class;
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.api;
import java.io.Serializable;
@ -8,14 +25,14 @@ import java.io.Serializable;
* @description:
*/
public interface IResultCode extends Serializable {
/**
* 消息
*
* @return String
*/
String getMessage();
/**
* 状态码
*

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.api;
import java.util.Collection;
@ -11,28 +28,28 @@ import java.util.stream.Collectors;
* @description: 基础分页对象
*/
public class NebulaPage<T> {
private long totalCount = 0;
private int pageSize = 1;
private Collection<T> list;
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
if (pageSize < 1) {
return 1;
}
return pageSize;
}
public void setPageSize(int pageSize) {
if (pageSize < 1) {
this.pageSize = 1;
@ -40,15 +57,15 @@ public class NebulaPage<T> {
this.pageSize = pageSize;
}
}
public Collection<T> getList() {
return list;
}
public void setList(Collection<T> list) {
this.list = list;
}
/**
* 构造器
*
@ -65,7 +82,7 @@ public class NebulaPage<T> {
page.setPageSize(pageSize);
return page;
}
/**
* 内存分页
*
@ -76,14 +93,14 @@ public class NebulaPage<T> {
*/
public static <T> NebulaPage<T> ofMemory(Collection<T> list, NebulaPageQuery pageQuery) {
List<T> pageList = list.stream().skip((long) (pageQuery.getPageIndex() - 1) * pageQuery.getPageSize())
.limit(pageQuery.getPageSize()).collect(Collectors.toList());
.limit(pageQuery.getPageSize()).collect(Collectors.toList());
NebulaPage<T> page = new NebulaPage<>();
page.setList(pageList);
page.setTotalCount(list.size());
page.setPageSize(pageQuery.getPageSize());
return page;
}
public static <T, R> NebulaPage<R> copy(NebulaPage<T> source, Function<T, R> converterFunction) {
NebulaPage<R> Page = new NebulaPage<>();
Page.setList(source.getList().stream().map(converterFunction).collect(Collectors.toList()));
@ -91,5 +108,5 @@ public class NebulaPage<T> {
Page.setPageSize(source.getPageSize());
return Page;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.api;
/**
@ -6,84 +23,84 @@ package com.nebula.web.boot.api;
* @description:
*/
public abstract class NebulaPageQuery {
public static final String ASC = "ASC";
public static final String DESC = "DESC";
private static final int DEFAULT_PAGE_SIZE = 20;
private Integer pageSize = DEFAULT_PAGE_SIZE;
private Integer pageIndex = 1;
private String orderBy;
private String orderDirection = DESC;
private String groupBy;
private boolean needTotalCount = true;
public int getPageIndex() {
if (pageIndex < 1) {
return 1;
}
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
if (pageSize < 1) {
pageSize = DEFAULT_PAGE_SIZE;
}
return pageSize;
}
public void setPageSize(int pageSize) {
if (pageSize < 1) {
pageSize = DEFAULT_PAGE_SIZE;
}
this.pageSize = pageSize;
}
public int getOffset() {
return (getPageIndex() - 1) * getPageSize();
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
if (ASC.equalsIgnoreCase(orderDirection) || DESC.equalsIgnoreCase(orderDirection)) {
this.orderDirection = orderDirection;
}
}
public String getGroupBy() {
return groupBy;
}
public void setGroupBy(String groupBy) {
this.groupBy = groupBy;
}
public boolean isNeedTotalCount() {
return needTotalCount;
}
public void setNeedTotalCount(boolean needTotalCount) {
this.needTotalCount = needTotalCount;
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.api;
import com.nebula.web.boot.enums.ResultCode;
@ -21,45 +38,44 @@ import org.springframework.lang.Nullable;
@Getter
@Setter
public class NebulaResponse<T> implements Serializable {
/**
* 状态码
*/
private int code;
/**
* 返回数据
*/
private T data;
/**
* 返回消息
*/
private String msg;
private NebulaResponse(IResultCode resultCode) {
this(resultCode, null, resultCode.getMessage());
}
private NebulaResponse(IResultCode resultCode, String msg) {
this(resultCode, null, msg);
}
private NebulaResponse(IResultCode resultCode, T data) {
this(resultCode, data, resultCode.getMessage());
}
private NebulaResponse(IResultCode resultCode, T data, String msg) {
this(resultCode.getCode(), data, msg);
}
private NebulaResponse(int code, T data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
/**
* 请求是否成功
* @param result
@ -70,7 +86,7 @@ public class NebulaResponse<T> implements Serializable {
.map(x -> Objects.equals(ResultCode.SUCCESS.getCode(), x.code))
.orElse(Boolean.FALSE);
}
/**
* 获取 data
* @return
@ -85,13 +101,13 @@ public class NebulaResponse<T> implements Serializable {
}
return this.data;
}
private boolean isBizException(NebulaResponse<T> NebulaResponse) {
return Optional.ofNullable(NebulaResponse)
.map(x -> Objects.equals(ResultCode.BIZ_EXCEPTION.getCode(), x.code))
.orElse(Boolean.FALSE);
}
/**
* 请求是否失败
* @param result
@ -100,7 +116,7 @@ public class NebulaResponse<T> implements Serializable {
public static boolean isNotSuccess(@Nullable NebulaResponse<?> result) {
return !NebulaResponse.isSuccess(result);
}
/**
* 返回R
*
@ -112,7 +128,7 @@ public class NebulaResponse<T> implements Serializable {
public static <T extends Serializable> NebulaResponse<T> data(T data, String msg) {
return data(HttpServletResponse.SC_OK, data, msg);
}
/**
* 返回R
*
@ -125,15 +141,15 @@ public class NebulaResponse<T> implements Serializable {
public static <T extends Serializable> NebulaResponse<T> data(int code, T data, String msg) {
return new NebulaResponse<>(code, data, data == null ? "no data" : msg);
}
public static <T> NebulaResponse<T> fail(IResultCode resultCode, String msg) {
return new NebulaResponse<>(resultCode, msg);
}
public static <T> NebulaResponse<T> fail(IResultCode resultCode) {
return new NebulaResponse<>(resultCode, resultCode.getMessage());
}
/**
* 返回R
*
@ -144,8 +160,5 @@ public class NebulaResponse<T> implements Serializable {
public static <T> NebulaResponse<T> fail(String msg) {
return new NebulaResponse<>(ResultCode.FAILURE, msg);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.config;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -27,17 +44,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration(proxyBeanMethods = false)
@AllArgsConstructor
public class BaseWebMvcConfig implements WebMvcConfigurer {
private final ObjectMapper objectMapper;
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
returnValueHandlers.add(new NebulaResponseBodyHandleReturnValue());
}
/**
* 使用 JACKSON 作为JSON MessageConverter
* @param converters
@ -51,10 +65,10 @@ public class BaseWebMvcConfig implements WebMvcConfigurer {
converters.add(new ResourceRegionHttpMessageConverter());
converters.add(new MappingApiJackson2HttpMessageConverter(objectMapper));
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new TimestampArgumentResolver());
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.enums;
import com.nebula.web.boot.api.IResultCode;
@ -13,7 +30,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ResultCode implements IResultCode {
/**
* 操作成功
*/
@ -34,8 +51,7 @@ public enum ResultCode implements IResultCode {
PARAM_BIND_ERROR(HttpServletResponse.SC_BAD_REQUEST, "请求参数绑定错误"),
BIZ_EXCEPTION(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "业务异常");
/**
* code编码
*/
@ -44,11 +60,5 @@ public enum ResultCode implements IResultCode {
* 中文信息描述
*/
final String message;
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.error;
import com.nebula.web.boot.api.NebulaResponse;
@ -38,94 +55,94 @@ import org.springframework.web.servlet.NoHandlerFoundException;
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@RestControllerAdvice
public class NebulaRestExceptionHandler {
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public NebulaResponse<String> handleError(HttpServletRequest request, MissingServletRequestParameterException e) {
String message = String.format("Missing required request parameters: %s", e.getParameterName());
return NebulaResponse.fail(ResultCode.PARAM_MISS, message);
}
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public NebulaResponse<?> handleError(HttpServletRequest request, BindException e) {
log.warn("Parameter binding failure: {}", e.getMessage());
return handleError(request, e.getBindingResult());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public NebulaResponse<?> handleError(HttpServletRequest request, MethodArgumentNotValidException e) {
log.warn("参数验证失败: {}", e.getMessage());
return handleError(request, e.getBindingResult());
}
@ExceptionHandler(UnauthorizedException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public NebulaResponse<?> handleError(HttpServletRequest request, UnauthorizedException e) {
log.warn("Unauthorised requests: {}", e.getMessage());
return NebulaResponse.fail(e.getCode(), e.getMessage());
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public NebulaResponse<?> handleError(HttpServletRequest request, HttpRequestMethodNotSupportedException e) {
log.error("Current request method not supported: {}", e.getMessage());
return NebulaResponse.fail(ResultCode.METHOD_NOT_SUPPORTED, e.getMessage());
}
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public NebulaResponse<?> handleError(HttpServletRequest request, NoHandlerFoundException e) {
log.error("404没找到请求:{}", e.getMessage());
return NebulaResponse.fail(ResultCode.NOT_FOUND, e.getMessage());
}
@ExceptionHandler(BizException.class)
@ResponseStatus(HttpStatus.OK)
public NebulaResponse<?> handleError(HttpServletRequest request, BizException e) {
log.error("业务异常", e);
return NebulaResponse.fail(e.getCode(), e.getMessage());
}
@ExceptionHandler(RpcException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public NebulaResponse<?> handleError(HttpServletRequest request, RpcException e) {
log.error("RPC Exception", e);
return NebulaResponse.fail(e.getCode(), e.getMessage());
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public NebulaResponse<?> methodArgumentTypeMismatchException(HttpServletRequest request,
MethodArgumentTypeMismatchException e) {
MethodArgumentTypeMismatchException e) {
log.error("参数类型异常 ", e);
return NebulaResponse.fail(ResultCode.PARAM_BIND_ERROR);
}
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public NebulaResponse<?> httpMessageNotReadableExceptionHandle(HttpServletRequest request,
HttpMessageNotReadableException e) {
HttpMessageNotReadableException e) {
log.error("数据格式错误 ", e);
return NebulaResponse.fail(ResultCode.PARAM_BIND_ERROR, "数据格式错误");
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public NebulaResponse<?> defaultErrorHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
Object handler, Exception ex) {
NebulaResponse<?> baseResponse = new NebulaResponse<>();
baseResponse.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode());
baseResponse.setMsg("Server busy");
return baseResponse;
}
private NebulaResponse<?> handleError(HttpServletRequest request, BindingResult result) {
FieldError error = result.getFieldError();
assert error != null;
String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
return NebulaResponse.fail(ResultCode.PARAM_BIND_ERROR, message);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.exception;
import com.nebula.web.boot.api.IResultCode;
@ -9,30 +26,31 @@ import lombok.Getter;
* @date : 2023/4/13 10:11
* @description:
*/
@Getter public abstract class BaseException extends RuntimeException {
@Getter
public abstract class BaseException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final IResultCode code;
public BaseException(String errMessage) {
super(errMessage);
this.code = ResultCode.INTERNAL_SERVER_ERROR;
}
public BaseException(IResultCode code, String errMessage) {
super(errMessage);
this.code = code;
}
public BaseException(String errMessage, Throwable e) {
super(errMessage, e);
this.code = ResultCode.FAILURE;
}
public BaseException(IResultCode code, String errMessage, Throwable e) {
super(errMessage, e);
this.code = code;
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.exception;
import com.nebula.web.boot.api.IResultCode;
@ -9,24 +26,23 @@ import com.nebula.web.boot.enums.ResultCode;
* @description:
*/
public class BizException extends BaseException {
private static final long serialVersionUID = 1L;
public BizException(String errMessage) {
super(ResultCode.FAILURE, errMessage);
}
public BizException(ResultCode errCode, String errMessage) {
super(errCode, errMessage);
}
public BizException(String errMessage, Throwable e) {
super(errMessage, e);
}
public BizException(IResultCode errorCode, String errMessage, Throwable e) {
super(errorCode, errMessage, e);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.exception;
/**
@ -6,7 +23,7 @@ package com.nebula.web.boot.exception;
* @description:
*/
public class RpcException extends BaseException {
public RpcException(String errMessage) {
super(errMessage);
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.exception;
import com.nebula.web.boot.enums.ResultCode;
@ -8,6 +25,7 @@ import com.nebula.web.boot.enums.ResultCode;
* @description:
*/
public class UnauthorizedException extends BaseException {
public UnauthorizedException(String errMessage) {
super(ResultCode.UNAUTHORIZED, errMessage);
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -18,7 +35,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
* handler response value of all http api
*/
public class NebulaResponseBodyHandleReturnValue implements HandlerMethodReturnValueHandler, AsyncHandlerMethodReturnValueHandler {
private static final String ContentType = "application/json;charset=utf-8";
/**
* 处理所有非异常的错误
@ -28,11 +45,11 @@ public class NebulaResponseBodyHandleReturnValue implements HandlerMethodReturnV
*/
@Override
public boolean supportsReturnType(MethodParameter returnType) {
//如果已经是基础的返回值
// 如果已经是基础的返回值
return returnType.getParameterType() != NebulaResponseBody.class
&& DataUtils.isNotEmpty(returnType.getAnnotatedElement().getAnnotation(NebulaResponseBody.class));
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
mavContainer.setRequestHandled(true);
@ -43,7 +60,7 @@ public class NebulaResponseBodyHandleReturnValue implements HandlerMethodReturnV
baseResponse.setCode(ResultCode.SUCCESS.getCode());
baseResponse.setMsg(ResultCode.SUCCESS.getMessage());
baseResponse.setData(returnValue);
NebulaResponseBody responseBody = returnType.getAnnotatedElement().getAnnotation(NebulaResponseBody.class);
Class<? extends ObjectMapper> objectMapperClass = responseBody.objectMapper();
if (Objects.equals(objectMapperClass, JsonUtil.JacksonObjectMapper.class)) {
@ -52,9 +69,9 @@ public class NebulaResponseBodyHandleReturnValue implements HandlerMethodReturnV
ObjectMapper objectMapper = objectMapperClass.getDeclaredConstructor().newInstance();
response.getWriter().write(Objects.requireNonNull(JsonUtil.toJSONString(objectMapper, baseResponse)));
}
}
@Override
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
return supportsReturnType(returnType);

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.jackson;
import com.fasterxml.jackson.core.JsonEncoding;
@ -32,36 +49,37 @@ import org.springframework.util.TypeUtils;
* AbstractReadWriteJackson2HttpMessageConverter
*/
public abstract class AbstractReadWriteJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
private static final java.nio.charset.Charset DEFAULT_CHARSET = Charsets.UTF_8;
private final ObjectMapper writeObjectMapper;
@Nullable
private PrettyPrinter ssePrettyPrinter;
public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper) {
super(readObjectMapper);
this.writeObjectMapper = writeObjectMapper;
initSsePrettyPrinter();
}
public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, MediaType supportedMediaType) {
this(readObjectMapper, writeObjectMapper);
setSupportedMediaTypes(Collections.singletonList(supportedMediaType));
initSsePrettyPrinter();
}
public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, MediaType... supportedMediaTypes) {
this(readObjectMapper, writeObjectMapper);
setSupportedMediaTypes(Arrays.asList(supportedMediaTypes));
}
private void initSsePrettyPrinter() {
setDefaultCharset(DEFAULT_CHARSET);
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:"));
this.ssePrettyPrinter = prettyPrinter;
}
@Override
public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) {
if (!canWrite(mediaType)) {
@ -74,22 +92,21 @@ public abstract class AbstractReadWriteJackson2HttpMessageConverter extends Abst
logWarningIfNecessary(clazz, causeRef.get());
return false;
}
@Override
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
MediaType contentType = outputMessage.getHeaders().getContentType();
JsonEncoding encoding = getJsonEncoding(contentType);
JsonGenerator generator = this.writeObjectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
try {
writePrefix(generator, object);
Object value = object;
Class<?> serializationView = null;
FilterProvider filters = null;
JavaType javaType = null;
if (object instanceof MappingJacksonValue) {
MappingJacksonValue container = (MappingJacksonValue) object;
value = container.getValue();
@ -99,9 +116,8 @@ public abstract class AbstractReadWriteJackson2HttpMessageConverter extends Abst
if (type != null && TypeUtils.isAssignable(type, value.getClass())) {
javaType = getJavaType(type, null);
}
ObjectWriter objectWriter = (serializationView != null ?
this.writeObjectMapper.writerWithView(serializationView) : this.writeObjectMapper.writer());
ObjectWriter objectWriter = (serializationView != null ? this.writeObjectMapper.writerWithView(serializationView) : this.writeObjectMapper.writer());
if (filters != null) {
objectWriter = objectWriter.with(filters);
}
@ -114,7 +130,7 @@ public abstract class AbstractReadWriteJackson2HttpMessageConverter extends Abst
objectWriter = objectWriter.with(this.ssePrettyPrinter);
}
objectWriter.writeValue(generator, value);
writeSuffix(generator, object);
generator.flush();
} catch (InvalidDefinitionException ex) {
@ -123,5 +139,5 @@ public abstract class AbstractReadWriteJackson2HttpMessageConverter extends Abst
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getOriginalMessage(), ex);
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.jackson;
import com.fasterxml.jackson.core.JsonParser;
@ -18,9 +35,10 @@ import java.time.LocalDateTime;
* </>
*/
public class LocalDateTimeJacksonDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(
JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
long longValue = jsonParser.getLongValue();
return TimeUtil.toLocalDateTime(longValue);
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.jackson;
import com.fasterxml.jackson.core.JsonGenerator;
@ -13,10 +30,10 @@ import java.time.ZoneOffset;
* @description:
*/
public class LocalDateTimeJacksonSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.jackson;
import com.fasterxml.jackson.core.JsonGenerator;
@ -11,10 +28,10 @@ import org.springframework.lang.Nullable;
* MappingApiJackson2HttpMessageConverter
*/
public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJackson2HttpMessageConverter {
@Nullable
private String jsonPrefix;
/**
* Construct a new {@link MappingApiJackson2HttpMessageConverter} using default configuration
* provided by {@link Jackson2ObjectMapperBuilder}.
@ -22,7 +39,7 @@ public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJac
public MappingApiJackson2HttpMessageConverter() {
this(Jackson2ObjectMapperBuilder.json().build());
}
/**
* Construct a new {@link MappingApiJackson2HttpMessageConverter} with a custom {@link ObjectMapper}.
* You can use {@link Jackson2ObjectMapperBuilder} to build it easily.
@ -33,12 +50,12 @@ public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJac
public MappingApiJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, initWriteObjectMapper(objectMapper), MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
}
private static ObjectMapper initWriteObjectMapper(ObjectMapper readObjectMapper) {
// 拷贝 readObjectMapper
return readObjectMapper.copy();
}
/**
* Specify a custom prefix to use for this view's JSON output.
* Default is none.
@ -49,7 +66,7 @@ public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJac
public void setJsonPrefix(String jsonPrefix) {
this.jsonPrefix = jsonPrefix;
}
/**
* Indicate whether the JSON output by this view should be prefixed with ")]}', ". Default is false.
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
@ -62,12 +79,12 @@ public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJac
public void setPrefixJson(boolean prefixJson) {
this.jsonPrefix = (prefixJson ? ")]}', " : null);
}
@Override
protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
if (this.jsonPrefix != null) {
generator.writeRaw(this.jsonPrefix);
}
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.resolver;
import com.nebula.base.utils.DataUtils;
@ -21,63 +38,63 @@ import org.springframework.web.method.support.ModelAndViewContainer;
*@description:
*/
public class TimestampArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(GetTimestamp.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
GetTimestamp getTimestamp = methodParameter.getParameterAnnotation(GetTimestamp.class);
Object instance = methodParameter.getParameterType().getDeclaredConstructor().newInstance();
String name = getTimestamp.name();
if (DataUtils.isEmpty(name)) {
name = methodParameter.getParameterName();
}
if (instance instanceof LocalDateTime) {
assert name != null;
String parameter = nativeWebRequest.getParameter(name);
return parse(parameter);
}
WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest, instance, name);
binder.registerCustomEditor(LocalDateTime.class, new LocalDateTimeEditor());
ServletRequestParameterPropertyValues propertyValues = new ServletRequestParameterPropertyValues(Objects.requireNonNull(nativeWebRequest.getNativeRequest(ServletRequest.class)));
binder.bind(propertyValues);
return instance;
}
class LocalDateTimeEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
final LocalDateTime localDateTime = (LocalDateTime) getValue();
if (localDateTime == null) {
return "";
}
return localDateTime.toString();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(parse(text));
}
}
private LocalDateTime parse(String timestampStr) {
if (DataUtils.isEmpty(timestampStr)) {
return null;
}
timestampStr = timestampStr.replaceAll("\"", "");
long timestamp = Long.parseLong(timestampStr);
if (timestamp == 0) {
return null;
}
return TimeUtil.toLocalDateTime(timestamp);
}
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(GetTimestamp.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
GetTimestamp getTimestamp = methodParameter.getParameterAnnotation(GetTimestamp.class);
Object instance = methodParameter.getParameterType().getDeclaredConstructor().newInstance();
String name = getTimestamp.name();
if (DataUtils.isEmpty(name)) {
name = methodParameter.getParameterName();
}
if (instance instanceof LocalDateTime) {
assert name != null;
String parameter = nativeWebRequest.getParameter(name);
return parse(parameter);
}
WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest, instance, name);
binder.registerCustomEditor(LocalDateTime.class, new LocalDateTimeEditor());
ServletRequestParameterPropertyValues propertyValues = new ServletRequestParameterPropertyValues(Objects.requireNonNull(nativeWebRequest.getNativeRequest(ServletRequest.class)));
binder.bind(propertyValues);
return instance;
}
class LocalDateTimeEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
final LocalDateTime localDateTime = (LocalDateTime) getValue();
if (localDateTime == null) {
return "";
}
return localDateTime.toString();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(parse(text));
}
}
private LocalDateTime parse(String timestampStr) {
if (DataUtils.isEmpty(timestampStr)) {
return null;
}
timestampStr = timestampStr.replaceAll("\"", "");
long timestamp = Long.parseLong(timestampStr);
if (timestamp == 0) {
return null;
}
return TimeUtil.toLocalDateTime(timestamp);
}
}

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ -9,7 +26,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
*/
@ExtendWith(MockitoExtension.class)
public class ActionTest {
@Test
public void test() {
System.out.println("hahah");

View File

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.boot.api;
import org.junit.jupiter.api.Test;
@ -8,10 +25,10 @@ import org.junit.jupiter.api.Test;
* @description:
*/
public class NebulaPageTest {
@Test
public void testGetTotalCount() {
System.out.println("hahah");
}
}