├── src ├── test │ ├── resources │ │ ├── conf1.json │ │ ├── conf │ │ │ └── conf2.json │ │ └── shell-test.sh │ └── java │ │ └── com │ │ └── ecfront │ │ └── dew │ │ └── common │ │ └── test │ │ ├── A.java │ │ ├── ABC.java │ │ ├── sub │ │ ├── BB.java │ │ └── ABCD.java │ │ ├── Id.java │ │ ├── Ext.java │ │ ├── TimerHelperTest.java │ │ ├── bean │ │ ├── IdxController.java │ │ ├── TestAnnotation.java │ │ ├── BaseController.java │ │ └── User.java │ │ ├── ClassScanHelperTest.java │ │ ├── AvgTest.java │ │ ├── GenericModel.java │ │ ├── AmountHelperTest.java │ │ ├── ScriptHelperTest.java │ │ ├── graalvm │ │ └── NativeImageMain.java │ │ ├── FieldHelperTest.java │ │ ├── TestIdModel.java │ │ ├── ReturnPerfTest.java │ │ ├── FallbackHelperTest.java │ │ ├── FileHelperTest.java │ │ ├── InterceptorTest.java │ │ ├── ShellHelperTest.java │ │ ├── HttpHelperTest.java │ │ ├── BeanHelperTest.java │ │ ├── JsonHelperTest.java │ │ └── SecurityHelperTest.java └── main │ ├── resources │ └── META-INF │ │ └── native-image │ │ └── com.ecfront.dew │ │ └── common │ │ ├── proxy-config.json │ │ ├── predefined-classes-config.json │ │ ├── serialization-config.json │ │ ├── jni-config.json │ │ ├── agent-access-filter.json │ │ ├── native-image.properties │ │ ├── resource-config.json │ │ └── reflect-config.json │ └── java │ └── com │ └── ecfront │ └── dew │ └── common │ ├── tuple │ ├── Tuple.java │ ├── Tuple2.java │ ├── Tuple3.java │ ├── Tuple4.java │ ├── Tuple5.java │ ├── Tuple6.java │ ├── Tuple7.java │ ├── Tuple8.java │ ├── Tuple9.java │ └── Tuple10.java │ ├── fun │ ├── VoidExecutor.java │ └── VoidPredicate.java │ ├── interceptor │ ├── DewInterceptExec.java │ ├── DewInterceptor.java │ └── DewInterceptContext.java │ ├── DependencyHelper.java │ ├── FunctionHelper.java │ ├── exception │ ├── RTException.java │ ├── RTIOException.java │ ├── RTScriptException.java │ ├── RTGeneralSecurityException.java │ ├── RTUnsupportedEncodingException.java │ └── RTReflectiveOperationException.java │ ├── StandardCode.java │ ├── TimeHelper.java │ ├── TimerHelper.java │ ├── ReportHandler.java │ ├── AmountHelper.java │ ├── $.java │ ├── Page.java │ ├── ScriptHelper.java │ ├── InterceptorHelper.java │ ├── FieldHelper.java │ ├── ClassScanHelper.java │ ├── JsonHelper.java │ ├── FileHelper.java │ └── ShellHelper.java ├── .gitattributes ├── .gitignore ├── it ├── src │ ├── main │ │ └── resources │ │ │ └── META-INF │ │ │ └── native-image │ │ │ └── com.ecfront.dew │ │ │ └── common-it │ │ │ ├── proxy-config.json │ │ │ ├── jni-config.json │ │ │ ├── agent-access-filter.json │ │ │ ├── resource-config.json │ │ │ ├── native-image.properties │ │ │ └── reflect-config.json │ └── test │ │ └── java │ │ └── com │ │ └── ecfront │ │ └── dew │ │ └── commonit │ │ └── test │ │ └── NativeImageTest.java └── pom.xml ├── .vscode └── settings.json ├── .travis.yml ├── docs └── index.adoc ├── .github └── workflows │ ├── semgrep.yml │ └── codeql-analysis.yml └── checkstyle.xml /src/test/resources/conf1.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 1 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/conf/conf2.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 2 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf 2 | Dockerfile eol=lf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | .idea 5 | *.iml 6 | .settings 7 | target 8 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.debug.settings.onBuildFailureProceed": true, 3 | "java.configuration.updateBuildConfiguration": "interactive" 4 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | script: mvn clean test -B -V 4 | 5 | jdk: 6 | - openjdk11 7 | 8 | notifications: 9 | email: 10 | - i@sunisle.org 11 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/predefined-classes-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"agent-extracted", 4 | "classes":[ 5 | ] 6 | } 7 | ] 8 | 9 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/serialization-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "types":[ 3 | ], 4 | "lambdaCapturingTypes":[ 5 | ], 6 | "proxies":[ 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/shell-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sleep 1 4 | echo 'step 10' 5 | echo 'Hello' 6 | sleep 5 7 | echo 'step 70' 8 | echo 'World' 9 | (>&2 echo "some error") 10 | echo 'done!' -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/A.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | /** 4 | * The type A. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class A { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/ABC.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | /** 4 | * The type Abc. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class ABC { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"java.lang.Boolean", 4 | "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/sub/BB.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.sub; 2 | 3 | /** 4 | * The type Bb. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | @Deprecated 9 | public class BB { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/sub/ABCD.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.sub; 2 | 3 | /** 4 | * The type Abcd. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | @Deprecated 9 | public class ABCD { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Tuple. 7 | * 8 | * @author gudaoxuri 9 | */ 10 | public interface Tuple extends Serializable { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/fun/VoidExecutor.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.fun; 2 | 3 | /** 4 | * The interface Void executor. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | @FunctionalInterface 9 | public interface VoidExecutor { 10 | 11 | /** 12 | * Exec. 13 | */ 14 | void exec(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/fun/VoidPredicate.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.fun; 2 | 3 | /** 4 | * The interface Void predicate. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | @FunctionalInterface 9 | public interface VoidPredicate { 10 | 11 | /** 12 | * Test boolean. 13 | * 14 | * @return the boolean 15 | */ 16 | boolean test(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"java.lang.ClassLoader", 4 | "methods":[ 5 | {"name":"getPlatformClassLoader","parameterTypes":[] }, 6 | {"name":"loadClass","parameterTypes":["java.lang.String"] } 7 | ] 8 | }, 9 | { 10 | "name":"java.lang.ClassNotFoundException" 11 | }, 12 | { 13 | "name":"java.lang.NoSuchMethodError" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/Id.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | /** 4 | * The type Id. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class Id { 9 | private String cid; 10 | 11 | /** 12 | * Gets cid. 13 | * 14 | * @return the cid 15 | */ 16 | public String getCid() { 17 | return cid; 18 | } 19 | 20 | /** 21 | * Sets cid. 22 | * 23 | * @param cid the cid 24 | */ 25 | public void setCid(String cid) { 26 | this.cid = cid; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/agent-access-filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "excludeClasses": "com.ecfront.dew.commonit.test.**" 5 | }, 6 | { 7 | "excludeClasses": "org.apache.maven.surefire.**" 8 | }, 9 | { 10 | "excludeClasses": "com.oracle.truffle.**" 11 | }, 12 | { 13 | "excludeClasses": "org.graalvm.**" 14 | }, 15 | { 16 | "excludeClasses": "junit.framework.**" 17 | }, 18 | { 19 | "excludeClasses": "sun.**" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/agent-access-filter.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "excludeClasses": "com.ecfront.dew.common.test.**" 5 | }, 6 | { 7 | "excludeClasses": "org.apache.maven.surefire.**" 8 | }, 9 | { 10 | "excludeClasses": "org.junit.**" 11 | }, 12 | { 13 | "excludeClasses": "com.oracle.truffle.**" 14 | }, 15 | { 16 | "excludeClasses": "org.graalvm.**" 17 | }, 18 | { 19 | "excludeClasses": "junit.framework.**" 20 | }, 21 | { 22 | "excludeClasses": "sun.**" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/interceptor/DewInterceptExec.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.interceptor; 2 | 3 | import com.ecfront.dew.common.Resp; 4 | 5 | /** 6 | * The interface Dew intercept exec. 7 | * 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @author gudaoxuri 11 | */ 12 | @FunctionalInterface 13 | public interface DewInterceptExec { 14 | 15 | /** 16 | * Exec resp. 17 | * 18 | * @param context the context 19 | * @return the resp 20 | */ 21 | Resp> exec(DewInterceptContext context); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /docs/index.adoc: -------------------------------------------------------------------------------- 1 | = Dew Common — Java常用操作工具集 2 | 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: zh-CN 6 | :toc: left 7 | :toclevels: 2 8 | 9 | ++++ 10 | Fork me on GitHub 11 | ++++ 12 | 13 | include::../README.adoc[] 14 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/Ext.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | /** 4 | * The type Ext. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class Ext extends Id { 9 | private String createTime; 10 | 11 | /** 12 | * Gets create time. 13 | * 14 | * @return the create time 15 | */ 16 | public String getCreateTime() { 17 | return createTime; 18 | } 19 | 20 | /** 21 | * Sets create time. 22 | * 23 | * @param createTime the create time 24 | */ 25 | public void setCreateTime(String createTime) { 26 | this.createTime = createTime; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: {} 3 | pull_request: {} 4 | push: 5 | branches: 6 | - main 7 | - master 8 | paths: 9 | - .github/workflows/semgrep.yml 10 | schedule: 11 | # random HH:MM to avoid a load spike on GitHub Actions at 00:00 12 | - cron: 52 1 * * * 13 | name: Semgrep 14 | jobs: 15 | semgrep: 16 | name: semgrep/ci 17 | runs-on: ubuntu-latest 18 | permissions: 19 | contents: read 20 | env: 21 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 22 | container: 23 | image: semgrep/semgrep 24 | steps: 25 | - uses: actions/checkout@v4 26 | - run: semgrep ci 27 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/DependencyHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | /** 4 | * The type Dependency helper. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public final class DependencyHelper { 9 | 10 | private DependencyHelper() { 11 | } 12 | 13 | /** 14 | * Has dependency boolean. 15 | * 16 | * @param clazz the clazz 17 | * @return the boolean 18 | */ 19 | public static boolean hasDependency(String clazz) { 20 | try { 21 | Class.forName(clazz); 22 | return true; 23 | } catch (ClassNotFoundException e) { 24 | return false; 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /it/src/test/java/com/ecfront/dew/commonit/test/NativeImageTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.commonit.test; 2 | 3 | import com.ecfront.dew.common.test.graalvm.NativeImageMain; 4 | import org.junit.jupiter.api.Test; 5 | 6 | /** 7 | * The type Native image test. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | public class NativeImageTest { 12 | 13 | /** 14 | * Test native image. 15 | * 16 | * @throws Exception the exception 17 | */ 18 | @Test 19 | public void testNativeImage() throws Exception { 20 | if (System.getProperty("java.vm.vendor").contains("GraalVM")) { 21 | NativeImageMain.main(new String[]{}); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":[ 3 | {"pattern":"\\QLICENSE-junit.txt\\E"}, 4 | {"pattern":"\\QMETA-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider\\E"}, 5 | {"pattern":"\\QMETA-INF/services/com.oracle.truffle.api.instrumentation.TruffleInstrument$Provider\\E"}, 6 | {"pattern":"\\QMETA-INF/services/com.oracle.truffle.js.runtime.Evaluator\\E"}, 7 | {"pattern":"\\QMETA-INF/services/java.nio.file.spi.FileSystemProvider\\E"}, 8 | {"pattern":"\\Q\\E"}, 9 | {"pattern":"\\Qcom/oracle/truffle/nfi/impl/NFILanguageImpl.class\\E"}, 10 | {"pattern":"\\Qconf/conf2.json\\E"}, 11 | {"pattern":"\\Qconf1.json\\E"} 12 | ], 13 | "bundles":[] 14 | } 15 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/native-image.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020. the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | Args = --language:js 18 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple2.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 2. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @author gudaoxuri 9 | */ 10 | public class Tuple2 implements Tuple { 11 | 12 | /** 13 | * The 0. 14 | */ 15 | public T0 _0; 16 | /** 17 | * The 1. 18 | */ 19 | public T1 _1; 20 | 21 | /** 22 | * Instantiates a new Tuple 2. 23 | */ 24 | public Tuple2() { 25 | } 26 | 27 | /** 28 | * Instantiates a new Tuple 2. 29 | * 30 | * @param _0 the 0 31 | * @param _1 the 1 32 | */ 33 | public Tuple2(T0 _0, T1 _1) { 34 | this._0 = _0; 35 | this._1 = _1; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/FunctionHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.util.Iterator; 4 | import java.util.Spliterator; 5 | import java.util.Spliterators; 6 | import java.util.stream.Stream; 7 | import java.util.stream.StreamSupport; 8 | 9 | /** 10 | * 函数操作. 11 | * 12 | * @author gudaoxuri 13 | */ 14 | public class FunctionHelper { 15 | 16 | /** 17 | * Instantiates a new Function helper. 18 | */ 19 | FunctionHelper() { 20 | } 21 | 22 | /** 23 | * Iterator 转 Stream. 24 | * 25 | * @param the type parameter 26 | * @param it the iterator 27 | * @return the stream 28 | */ 29 | public Stream stream(Iterator it) { 30 | return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/TimerHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | /** 8 | * The type Timer helper test. 9 | * 10 | * @author gudaoxuri 11 | */ 12 | public class TimerHelperTest { 13 | 14 | /** 15 | * Test timer. 16 | * 17 | * @throws Exception the exception 18 | */ 19 | @Test 20 | public void testTimer() throws Exception { 21 | int[] i = {0}; 22 | $.timer.timer(1, () -> Assertions.assertEquals(1, i[0])); 23 | i[0] = 1; 24 | 25 | String taskId = $.timer.periodic(1, true, () -> i[0]++); 26 | Thread.sleep(1500); 27 | $.timer.cancel(taskId); 28 | Thread.sleep(2000); 29 | Assertions.assertEquals(3, i[0]); 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/native-image.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020. the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | Args=--no-fallback \ 17 | --enable-all-security-services \ 18 | --allow-incomplete-classpath \ 19 | --report-unsupported-elements-at-runtime 20 | # --language:js 21 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/bean/IdxController.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.bean; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * The type Idx controller. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | @TestAnnotation.RPC(path = "/idx/") 12 | public class IdxController extends BaseController { 13 | 14 | @Deprecated 15 | private String childField; 16 | 17 | /** 18 | * Child find list. 19 | * 20 | * @param args the args 21 | * @param body the body 22 | * @return the list 23 | */ 24 | @TestAnnotation.POST(path = "") 25 | public List childFind(Map args, List body) { 26 | body.add("new"); 27 | return body; 28 | } 29 | 30 | @Override 31 | public User find(Map args, User body) { 32 | return super.find(args, body); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple3.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 3. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @author gudaoxuri 10 | */ 11 | public class Tuple3 implements Tuple { 12 | 13 | /** 14 | * The 0. 15 | */ 16 | public T0 _0; 17 | /** 18 | * The 1. 19 | */ 20 | public T1 _1; 21 | /** 22 | * The 2. 23 | */ 24 | public T2 _2; 25 | 26 | /** 27 | * Instantiates a new Tuple 3. 28 | */ 29 | public Tuple3() { 30 | } 31 | 32 | /** 33 | * Instantiates a new Tuple 3. 34 | * 35 | * @param _0 the 0 36 | * @param _1 the 1 37 | * @param _2 the 2 38 | */ 39 | public Tuple3(T0 _0, T1 _1, T2 _2) { 40 | this._0 = _0; 41 | this._1 = _1; 42 | this._2 = _2; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/ClassScanHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | /** 11 | * The type Class scan helper test. 12 | * 13 | * @author gudaoxuri 14 | */ 15 | public class ClassScanHelperTest { 16 | 17 | /** 18 | * Scan. 19 | */ 20 | @Test 21 | public void scan() { 22 | Set> resultInFile = $.clazz.scan("com.ecfront.dew.common.test", new HashSet<>() { 23 | { 24 | add(Deprecated.class); 25 | } 26 | }, null); 27 | Assertions.assertEquals(2, resultInFile.size()); 28 | Set> resultInJar = $.clazz.scan("org.junit", null, new HashSet<>() { 29 | { 30 | add("Before\\w*"); 31 | } 32 | }); 33 | Assertions.assertTrue(resultInJar.size() > 0); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple4.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 4. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @author gudaoxuri 11 | */ 12 | public class Tuple4 implements Tuple { 13 | 14 | 15 | /** 16 | * The 0. 17 | */ 18 | public T0 _0; 19 | /** 20 | * The 1. 21 | */ 22 | public T1 _1; 23 | /** 24 | * The 2. 25 | */ 26 | public T2 _2; 27 | /** 28 | * The 3. 29 | */ 30 | public T3 _3; 31 | 32 | 33 | /** 34 | * Instantiates a new Tuple 4. 35 | */ 36 | public Tuple4() { 37 | } 38 | 39 | /** 40 | * Instantiates a new Tuple 4. 41 | * 42 | * @param _0 the 0 43 | * @param _1 the 1 44 | * @param _2 the 2 45 | * @param _3 the 3 46 | */ 47 | public Tuple4(T0 _0, T1 _1, T2 _2, T3 _3) { 48 | this._0 = _0; 49 | this._1 = _1; 50 | this._2 = _2; 51 | this._3 = _3; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/interceptor/DewInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.interceptor; 2 | 3 | import com.ecfront.dew.common.Resp; 4 | 5 | /** 6 | * 拦截器栈定义. 7 | * 8 | * @param 输入对象的类型 9 | * @param 输出对象的类型 10 | * @author gudaoxuri 11 | */ 12 | public interface DewInterceptor { 13 | 14 | /** 15 | * 获取拦截器所属类型,用于区别不同的栈. 16 | * 17 | * @return the category 18 | */ 19 | String getCategory(); 20 | 21 | /** 22 | * 获取拦截器名称. 23 | * 24 | * @return the name 25 | */ 26 | String getName(); 27 | 28 | /** 29 | * 前置执行. 30 | * 31 | * @param context 操作上下文 32 | * @return 执行后结果 resp 33 | */ 34 | Resp> before(DewInterceptContext context); 35 | 36 | /** 37 | * 后置执行. 38 | * 39 | * @param context 操作上下文 40 | * @return 执行后结果 resp 41 | */ 42 | Resp> after(DewInterceptContext context); 43 | 44 | /** 45 | * 错误处理,在前置/后置执行错误时触发,多用于资源回收. 46 | * 47 | * @param context 操作上下文 48 | */ 49 | default void error(DewInterceptContext context) { 50 | // Do Nothing. 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple5.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 5. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @author gudaoxuri 12 | */ 13 | public class Tuple5 implements Tuple { 14 | 15 | 16 | /** 17 | * The 0. 18 | */ 19 | public T0 _0; 20 | /** 21 | * The 1. 22 | */ 23 | public T1 _1; 24 | /** 25 | * The 2. 26 | */ 27 | public T2 _2; 28 | /** 29 | * The 3. 30 | */ 31 | public T3 _3; 32 | /** 33 | * The 4. 34 | */ 35 | public T4 _4; 36 | 37 | 38 | /** 39 | * Instantiates a new Tuple 5. 40 | */ 41 | public Tuple5() { 42 | } 43 | 44 | /** 45 | * Instantiates a new Tuple 5. 46 | * 47 | * @param _0 the 0 48 | * @param _1 the 1 49 | * @param _2 the 2 50 | * @param _3 the 3 51 | * @param _4 the 4 52 | */ 53 | public Tuple5(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4) { 54 | this._0 = _0; 55 | this._1 = _1; 56 | this._2 = _2; 57 | this._3 = _3; 58 | this._4 = _4; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/bean/TestAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.bean; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * The type Test annotation. 11 | * 12 | * @author gudaoxuri 13 | */ 14 | public class TestAnnotation { 15 | 16 | /** 17 | * The interface Rpc. 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target({ElementType.TYPE, ElementType.FIELD}) 21 | public @interface RPC { 22 | /** 23 | * Path string. 24 | * 25 | * @return the string 26 | */ 27 | String path(); 28 | } 29 | 30 | /** 31 | * The interface Post. 32 | */ 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target(ElementType.METHOD) 35 | public @interface POST { 36 | /** 37 | * Path string. 38 | * 39 | * @return the string 40 | */ 41 | String path(); 42 | } 43 | 44 | /** 45 | * The interface Get. 46 | */ 47 | @Retention(RetentionPolicy.RUNTIME) 48 | @Target(ElementType.METHOD) 49 | public @interface GET { 50 | /** 51 | * Path string. 52 | * 53 | * @return the string 54 | */ 55 | String path(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple6.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 6. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @param the type parameter 12 | * @author gudaoxuri 13 | */ 14 | public class Tuple6 implements Tuple { 15 | 16 | 17 | /** 18 | * The 0. 19 | */ 20 | public T0 _0; 21 | /** 22 | * The 1. 23 | */ 24 | public T1 _1; 25 | /** 26 | * The 2. 27 | */ 28 | public T2 _2; 29 | /** 30 | * The 3. 31 | */ 32 | public T3 _3; 33 | /** 34 | * The 4. 35 | */ 36 | public T4 _4; 37 | /** 38 | * The 5. 39 | */ 40 | public T5 _5; 41 | 42 | 43 | /** 44 | * Instantiates a new Tuple 6. 45 | */ 46 | public Tuple6() { 47 | } 48 | 49 | /** 50 | * Instantiates a new Tuple 6. 51 | * 52 | * @param _0 the 0 53 | * @param _1 the 1 54 | * @param _2 the 2 55 | * @param _3 the 3 56 | * @param _4 the 4 57 | * @param _5 the 5 58 | */ 59 | public Tuple6(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5) { 60 | this._0 = _0; 61 | this._1 = _1; 62 | this._2 = _2; 63 | this._3 = _3; 64 | this._4 = _4; 65 | this._5 = _5; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/AvgTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | /** 7 | * Avg Test. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | public class AvgTest { 12 | 13 | private final Accumulator accumulator = new Accumulator(); 14 | 15 | /** 16 | * Test. 17 | */ 18 | @Test 19 | public void test() { 20 | accumulator.addDateValue(1); 21 | accumulator.addDateValue(2); 22 | accumulator.addDateValue(3); 23 | Assertions.assertEquals(2, accumulator.m, 0); 24 | accumulator.addDateValue(4); 25 | accumulator.addDateValue(5); 26 | accumulator.addDateValue(6); 27 | accumulator.addDateValue(7); 28 | Assertions.assertEquals(4, accumulator.m, 0); 29 | } 30 | 31 | static class Accumulator { 32 | private double m; 33 | private double s; 34 | private int n; 35 | 36 | public void addDateValue(double x) { 37 | n++; 38 | s = s + 1.0 * (n - 1) / n * (x - m) * (x - m); 39 | m = m + (x - m) / n; 40 | } 41 | 42 | public double mean() { 43 | return m; 44 | } 45 | 46 | public double var() { 47 | return s / (n - 1); 48 | } 49 | 50 | public double stddev() { 51 | return Math.sqrt(this.var()); 52 | } 53 | } 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/GenericModel.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * The type Generic model. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | public class GenericModel { 12 | 13 | private List strs; 14 | private List Exts; 15 | private Map extMap; 16 | 17 | /** 18 | * Gets strs. 19 | * 20 | * @return the strs 21 | */ 22 | public List getStrs() { 23 | return strs; 24 | } 25 | 26 | /** 27 | * Sets strs. 28 | * 29 | * @param strs the strs 30 | */ 31 | public void setStrs(List strs) { 32 | this.strs = strs; 33 | } 34 | 35 | /** 36 | * Gets exts. 37 | * 38 | * @return the exts 39 | */ 40 | public List getExts() { 41 | return Exts; 42 | } 43 | 44 | /** 45 | * Sets exts. 46 | * 47 | * @param exts the exts 48 | */ 49 | public void setExts(List exts) { 50 | Exts = exts; 51 | } 52 | 53 | /** 54 | * Gets ext map. 55 | * 56 | * @return the ext map 57 | */ 58 | public Map getExtMap() { 59 | return extMap; 60 | } 61 | 62 | /** 63 | * Sets ext map. 64 | * 65 | * @param extMap the ext map 66 | */ 67 | public void setExtMap(Map extMap) { 68 | this.extMap = extMap; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Rt exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTException extends RuntimeException { 9 | 10 | /** 11 | * Instantiates a new Rt exception. 12 | */ 13 | public RTException() { 14 | } 15 | 16 | /** 17 | * Instantiates a new Rt exception. 18 | * 19 | * @param message the message 20 | */ 21 | public RTException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Instantiates a new Rt exception. 27 | * 28 | * @param message the message 29 | * @param cause the cause 30 | */ 31 | public RTException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | /** 36 | * Instantiates a new Rt exception. 37 | * 38 | * @param cause the cause 39 | */ 40 | public RTException(Throwable cause) { 41 | super(cause); 42 | } 43 | 44 | /** 45 | * Instantiates a new Rt exception. 46 | * 47 | * @param message the message 48 | * @param cause the cause 49 | * @param enableSuppression the enable suppression 50 | * @param writableStackTrace the writable stack trace 51 | */ 52 | public RTException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/StandardCode.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | /** 4 | * The enum Standard code. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public enum StandardCode { 9 | /** 10 | * Success standard code. 11 | */ 12 | SUCCESS("200"), 13 | /** 14 | * Bad request standard code. 15 | */ 16 | BAD_REQUEST("400"), 17 | /** 18 | * Unauthorized standard code. 19 | */ 20 | UNAUTHORIZED("401"), 21 | /** 22 | * Forbidden standard code. 23 | */ 24 | FORBIDDEN("403"), 25 | /** 26 | * Not found standard code. 27 | */ 28 | NOT_FOUND("404"), 29 | /** 30 | * Conflict standard code. 31 | */ 32 | CONFLICT("409"), 33 | /** 34 | * Locked standard code. 35 | */ 36 | LOCKED("423"), 37 | /** 38 | * Unsupported media type standard code. 39 | */ 40 | UNSUPPORTED_MEDIA_TYPE("415"), 41 | /** 42 | * Internal server error standard code. 43 | */ 44 | INTERNAL_SERVER_ERROR("500"), 45 | /** 46 | * Not implemented standard code. 47 | */ 48 | NOT_IMPLEMENTED("501"), 49 | /** 50 | * Service unavailable standard code. 51 | */ 52 | SERVICE_UNAVAILABLE("503"), 53 | /** 54 | * Unknown standard code. 55 | */ 56 | UNKNOWN("-1"); 57 | 58 | private final String code; 59 | 60 | StandardCode(String code) { 61 | this.code = code; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return code; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTIOException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Runtime IO exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTIOException extends RTException { 9 | 10 | /** 11 | * Instantiates a new Rtio exception. 12 | */ 13 | public RTIOException() { 14 | } 15 | 16 | /** 17 | * Instantiates a new Rtio exception. 18 | * 19 | * @param message the message 20 | */ 21 | public RTIOException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Instantiates a new Rtio exception. 27 | * 28 | * @param message the message 29 | * @param cause the cause 30 | */ 31 | public RTIOException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | /** 36 | * Instantiates a new Rtio exception. 37 | * 38 | * @param cause the cause 39 | */ 40 | public RTIOException(Throwable cause) { 41 | super(cause); 42 | } 43 | 44 | /** 45 | * Instantiates a new Rtio exception. 46 | * 47 | * @param message the message 48 | * @param cause the cause 49 | * @param enableSuppression the enable suppression 50 | * @param writableStackTrace the writable stack trace 51 | */ 52 | public RTIOException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTScriptException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Rt script exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTScriptException extends RTException { 9 | 10 | /** 11 | * Instantiates a new Rt script exception. 12 | */ 13 | public RTScriptException() { 14 | } 15 | 16 | /** 17 | * Instantiates a new Rt script exception. 18 | * 19 | * @param message the message 20 | */ 21 | public RTScriptException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Instantiates a new Rt script exception. 27 | * 28 | * @param message the message 29 | * @param cause the cause 30 | */ 31 | public RTScriptException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | /** 36 | * Instantiates a new Rt script exception. 37 | * 38 | * @param cause the cause 39 | */ 40 | public RTScriptException(Throwable cause) { 41 | super(cause); 42 | } 43 | 44 | /** 45 | * Instantiates a new Rt script exception. 46 | * 47 | * @param message the message 48 | * @param cause the cause 49 | * @param enableSuppression the enable suppression 50 | * @param writableStackTrace the writable stack trace 51 | */ 52 | public RTScriptException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple7.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 7. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @param the type parameter 12 | * @param the type parameter 13 | * @author gudaoxuri 14 | */ 15 | public class Tuple7 implements Tuple { 16 | 17 | 18 | /** 19 | * The 0. 20 | */ 21 | public T0 _0; 22 | /** 23 | * The 1. 24 | */ 25 | public T1 _1; 26 | /** 27 | * The 2. 28 | */ 29 | public T2 _2; 30 | /** 31 | * The 3. 32 | */ 33 | public T3 _3; 34 | /** 35 | * The 4. 36 | */ 37 | public T4 _4; 38 | /** 39 | * The 5. 40 | */ 41 | public T5 _5; 42 | /** 43 | * The 6. 44 | */ 45 | public T6 _6; 46 | 47 | /** 48 | * Instantiates a new Tuple 7. 49 | */ 50 | public Tuple7() { 51 | } 52 | 53 | /** 54 | * Instantiates a new Tuple 7. 55 | * 56 | * @param _0 the 0 57 | * @param _1 the 1 58 | * @param _2 the 2 59 | * @param _3 the 3 60 | * @param _4 the 4 61 | * @param _5 the 5 62 | * @param _6 the 6 63 | */ 64 | public Tuple7(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6) { 65 | this._0 = _0; 66 | this._1 = _1; 67 | this._2 = _2; 68 | this._3 = _3; 69 | this._4 = _4; 70 | this._5 = _5; 71 | this._6 = _6; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/bean/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.bean; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * The type Base controller. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | public class BaseController { 12 | 13 | @TestAnnotation.RPC(path = "") 14 | private String parentField; 15 | 16 | /** 17 | * Gets parent field. 18 | * 19 | * @return the parent field 20 | */ 21 | public String getParentField() { 22 | return parentField; 23 | } 24 | 25 | /** 26 | * Sets parent field. 27 | * 28 | * @param parentField the parent field 29 | */ 30 | public void setParentField(String parentField) { 31 | this.parentField = parentField; 32 | } 33 | 34 | /** 35 | * Parent find list. 36 | * 37 | * @param args the args 38 | * @param body the body 39 | * @return the list 40 | */ 41 | @TestAnnotation.POST(path = "") 42 | public List parentFind(Map args, List body) { 43 | body.add("parent"); 44 | return body; 45 | } 46 | 47 | /** 48 | * Find user. 49 | * 50 | * @param args the args 51 | * @param body the body 52 | * @return the user 53 | */ 54 | @TestAnnotation.POST(path = "user/") 55 | public User find(Map args, User body) { 56 | return body; 57 | } 58 | 59 | /** 60 | * Get user. 61 | * 62 | * @param args the args 63 | * @return the user 64 | */ 65 | @TestAnnotation.GET(path = "user/") 66 | public User get(Map args) { 67 | return null; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTGeneralSecurityException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Rt general security exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTGeneralSecurityException extends RTException { 9 | 10 | /** 11 | * Instantiates a new Rt general security exception. 12 | */ 13 | public RTGeneralSecurityException() { 14 | } 15 | 16 | /** 17 | * Instantiates a new Rt general security exception. 18 | * 19 | * @param message the message 20 | */ 21 | public RTGeneralSecurityException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Instantiates a new Rt general security exception. 27 | * 28 | * @param message the message 29 | * @param cause the cause 30 | */ 31 | public RTGeneralSecurityException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | /** 36 | * Instantiates a new Rt general security exception. 37 | * 38 | * @param cause the cause 39 | */ 40 | public RTGeneralSecurityException(Throwable cause) { 41 | super(cause); 42 | } 43 | 44 | /** 45 | * Instantiates a new Rt general security exception. 46 | * 47 | * @param message the message 48 | * @param cause the cause 49 | * @param enableSuppression the enable suppression 50 | * @param writableStackTrace the writable stack trace 51 | */ 52 | public RTGeneralSecurityException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTUnsupportedEncodingException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Rt unsupported encoding exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTUnsupportedEncodingException extends RTException { 9 | 10 | /** 11 | * Instantiates a new Rt unsupported encoding exception. 12 | */ 13 | public RTUnsupportedEncodingException() { 14 | } 15 | 16 | /** 17 | * Instantiates a new Rt unsupported encoding exception. 18 | * 19 | * @param message the message 20 | */ 21 | public RTUnsupportedEncodingException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Instantiates a new Rt unsupported encoding exception. 27 | * 28 | * @param message the message 29 | * @param cause the cause 30 | */ 31 | public RTUnsupportedEncodingException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | /** 36 | * Instantiates a new Rt unsupported encoding exception. 37 | * 38 | * @param cause the cause 39 | */ 40 | public RTUnsupportedEncodingException(Throwable cause) { 41 | super(cause); 42 | } 43 | 44 | /** 45 | * Instantiates a new Rt unsupported encoding exception. 46 | * 47 | * @param message the message 48 | * @param cause the cause 49 | * @param enableSuppression the enable suppression 50 | * @param writableStackTrace the writable stack trace 51 | */ 52 | public RTUnsupportedEncodingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/exception/RTReflectiveOperationException.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.exception; 2 | 3 | /** 4 | * The type Rt reflective operation exception. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class RTReflectiveOperationException extends RTException { 9 | 10 | 11 | /** 12 | * Instantiates a new Rt reflective operation exception. 13 | */ 14 | public RTReflectiveOperationException() { 15 | } 16 | 17 | /** 18 | * Instantiates a new Rt reflective operation exception. 19 | * 20 | * @param message the message 21 | */ 22 | public RTReflectiveOperationException(String message) { 23 | super(message); 24 | } 25 | 26 | /** 27 | * Instantiates a new Rt reflective operation exception. 28 | * 29 | * @param message the message 30 | * @param cause the cause 31 | */ 32 | public RTReflectiveOperationException(String message, Throwable cause) { 33 | super(message, cause); 34 | } 35 | 36 | /** 37 | * Instantiates a new Rt reflective operation exception. 38 | * 39 | * @param cause the cause 40 | */ 41 | public RTReflectiveOperationException(Throwable cause) { 42 | super(cause); 43 | } 44 | 45 | /** 46 | * Instantiates a new Rt reflective operation exception. 47 | * 48 | * @param message the message 49 | * @param cause the cause 50 | * @param enableSuppression the enable suppression 51 | * @param writableStackTrace the writable stack trace 52 | */ 53 | public RTReflectiveOperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 54 | super(message, cause, enableSuppression, writableStackTrace); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple8.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 8. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @param the type parameter 12 | * @param the type parameter 13 | * @param the type parameter 14 | * @author gudaoxuri 15 | */ 16 | public class Tuple8 implements Tuple { 17 | 18 | 19 | /** 20 | * The 0. 21 | */ 22 | public T0 _0; 23 | /** 24 | * The 1. 25 | */ 26 | public T1 _1; 27 | /** 28 | * The 2. 29 | */ 30 | public T2 _2; 31 | /** 32 | * The 3. 33 | */ 34 | public T3 _3; 35 | /** 36 | * The 4. 37 | */ 38 | public T4 _4; 39 | /** 40 | * The 5. 41 | */ 42 | public T5 _5; 43 | /** 44 | * The 6. 45 | */ 46 | public T6 _6; 47 | /** 48 | * The 7. 49 | */ 50 | public T7 _7; 51 | 52 | 53 | /** 54 | * Instantiates a new Tuple 8. 55 | */ 56 | public Tuple8() { 57 | } 58 | 59 | /** 60 | * Instantiates a new Tuple 8. 61 | * 62 | * @param _0 the 0 63 | * @param _1 the 1 64 | * @param _2 the 2 65 | * @param _3 the 3 66 | * @param _4 the 4 67 | * @param _5 the 5 68 | * @param _6 the 6 69 | * @param _7 the 7 70 | */ 71 | public Tuple8(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7) { 72 | this._0 = _0; 73 | this._1 = _1; 74 | this._2 = _2; 75 | this._3 = _3; 76 | this._4 = _4; 77 | this._5 = _5; 78 | this._6 = _6; 79 | this._7 = _7; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple9.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 9. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @param the type parameter 12 | * @param the type parameter 13 | * @param the type parameter 14 | * @param the type parameter 15 | * @author gudaoxuri 16 | */ 17 | public class Tuple9 implements Tuple { 18 | 19 | 20 | /** 21 | * The 0. 22 | */ 23 | public T0 _0; 24 | /** 25 | * The 1. 26 | */ 27 | public T1 _1; 28 | /** 29 | * The 2. 30 | */ 31 | public T2 _2; 32 | /** 33 | * The 3. 34 | */ 35 | public T3 _3; 36 | /** 37 | * The 4. 38 | */ 39 | public T4 _4; 40 | /** 41 | * The 5. 42 | */ 43 | public T5 _5; 44 | /** 45 | * The 6. 46 | */ 47 | public T6 _6; 48 | /** 49 | * The 7. 50 | */ 51 | public T7 _7; 52 | /** 53 | * The 8. 54 | */ 55 | public T8 _8; 56 | 57 | 58 | /** 59 | * Instantiates a new Tuple 9. 60 | */ 61 | public Tuple9() { 62 | } 63 | 64 | /** 65 | * Instantiates a new Tuple 9. 66 | * 67 | * @param _0 the 0 68 | * @param _1 the 1 69 | * @param _2 the 2 70 | * @param _3 the 3 71 | * @param _4 the 4 72 | * @param _5 the 5 73 | * @param _6 the 6 74 | * @param _7 the 7 75 | * @param _8 the 8 76 | */ 77 | public Tuple9(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8) { 78 | this._0 = _0; 79 | this._1 = _1; 80 | this._2 = _2; 81 | this._3 = _3; 82 | this._4 = _4; 83 | this._5 = _5; 84 | this._6 = _6; 85 | this._7 = _7; 86 | this._8 = _8; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/AmountHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | /** 8 | * The type Amount helper test. 9 | * 10 | * @author gudaoxuri 11 | */ 12 | public class AmountHelperTest { 13 | 14 | /** 15 | * Test convert. 16 | */ 17 | @Test 18 | public void testConvert() { 19 | Assertions.assertEquals("零元整", $.amount.convert("0.00")); 20 | Assertions.assertEquals("壹仟元整", $.amount.convert("1000")); 21 | Assertions.assertEquals("壹仟元整", $.amount.convert("1000.0")); 22 | Assertions.assertEquals("壹仟元壹角", $.amount.convert("1000.1")); 23 | Assertions.assertEquals("壹仟元整", $.amount.convert("1000.00")); 24 | 25 | Assertions.assertEquals("壹万陆仟肆佰零玖元零贰分", $.amount.convert("16,409.02")); 26 | Assertions.assertEquals("壹仟肆佰零玖元伍角", $.amount.convert("1,409.50")); 27 | Assertions.assertEquals("陆仟零柒元壹角肆分", $.amount.convert("6,007.14")); 28 | Assertions.assertEquals("壹仟陆佰捌拾元叁角贰分", $.amount.convert("1,680.32")); 29 | Assertions.assertEquals("叁佰贰拾伍元零肆分", $.amount.convert("325.04")); 30 | Assertions.assertEquals("肆仟叁佰贰拾壹元整", $.amount.convert("4,321.00")); 31 | Assertions.assertEquals("壹分", $.amount.convert("0.01")); 32 | 33 | Assertions.assertEquals("壹仟贰佰叁拾肆亿伍仟陆佰柒拾捌万玖仟零壹拾贰元叁角肆分", $.amount.convert("1234,5678,9012.34")); 34 | Assertions.assertEquals("壹仟亿零壹仟万零壹仟元壹角", $.amount.convert("1000,1000,1000.10")); 35 | Assertions.assertEquals("玖仟零玖亿玖仟零玖万玖仟零玖元玖角玖分", $.amount.convert("9009,9009,9009.99")); 36 | Assertions.assertEquals("伍仟肆佰叁拾贰亿零壹万零壹元零壹分", $.amount.convert("5432,0001,0001.01")); 37 | Assertions.assertEquals("壹仟亿零壹仟壹佰壹拾元整", $.amount.convert("1000,0000,1110.00")); 38 | Assertions.assertEquals("壹仟零壹拾亿零壹元壹角壹分", $.amount.convert("1010,0000,0001.11")); 39 | Assertions.assertEquals("壹仟亿元零壹分", $.amount.convert("1000,0000,0000.01")); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/interceptor/DewInterceptContext.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.interceptor; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 操作上下文. 7 | * 8 | * @param 输入对象类型 9 | * @param 输出对象类型 10 | * @author gudaoxuri 11 | */ 12 | public class DewInterceptContext { 13 | 14 | private I input; 15 | private O output; 16 | private Map args; 17 | 18 | /** 19 | * Build dew intercept context. 20 | * 21 | * @param the type parameter 22 | * @param the type parameter 23 | * @param input the input 24 | * @param output the output 25 | * @param args the args 26 | * @return the dew intercept context 27 | */ 28 | public static DewInterceptContext build(I input, O output, Map args) { 29 | DewInterceptContext context = new DewInterceptContext<>(); 30 | context.setInput(input); 31 | context.setOutput(output); 32 | context.setArgs(args); 33 | return context; 34 | } 35 | 36 | /** 37 | * Gets input. 38 | * 39 | * @return the input 40 | */ 41 | public I getInput() { 42 | return input; 43 | } 44 | 45 | /** 46 | * Sets input. 47 | * 48 | * @param input the input 49 | */ 50 | public void setInput(I input) { 51 | this.input = input; 52 | } 53 | 54 | /** 55 | * Gets output. 56 | * 57 | * @return the output 58 | */ 59 | public O getOutput() { 60 | return output; 61 | } 62 | 63 | /** 64 | * Sets output. 65 | * 66 | * @param output the output 67 | */ 68 | public void setOutput(O output) { 69 | this.output = output; 70 | } 71 | 72 | /** 73 | * Gets args. 74 | * 75 | * @return the args 76 | */ 77 | public Map getArgs() { 78 | return args; 79 | } 80 | 81 | /** 82 | * Sets args. 83 | * 84 | * @param args the args 85 | */ 86 | public void setArgs(Map args) { 87 | this.args = args; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/tuple/Tuple10.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.tuple; 2 | 3 | /** 4 | * Tuple 10. 5 | * 6 | * @param the type parameter 7 | * @param the type parameter 8 | * @param the type parameter 9 | * @param the type parameter 10 | * @param the type parameter 11 | * @param the type parameter 12 | * @param the type parameter 13 | * @param the type parameter 14 | * @param the type parameter 15 | * @param the type parameter 16 | * @author gudaoxuri 17 | */ 18 | public class Tuple10 implements Tuple { 19 | 20 | 21 | /** 22 | * The 0. 23 | */ 24 | public T0 _0; 25 | /** 26 | * The 1. 27 | */ 28 | public T1 _1; 29 | /** 30 | * The 2. 31 | */ 32 | public T2 _2; 33 | /** 34 | * The 3. 35 | */ 36 | public T3 _3; 37 | /** 38 | * The 4. 39 | */ 40 | public T4 _4; 41 | /** 42 | * The 5. 43 | */ 44 | public T5 _5; 45 | /** 46 | * The 6. 47 | */ 48 | public T6 _6; 49 | /** 50 | * The 7. 51 | */ 52 | public T7 _7; 53 | /** 54 | * The 8. 55 | */ 56 | public T8 _8; 57 | /** 58 | * The 9. 59 | */ 60 | public T9 _9; 61 | 62 | 63 | /** 64 | * Instantiates a new Tuple 10. 65 | */ 66 | public Tuple10() { 67 | } 68 | 69 | /** 70 | * Instantiates a new Tuple 10. 71 | * 72 | * @param _0 the 0 73 | * @param _1 the 1 74 | * @param _2 the 2 75 | * @param _3 the 3 76 | * @param _4 the 4 77 | * @param _5 the 5 78 | * @param _6 the 6 79 | * @param _7 the 7 80 | * @param _8 the 8 81 | * @param _9 the 9 82 | */ 83 | public Tuple10(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9) { 84 | this._0 = _0; 85 | this._1 = _1; 86 | this._2 = _2; 87 | this._3 = _3; 88 | this._4 = _4; 89 | this._5 = _5; 90 | this._6 = _6; 91 | this._7 = _7; 92 | this._8 = _8; 93 | this._9 = _9; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/ScriptHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.ScriptHelper; 5 | import org.graalvm.polyglot.Context; 6 | import org.graalvm.polyglot.Source; 7 | import org.junit.jupiter.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * The type Script helper test. 14 | * 15 | * @author gudaoxuri 16 | */ 17 | public class ScriptHelperTest { 18 | 19 | /** 20 | * Test script. 21 | */ 22 | @Test 23 | public void testScript() { 24 | ScriptHelper s1 = $.script(ScriptHelper.ScriptKind.JS, "function fun1(param){return param;}"); 25 | Assertions.assertEquals("hi", s1.execute("fun1", String.class, "hi")); 26 | 27 | ScriptHelper s2 = $.script(ScriptHelper.ScriptKind.JS, 28 | "function fun2(D){\r\n" + " var data = JSON.parse(D);\n" + " return $.field.getGenderByIdCard(data.idcard);\n" + "}"); 29 | Assertions.assertEquals("M", s2.execute("fun2", String.class, "{\"idcard\":\"110101201604016117\"}")); 30 | 31 | Assertions.assertEquals(10240, (long) $.eval(ScriptHelper.ScriptKind.JS, Long.class, "1024*10")); 32 | } 33 | 34 | /** 35 | * Test eval. 36 | * 37 | * @throws IOException the io exception 38 | */ 39 | @Test 40 | public void testEval() throws IOException { 41 | Context context = Context.newBuilder().allowAllAccess(true).build(); 42 | context.eval(Source.create("js", "function fun1(param){return param;}")); 43 | context.eval(Source.newBuilder("js", "function fun2(param){return param;}", "src.js").build()); 44 | context.eval(Source.create("js", "function fun3(param){return param;}")); 45 | var result = context.getBindings("js").getMember("fun1").execute("aa").as(String.class); 46 | Assertions.assertEquals("aa", result); 47 | result = context.getBindings("js").getMember("fun2").execute("aaa").as(String.class); 48 | Assertions.assertEquals("aaa", result); 49 | result = context.getBindings("js").getMember("fun3").execute("aaa").as(String.class); 50 | Assertions.assertEquals("aaa", result); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/TimeHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.time.ZonedDateTime; 5 | import java.util.Date; 6 | import java.util.TimeZone; 7 | 8 | /** 9 | * 时间操作. 10 | * 11 | * @author gudaoxuri 12 | */ 13 | public class TimeHelper { 14 | 15 | /** 16 | * The Msf. 17 | */ 18 | public final SimpleDateFormat msf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); 19 | /** 20 | * The Sf. 21 | */ 22 | public final SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); 23 | /** 24 | * The Mf. 25 | */ 26 | public final SimpleDateFormat mf = new SimpleDateFormat("yyyyMMddHHmm"); 27 | /** 28 | * The Hf. 29 | */ 30 | public final SimpleDateFormat hf = new SimpleDateFormat("yyyyMMddHH"); 31 | /** 32 | * The Df. 33 | */ 34 | public final SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); 35 | /** 36 | * The Mf. 37 | */ 38 | public final SimpleDateFormat Mf = new SimpleDateFormat("yyyyMM"); 39 | /** 40 | * The Yf. 41 | */ 42 | public final SimpleDateFormat yf = new SimpleDateFormat("yyyy"); 43 | /** 44 | * The Yyyy mm dd hh mm ss sss. 45 | */ 46 | public final SimpleDateFormat yyyy_MM_dd_HH_mm_ss_SSS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); 47 | /** 48 | * The Yyyy mm dd hh mm ss. 49 | */ 50 | public final SimpleDateFormat yyyy_MM_dd_HH_mm_ss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 51 | /** 52 | * The Yyyy mm dd. 53 | */ 54 | public final SimpleDateFormat yyyy_MM_dd = new SimpleDateFormat("yyyy-MM-dd"); 55 | /** 56 | * Instantiates a new Time helper. 57 | */ 58 | TimeHelper() { 59 | } 60 | 61 | /** 62 | * Utc 2 local. 63 | * 64 | * @param utcTime the utc time 65 | * @param localTimeFormat the local time format 66 | * @return the string 67 | */ 68 | public static String utc2Local(String utcTime, String localTimeFormat) { 69 | Date utcDate = Date.from(ZonedDateTime.parse(utcTime).toInstant()); 70 | SimpleDateFormat localF = new SimpleDateFormat(localTimeFormat); 71 | localF.setTimeZone(TimeZone.getDefault()); 72 | return localF.format(utcDate.getTime()); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[{ 4 | "pattern":"\\QMETA-INF/LICENSE.md\\E" 5 | }, { 6 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider\\E" 7 | }, { 8 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.TruffleRuntimeAccess\\E" 9 | }, { 10 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.impl.TruffleLocator\\E" 11 | }, { 12 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.instrumentation.TruffleInstrument$Provider\\E" 13 | }, { 14 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.library.DefaultExportProvider\\E" 15 | }, { 16 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.api.object.LayoutFactory\\E" 17 | }, { 18 | "pattern":"\\QMETA-INF/services/com.oracle.truffle.js.runtime.Evaluator\\E" 19 | }, { 20 | "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" 21 | }, { 22 | "pattern":"\\QMETA-INF/services/java.net.spi.InetAddressResolverProvider\\E" 23 | }, { 24 | "pattern":"\\QMETA-INF/services/java.net.spi.URLStreamHandlerProvider\\E" 25 | }, { 26 | "pattern":"\\QMETA-INF/services/java.nio.channels.spi.SelectorProvider\\E" 27 | }, { 28 | "pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E" 29 | }, { 30 | "pattern":"\\QMETA-INF/services/org.apache.commons.logging.LogFactory\\E" 31 | }, { 32 | "pattern":"\\QMETA-INF/services/org.graalvm.home.HomeFinder\\E" 33 | }, { 34 | "pattern":"\\QMETA-INF/services/org.graalvm.polyglot.impl.AbstractPolyglotImpl\\E" 35 | }, { 36 | "pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" 37 | }, { 38 | "pattern":"\\Q\\E" 39 | }, { 40 | "pattern":"\\Qcom/oracle/truffle/js/lang/JavaScriptLanguage.class\\E" 41 | }, { 42 | "pattern":"\\Qcom/oracle/truffle/regex/RegexLanguage.class\\E" 43 | }, { 44 | "pattern":"\\Qcommons-logging.properties\\E" 45 | }, { 46 | "pattern":"\\Qconf/conf2.json\\E" 47 | }, { 48 | "pattern":"\\Qconf1.json\\E" 49 | }, { 50 | "pattern":"\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E" 51 | }, { 52 | "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/uprops.icu\\E" 53 | }, { 54 | "pattern":"java.base:\\Qsun/net/idn/uidna.spp\\E" 55 | }]}, 56 | "bundles":[] 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/graalvm/NativeImageMain.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.graalvm; 2 | 3 | import com.ecfront.dew.common.test.*; 4 | 5 | /** 6 | * The type Native image main. 7 | * 8 | * @author gudaoxuri 9 | */ 10 | public class NativeImageMain { 11 | 12 | private NativeImageMain() { 13 | } 14 | 15 | /** 16 | * The entry point of application. 17 | * 18 | * @param args the input arguments 19 | * @throws Exception the exception 20 | */ 21 | public static void main(String[] args) throws Exception { 22 | System.out.println(NativeImageMain.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 23 | System.out.println("Test by Main..."); 24 | new AmountHelperTest().testConvert(); 25 | new AvgTest().test(); 26 | new BeanHelperTest().copyProperties(); 27 | new BeanHelperTest().findClassAnnotation(); 28 | new BeanHelperTest().findFieldInfo(); 29 | new BeanHelperTest().findMethodInfo(); 30 | new BeanHelperTest().findValues(); 31 | new BeanHelperTest().findValuesByRel(); 32 | new BeanHelperTest().parseRelFieldAndMethod(); 33 | new BeanHelperTest().getValue(); 34 | new BeanHelperTest().setValue(); 35 | //new ClassScanHelperTest().scan(); 36 | new FallbackHelperTest().testGetUser(); 37 | new FallbackHelperTest().testGetUserWithoutSomeException(); 38 | new FallbackHelperTest().testGetUserWithStrategy(); 39 | new FieldHelperTest().testField(); 40 | new FileHelperTest().testFile(); 41 | new HttpHelperTest().testHttp(); 42 | new InterceptorTest().testInterceptor(); 43 | new JsonHelperTest().testPath(); 44 | new JsonHelperTest().toJsonString(); 45 | new JsonHelperTest().toJson(); 46 | new JsonHelperTest().toList(); 47 | new JsonHelperTest().toSet(); 48 | new JsonHelperTest().toMap(); 49 | new JsonHelperTest().toObject(); 50 | new JsonHelperTest().toGenericObject(); 51 | new JsonHelperTest().testLocalDateTime(); 52 | new JsonHelperTest().testOptional(); 53 | new JsonHelperTest().customMapper(); 54 | new ScriptHelperTest().testScript(); 55 | new SecurityHelperTest().digest(); 56 | new SecurityHelperTest().symmetric(); 57 | new SecurityHelperTest().asymmetric(); 58 | new ShellHelperTest().test(); 59 | new TimerHelperTest().testTimer(); 60 | System.out.println("Test finished."); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/TimerHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.UUID; 6 | import java.util.concurrent.ScheduledFuture; 7 | import java.util.concurrent.ScheduledThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * 定时器操作. 12 | * 13 | * @author gudaoxuri 14 | */ 15 | public class TimerHelper { 16 | 17 | private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(1); 18 | 19 | private static final Map> CONTAINER = new HashMap<>(); 20 | 21 | /** 22 | * Instantiates a new Timer helper. 23 | */ 24 | TimerHelper() { 25 | } 26 | 27 | /** 28 | * 延迟执行的周期性任务. 29 | * 30 | * @param delaySec 延迟秒数 31 | * @param periodSec 周期秒数 32 | * @param fixedRate 是否按固定周期执行, 为true时表示每periodSec执行,为false表示fixedDelay,表示在当前任务执行完成后过periodSec再执行 33 | * @param fun 执行的方法 34 | * @return 任务id string 35 | */ 36 | public String periodic(long delaySec, long periodSec, boolean fixedRate, Runnable fun) { 37 | String id = UUID.randomUUID().toString(); 38 | ScheduledFuture future; 39 | if (fixedRate) { 40 | future = EXECUTOR.scheduleAtFixedRate(fun, delaySec, periodSec, TimeUnit.SECONDS); 41 | } else { 42 | future = EXECUTOR.scheduleWithFixedDelay(fun, delaySec, periodSec, TimeUnit.SECONDS); 43 | } 44 | CONTAINER.put(id, future); 45 | return id; 46 | } 47 | 48 | /** 49 | * 周期性任务. 50 | * 51 | * @param periodSec 周期秒数 52 | * @param fixedRate 是否按固定周期执行, 为true时表示每periodSec执行,为false表示fixedDelay,表示在当前任务执行完成后过periodSec再执行 53 | * @param fun 执行的方法 54 | * @return 任务id string 55 | */ 56 | public String periodic(long periodSec, boolean fixedRate, Runnable fun) { 57 | return periodic(0, periodSec, fixedRate, fun); 58 | } 59 | 60 | /** 61 | * 取消周期性任务. 62 | * 63 | * @param taskId 任务id 64 | */ 65 | public void cancel(String taskId) { 66 | if (CONTAINER.containsKey(taskId)) { 67 | CONTAINER.get(taskId).cancel(true); 68 | CONTAINER.remove(taskId); 69 | } 70 | } 71 | 72 | /** 73 | * 延迟任务. 74 | * 75 | * @param delaySec 延迟秒数 76 | * @param fun 执行的方法 77 | */ 78 | public void timer(long delaySec, Runnable fun) { 79 | EXECUTOR.schedule(fun, delaySec, TimeUnit.SECONDS); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/bean/User.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test.bean; 2 | 3 | /** 4 | * The type User. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public class User { 9 | 10 | private String name; 11 | private int age; 12 | private Integer workAge; 13 | private boolean enable; 14 | private Boolean status; 15 | private long others; 16 | 17 | /** 18 | * Gets name. 19 | * 20 | * @return the name 21 | */ 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | /** 27 | * Sets name. 28 | * 29 | * @param name the name 30 | */ 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | /** 36 | * Gets age. 37 | * 38 | * @return the age 39 | */ 40 | public int getAge() { 41 | return age; 42 | } 43 | 44 | /** 45 | * Sets age. 46 | * 47 | * @param age the age 48 | */ 49 | public void setAge(int age) { 50 | this.age = age; 51 | } 52 | 53 | /** 54 | * Gets work age. 55 | * 56 | * @return the work age 57 | */ 58 | public Integer getWorkAge() { 59 | return workAge; 60 | } 61 | 62 | /** 63 | * Sets work age. 64 | * 65 | * @param workAge the work age 66 | */ 67 | public void setWorkAge(Integer workAge) { 68 | this.workAge = workAge; 69 | } 70 | 71 | /** 72 | * Is enable boolean. 73 | * 74 | * @return the boolean 75 | */ 76 | public boolean isEnable() { 77 | return enable; 78 | } 79 | 80 | /** 81 | * Sets enable. 82 | * 83 | * @param enable the enable 84 | */ 85 | public void setEnable(boolean enable) { 86 | this.enable = enable; 87 | } 88 | 89 | /** 90 | * Gets status. 91 | * 92 | * @return the status 93 | */ 94 | public Boolean getStatus() { 95 | return status; 96 | } 97 | 98 | /** 99 | * Sets status. 100 | * 101 | * @param status the status 102 | */ 103 | public void setStatus(Boolean status) { 104 | this.status = status; 105 | } 106 | 107 | /** 108 | * Gets others. 109 | * 110 | * @return the others 111 | */ 112 | public long getOthers() { 113 | return others; 114 | } 115 | 116 | /** 117 | * Sets others. 118 | * 119 | * @param others the others 120 | */ 121 | public void setOthers(long others) { 122 | this.others = others; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "master" ] 20 | schedule: 21 | - cron: '31 12 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v2 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v2 73 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/FieldHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | /** 8 | * The type Field helper test. 9 | * 10 | * @author gudaoxuri 11 | */ 12 | public class FieldHelperTest { 13 | 14 | /** 15 | * Test field. 16 | */ 17 | @Test 18 | public void testField() { 19 | Assertions.assertTrue($.field.validateEmail("i@sunisle.org")); 20 | Assertions.assertTrue($.field.validateEmail("fy53.org@gmail.com")); 21 | Assertions.assertFalse($.field.validateEmail("i@sunisle")); 22 | Assertions.assertFalse($.field.validateEmail("i@sunisle..org")); 23 | Assertions.assertFalse($.field.validateEmail("@sunisle.org")); 24 | Assertions.assertFalse($.field.validateEmail("i#sunisle.org")); 25 | 26 | Assertions.assertTrue($.field.validateMobile("14726847687")); 27 | Assertions.assertTrue($.field.validateMobile("15326847687")); 28 | Assertions.assertTrue($.field.validateMobile("15526847687")); 29 | Assertions.assertTrue($.field.validateMobile("18657120000")); 30 | Assertions.assertTrue($.field.validateMobile("13765712000")); 31 | Assertions.assertTrue($.field.validateMobile("17714712000")); 32 | Assertions.assertTrue($.field.validateMobile("16614712000")); 33 | Assertions.assertTrue($.field.validateMobile("19914712000")); 34 | Assertions.assertTrue($.field.validateMobile("19814712000")); 35 | Assertions.assertFalse($.field.validateMobile("1865712000")); 36 | Assertions.assertFalse($.field.validateMobile("28657120000")); 37 | Assertions.assertFalse($.field.validateMobile("11657120000")); 38 | Assertions.assertFalse($.field.validateMobile("15426847687")); 39 | Assertions.assertFalse($.field.validateMobile("15?26847687")); 40 | 41 | Assertions.assertTrue($.field.isChinese("孤岛旭日")); 42 | Assertions.assertFalse($.field.isChinese("孤岛xuri")); 43 | Assertions.assertFalse($.field.isChinese("gudaoxuri")); 44 | 45 | Assertions.assertTrue($.field.isIPv4Address("127.0.0.1")); 46 | Assertions.assertTrue($.field.isIPv4Address("192.168.0.1")); 47 | Assertions.assertFalse($.field.isIPv4Address("300.168.0.1")); 48 | 49 | Assertions.assertTrue($.field.validateIdNumber("330102199901015759")); 50 | Assertions.assertEquals("19990101", $.field.getBirthByIdCard("330102199901015759")); 51 | Assertions.assertEquals("M", $.field.getGenderByIdCard("330102199901015759")); 52 | Assertions.assertEquals("浙江", $.field.getProvinceByIdCard("330102199901015759")); 53 | Assertions.assertEquals(1, (short) $.field.getDateByIdCard("330102199901015759")); 54 | Assertions.assertEquals(1, (short) $.field.getMonthByIdCard("330102199901015759")); 55 | Assertions.assertEquals(1999, (short) $.field.getYearByIdCard("330102199901015759")); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/TestIdModel.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | 5 | import java.time.LocalDate; 6 | import java.time.LocalDateTime; 7 | import java.time.LocalTime; 8 | import java.util.Date; 9 | import java.util.Map; 10 | import java.util.Optional; 11 | 12 | /** 13 | * The type Test id model. 14 | * 15 | * @author gudaoxuri 16 | */ 17 | public class TestIdModel extends Ext { 18 | private String name; 19 | 20 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") 21 | private Date date; 22 | 23 | private LocalDateTime localDateTime; 24 | private LocalDate localDate; 25 | private LocalTime localTime; 26 | 27 | private Optional> opt; 28 | 29 | /** 30 | * Gets name. 31 | * 32 | * @return the name 33 | */ 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | /** 39 | * Sets name. 40 | * 41 | * @param name the name 42 | */ 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | /** 48 | * Gets date. 49 | * 50 | * @return the date 51 | */ 52 | public Date getDate() { 53 | return date; 54 | } 55 | 56 | /** 57 | * Sets date. 58 | * 59 | * @param date the date 60 | */ 61 | public void setDate(Date date) { 62 | this.date = date; 63 | } 64 | 65 | /** 66 | * Gets local date time. 67 | * 68 | * @return the local date time 69 | */ 70 | public LocalDateTime getLocalDateTime() { 71 | return localDateTime; 72 | } 73 | 74 | /** 75 | * Sets local date time. 76 | * 77 | * @param localDateTime the local date time 78 | */ 79 | public void setLocalDateTime(LocalDateTime localDateTime) { 80 | this.localDateTime = localDateTime; 81 | } 82 | 83 | /** 84 | * Gets local date. 85 | * 86 | * @return the local date 87 | */ 88 | public LocalDate getLocalDate() { 89 | return localDate; 90 | } 91 | 92 | /** 93 | * Sets local date. 94 | * 95 | * @param localDate the local date 96 | */ 97 | public void setLocalDate(LocalDate localDate) { 98 | this.localDate = localDate; 99 | } 100 | 101 | /** 102 | * Gets local time. 103 | * 104 | * @return the local time 105 | */ 106 | public LocalTime getLocalTime() { 107 | return localTime; 108 | } 109 | 110 | /** 111 | * Sets local time. 112 | * 113 | * @param localTime the local time 114 | */ 115 | public void setLocalTime(LocalTime localTime) { 116 | this.localTime = localTime; 117 | } 118 | 119 | /** 120 | * Gets opt. 121 | * 122 | * @return the opt 123 | */ 124 | public Optional> getOpt() { 125 | return opt; 126 | } 127 | 128 | /** 129 | * Sets opt. 130 | * 131 | * @param opt the opt 132 | */ 133 | public void setOpt(Optional> opt) { 134 | this.opt = opt; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/ReturnPerfTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.Resp; 4 | import com.ecfront.dew.common.exception.RTException; 5 | 6 | import java.time.Instant; 7 | import java.util.concurrent.atomic.AtomicLong; 8 | 9 | /** 10 | * The type Return perf test. 11 | * 12 | * @author gudaoxuri 13 | */ 14 | public final class ReturnPerfTest { 15 | 16 | private ReturnPerfTest() { 17 | } 18 | 19 | /** 20 | * Gets user by user id limit by app id with exception. 21 | * 22 | * @param userId the user id 23 | * @param appId the app id 24 | * @return the user by user id limit by app id with exception 25 | * @throws InvokeException the invoke exception 26 | */ 27 | public static String getUserByUserIdLimitByAppIdWithException(String userId, String appId) throws InvokeException { 28 | throw new InvokeException("10001", "Some Error"); 29 | } 30 | 31 | /** 32 | * Gets user by user id limit by app id with resp. 33 | * 34 | * @param userId the user id 35 | * @param appId the app id 36 | * @return the user by user id limit by app id with resp 37 | */ 38 | public static Resp getUserByUserIdLimitByAppIdWithResp(String userId, String appId) { 39 | return Resp.customFail("10001", "Some Error"); 40 | } 41 | 42 | private static class InvokeException extends Exception { 43 | /** 44 | * Instantiates a new Invoke exception. 45 | * 46 | * @param code the code 47 | * @param message the message 48 | */ 49 | InvokeException(String code, String message) { 50 | super("{\"code\":\"" + code + "\",\"message\":\"" + message + "\"}"); 51 | } 52 | } 53 | 54 | /** 55 | * The entry point of application. 56 | * 57 | * @param args the input arguments 58 | * @throws InterruptedException the interrupted exception 59 | */ 60 | public static void main(String[] args) throws InterruptedException { 61 | AtomicLong exceptionCounter = new AtomicLong(); 62 | AtomicLong respCounter = new AtomicLong(); 63 | Thread exceptionThread = new Thread(() -> { 64 | while (true) { 65 | try { 66 | getUserByUserIdLimitByAppIdWithException("", ""); 67 | } catch (InvokeException ignored) { 68 | throw new RTException(ignored); 69 | } 70 | exceptionCounter.incrementAndGet(); 71 | } 72 | }); 73 | Thread respThread = new Thread(() -> { 74 | while (true) { 75 | getUserByUserIdLimitByAppIdWithResp("", ""); 76 | respCounter.incrementAndGet(); 77 | } 78 | }); 79 | long timestamp = Instant.now().toEpochMilli(); 80 | exceptionThread.start(); 81 | respThread.start(); 82 | while (true) { 83 | Thread.sleep(1000); 84 | System.out.println( 85 | String.format("Elapsed time %ss -> exception count %sw | resp count %sw", 86 | (Instant.now().toEpochMilli() - timestamp) / 1000, exceptionCounter.get() / 10000, respCounter.get() / 10000)); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/FallbackHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.FallbackHelper; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * The type Fallback helper test. 10 | * 11 | * @author gudaoxuri 12 | */ 13 | public class FallbackHelperTest { 14 | 15 | /** 16 | * Test get user. 17 | */ 18 | @Test 19 | public void testGetUser() { 20 | String result = $.fallback.execute("testGetUser", 21 | this::getUserNormal, 22 | this::getUserError); 23 | Assertions.assertEquals("-1", result); 24 | } 25 | 26 | /** 27 | * Test get user with strategy. 28 | */ 29 | @Test 30 | public void testGetUserWithStrategy() { 31 | for (int i = 0; i < 10; i++) { 32 | Assertions.assertEquals("-1", getUserWithStrategy()); 33 | } 34 | Assertions.assertEquals("-2", getUserWithStrategy()); 35 | Assertions.assertEquals("-2", getUserWithStrategy()); 36 | Assertions.assertEquals("-2", getUserWithStrategy()); 37 | Assertions.assertEquals("-2", getUserWithStrategy()); 38 | Assertions.assertEquals("-2", getUserWithStrategy()); 39 | Assertions.assertEquals("-1", getUserWithStrategy()); 40 | } 41 | 42 | private String getUserWithStrategy() { 43 | return $.fallback.execute("testGetUserWithStrategy", 44 | this::getUserNormal, 45 | this::getUserError, info -> { 46 | if (info.getRequestTimes() - info.getSuccessTimes() > 15) { 47 | info.setStatus(FallbackHelper.FallbackStatus.GREEN); 48 | } else if (info.getRequestTimes() - info.getSuccessTimes() > 10) { 49 | info.setStatus(FallbackHelper.FallbackStatus.YELLOW); 50 | return false; 51 | } 52 | return true; 53 | }); 54 | } 55 | 56 | /** 57 | * Test get user without some exception. 58 | */ 59 | @Test 60 | public void testGetUserWithoutSomeException() { 61 | try { 62 | $.fallback.execute("testGetUserWithoutSomeException", 63 | this::getUserNormal, 64 | this::getUserError, NotFoundException.class); 65 | } catch (Throwable e) { 66 | if (e.getCause().getClass() != NotFoundException.class) { 67 | Assertions.fail(); 68 | } 69 | } 70 | } 71 | 72 | private String getUserNormal() throws Exception { 73 | throw new NotFoundException("Not Found xxx"); 74 | } 75 | 76 | 77 | private String getUserError(Throwable e, FallbackHelper.FallbackInfo fallbackInfo) { 78 | return e.getClass() == FallbackHelper.FallbackException.class ? "-2" : "-1"; 79 | } 80 | 81 | /** 82 | * The type Not found exception. 83 | */ 84 | public static class NotFoundException extends Exception { 85 | /** 86 | * Instantiates a new Not found exception. 87 | * 88 | * @param message the message 89 | */ 90 | public NotFoundException(String message) { 91 | super(message); 92 | } 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/ReportHandler.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 任务报告接口. 8 | * 9 | * @author gudaoxuri 10 | */ 11 | public abstract class ReportHandler { 12 | 13 | private boolean isSuccess = false; 14 | private boolean isFail = false; 15 | private String failMessage = ""; 16 | private int progress = 0; 17 | private List output = new ArrayList<>(); 18 | private List error = new ArrayList<>(); 19 | 20 | /** 21 | * 是否成功 22 | * 23 | * @return 是否成功 24 | */ 25 | public final boolean isSuccess() { 26 | return isSuccess; 27 | } 28 | 29 | /** 30 | * 是否失败 31 | * 32 | * @return 是否失败 33 | */ 34 | public final boolean isFail() { 35 | return isFail; 36 | } 37 | 38 | /** 39 | * 获取失败原因 40 | * 41 | * @return 失败原因 42 | */ 43 | public final String getFailMessage() { 44 | return failMessage; 45 | } 46 | 47 | /** 48 | * 获取进度 49 | * 50 | * @return 进度 51 | */ 52 | public final int getProgress() { 53 | return progress; 54 | } 55 | 56 | /** 57 | * 获取输出内容 58 | * 59 | * @return 输出内容 60 | */ 61 | public final List getOutput() { 62 | return output; 63 | } 64 | 65 | /** 66 | * 获取错误信息 67 | * 68 | * @return 错误信息 69 | */ 70 | public final List getError() { 71 | return error; 72 | } 73 | 74 | /** 75 | * 成功,在执行到successFlag时调用. 76 | */ 77 | final void onSuccess() { 78 | this.isSuccess = true; 79 | success(); 80 | } 81 | 82 | /** 83 | * 输出每行错误输出数据. 84 | * 85 | * @param line 输出行内容 86 | */ 87 | public void errorlog(String line) { 88 | 89 | } 90 | 91 | /** 92 | * 输出每行标准输出数据. 93 | * 94 | * @param line 输出行内容 95 | */ 96 | public void outputlog(String line) { 97 | 98 | } 99 | 100 | /** 101 | * 成功,在执行到successFlag时调用. 102 | */ 103 | public void success() { 104 | 105 | } 106 | 107 | /** 108 | * 失败,在发生错误时调用. 109 | * 110 | * @param message 失败原因描述 111 | */ 112 | final void onFail(String message) { 113 | this.isFail = true; 114 | this.failMessage = message; 115 | fail(message); 116 | } 117 | 118 | /** 119 | * 失败,在发生错误时调用. 120 | * 121 | * @param message 失败原因描述 122 | */ 123 | public void fail(String message) { 124 | 125 | } 126 | 127 | /** 128 | * 进度回调,在执行到progressFlag且格式正确时调用. 129 | * 130 | * @param progress 0-100 131 | */ 132 | final void onProgress(int progress) { 133 | this.progress = progress; 134 | progress(progress); 135 | } 136 | 137 | /** 138 | * 进度回调,在执行到progressFlag且格式正确时调用. 139 | * 140 | * @param progress 0-100 141 | */ 142 | public void progress(int progress) { 143 | } 144 | 145 | /** 146 | * 完成,无论是否成功,在执行完成时(success 或 fail 方法后)调用. 147 | * 148 | * @param output stdout标准输出结果 149 | * @param error stderr标准错误结果 150 | */ 151 | final void onComplete(List output, List error) { 152 | this.output = output; 153 | this.error = error; 154 | complete(output, error); 155 | } 156 | 157 | /** 158 | * 完成,无论是否成功,在执行完成时(success 或 fail 方法后)调用. 159 | * 160 | * @param output stdout结果 161 | * @param error stderr结果 162 | */ 163 | public void complete(List output, List error) { 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/FileHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.io.File; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | 13 | /** 14 | * The type File helper test. 15 | * 16 | * @author gudaoxuri 17 | */ 18 | public class FileHelperTest { 19 | 20 | private String currentPath; 21 | 22 | { 23 | currentPath = FileHelperTest.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 24 | File file = new File(currentPath); 25 | currentPath = file.getPath(); 26 | if (file.isFile()) { 27 | currentPath = file.getParentFile().getPath(); 28 | } 29 | System.out.println("Current Path:" + currentPath); 30 | } 31 | 32 | /** 33 | * Test file. 34 | */ 35 | @Test 36 | public void testFile() { 37 | String conf = $.file.readAllByClassPath("conf1.json", "UTF-8"); 38 | assertTrue(conf.contains("1")); 39 | conf = $.file.readAllByClassPath("conf/conf2.json", "UTF-8"); 40 | assertTrue(conf.contains("2")); 41 | 42 | $.file.copyStreamToPath(Test.class.getResourceAsStream("/META-INF/LICENSE.md"), currentPath + File.separator + "LICENSE-junit-copy" + 43 | ".txt"); 44 | assertTrue(new File(currentPath + File.separator + "LICENSE-junit-copy.txt").exists()); 45 | new File(currentPath + File.separator + "LICENSE-junit-copy.txt").delete(); 46 | // Glob Math 47 | List files = new ArrayList<>() { 48 | { 49 | add("/models/parent/pom.xml"); 50 | add("/models/kernel/pom.xml"); 51 | add("/models/kernel/src/main/java/com/ecfront/test/Test.java"); 52 | add("/models/kernel/src/main/java/com/ecfront/test/Main.java"); 53 | add("/models/kernel/src/main/resource/bootstrap.yml"); 54 | add("/models/kernel/src/main/resource/application.yml"); 55 | add("/models/pom.xml"); 56 | add("/models/README.adoc"); 57 | add("/models/.gitignore"); 58 | } 59 | }; 60 | List matchFiles = $.file.mathFilter(files, new ArrayList<>()); 61 | assertEquals(files.size(), matchFiles.size()); 62 | matchFiles = $.file.mathFilter(files, new ArrayList<>() { 63 | { 64 | add("/models/*.xml"); 65 | } 66 | }); 67 | assertEquals(1, matchFiles.size()); 68 | matchFiles = $.file.mathFilter(files, new ArrayList<>() { 69 | { 70 | add("**/*.xml"); 71 | } 72 | }); 73 | assertEquals(3, matchFiles.size()); 74 | matchFiles = $.file.mathFilter(files, new ArrayList<>() { 75 | { 76 | add("**/*.xml"); 77 | add("**/*.{java,yml}"); 78 | } 79 | }); 80 | assertEquals(7, matchFiles.size()); 81 | matchFiles = $.file.mathFilter(files, new ArrayList<>() { 82 | { 83 | add("**/java/**"); 84 | } 85 | }); 86 | assertEquals(2, matchFiles.size()); 87 | assertTrue($.file.anyMath(files, new ArrayList<>() { 88 | { 89 | add("**/java/**"); 90 | } 91 | })); 92 | assertTrue($.file.noneMath(files, new ArrayList<>() { 93 | { 94 | add("**/java/*"); 95 | } 96 | })); 97 | 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/AmountHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * 金额操作. 8 | * 9 | * @author Based By https://gist.github.com/binjoo/6028263 10 | */ 11 | public class AmountHelper { 12 | 13 | private static final Pattern AMOUNT_PATTERN = 14 | Pattern.compile("^(0|[1-9]\\d{0,11})\\.(\\d\\d)$"); // 不考虑分隔符的正确性 15 | private static final char[] RMB_NUMS = "零壹贰叁肆伍陆柒捌玖".toCharArray(); 16 | private static final String[] UNITS = {"元", "角", "分", "整"}; 17 | private static final String[] U1 = {"", "拾", "佰", "仟"}; 18 | private static final String[] U2 = {"", "万", "亿"}; 19 | 20 | // 将金额小数部分转换为中文大写 21 | private static String fraction2rmb(String fraction) { 22 | char jiao = fraction.charAt(0); // 角 23 | char fen = fraction.charAt(1); // 分 24 | return (RMB_NUMS[jiao - '0'] + (jiao > '0' ? UNITS[1] : "")) 25 | + (fen > '0' ? RMB_NUMS[fen - '0'] + UNITS[2] : ""); 26 | } 27 | 28 | // 将金额整数部分转换为中文大写 29 | private static String integer2rmb(String integer) { 30 | StringBuilder buffer = new StringBuilder(); 31 | // 从个位数开始转换 32 | int i; 33 | int j; 34 | for (i = integer.length() - 1, j = 0; i >= 0; i--, j++) { 35 | char n = integer.charAt(i); 36 | if (n == '0') { 37 | // 当n是0且n的右边一位不是0时,插入[零] 38 | if (i < integer.length() - 1 && integer.charAt(i + 1) != '0') { 39 | buffer.append(RMB_NUMS[0]); 40 | } 41 | // 插入[万]或者[亿] 42 | if (j % 4 == 0) { 43 | if (i > 0 && integer.charAt(i - 1) != '0' 44 | || i > 1 && integer.charAt(i - 2) != '0' 45 | || i > 2 && integer.charAt(i - 3) != '0') { 46 | buffer.append(U2[j / 4]); 47 | } 48 | } 49 | } else { 50 | if (j % 4 == 0) { 51 | buffer.append(U2[j / 4]); // 插入[万]或者[亿] 52 | } 53 | buffer.append(U1[j % 4]); // 插入[拾]、[佰]或[仟] 54 | buffer.append(RMB_NUMS[n - '0']); // 插入数字 55 | } 56 | } 57 | return buffer.reverse().toString(); 58 | } 59 | 60 | /** 61 | * 将金额(整数部分等于或少于12位,小数部分2位)转换为中文大写形式. 62 | * 63 | * @param amount 金额数字 64 | * @return 中文大写 string 65 | * @throws IllegalArgumentException the illegal argument exception 66 | */ 67 | public String convert(String amount) throws IllegalArgumentException { 68 | amount = amount.replace(",", ""); 69 | String[] amountArray = amount.split("\\."); 70 | if (amountArray.length != 2) { 71 | amount = amount + ".00"; 72 | } else { 73 | if (amountArray[1].length() == 1) { 74 | amount = amount + "0"; 75 | } 76 | } 77 | if (amount.equals("0.00")) { 78 | return "零元整"; 79 | } 80 | Matcher matcher = AMOUNT_PATTERN.matcher(amount); 81 | if (!matcher.find()) { 82 | throw new IllegalArgumentException("输入金额有误."); 83 | } 84 | String integer = matcher.group(1); // 整数部分 85 | String fraction = matcher.group(2); // 小数部分 86 | StringBuilder sb = new StringBuilder(); 87 | if (!integer.equals("0")) { 88 | sb.append(integer2rmb(integer)).append(UNITS[0]); // 整数部分 89 | } 90 | if (fraction.equals("00")) { 91 | sb.append(UNITS[3]); // 添加[整] 92 | } else if (fraction.startsWith("0") && integer.equals("0")) { 93 | sb.append(fraction2rmb(fraction).substring(1)); // 去掉分前面的[零] 94 | } else { 95 | sb.append(fraction2rmb(fraction)); // 小数部分 96 | } 97 | return sb.toString(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/$.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | /** 4 | * DEW Common 操作入口. 5 | * 6 | * @author gudaoxuri 7 | */ 8 | public final class $ { 9 | 10 | private $() { 11 | } 12 | 13 | /** 14 | * Json与Java对象互转. 15 | */ 16 | public static JsonHelper json = JsonHelper.pick(""); 17 | /** 18 | * Java Bean操作. 19 | */ 20 | public static BeanHelper bean = new BeanHelper(); 21 | /** 22 | * Java Class扫描操作. 23 | */ 24 | public static ClassScanHelper clazz = new ClassScanHelper(); 25 | /** 26 | * 安全(加解密、信息摘要等)操作. 27 | */ 28 | public static SecurityHelper security = new SecurityHelper(); 29 | /** 30 | * 常用字段操作. 31 | */ 32 | public static FieldHelper field = new FieldHelper(); 33 | /** 34 | * 常用文件操作. 35 | */ 36 | public static FileHelper file = new FileHelper(); 37 | /** 38 | * MIME信息操作. 39 | */ 40 | public static MimeHelper mime = new MimeHelper(); 41 | /** 42 | * 定时器操作. 43 | */ 44 | public static TimerHelper timer = new TimerHelper(); 45 | /** 46 | * Shell脚本操作. 47 | */ 48 | public static ShellHelper shell = new ShellHelper(); 49 | /** 50 | * 拦截器栈执行器. 51 | */ 52 | public static InterceptorHelper interceptor = new InterceptorHelper(); 53 | /** 54 | * Http操作. 55 | */ 56 | public static HttpHelper http = new HttpHelper(-1, true); 57 | /** 58 | * 金额操作. 59 | */ 60 | public static AmountHelper amount = new AmountHelper(); 61 | /** 62 | * 函数操作. 63 | */ 64 | public static FunctionHelper fun = new FunctionHelper(); 65 | /** 66 | * 简单的降级处理. 67 | */ 68 | public static FallbackHelper fallback = new FallbackHelper(); 69 | 70 | /** 71 | * Json与Java对象互转. 72 | *

73 | * 使用自定义实例ID(用于支持不同Json配置) 74 | * 75 | * @param instanceId 实例Id 76 | * @return 对应实例的Json操作 json helper 77 | */ 78 | public static JsonHelper json(String instanceId) { 79 | assert instanceId != null && !instanceId.trim().equals(""); 80 | return JsonHelper.pick(instanceId); 81 | } 82 | 83 | /** 84 | * Java Bean操作. 85 | * 86 | * @param useCache 是否启用缓存,启用后会缓存获取过的字段和方法列表,默认启用 87 | * @return 是启用缓存的Bean操作 bean helper 88 | */ 89 | public static BeanHelper bean(boolean useCache) { 90 | return new BeanHelper(useCache); 91 | } 92 | 93 | /** 94 | * 时间操作. 95 | * 96 | * @return 时间操作实例 time helper 97 | */ 98 | public static TimeHelper time() { 99 | return new TimeHelper(); 100 | } 101 | 102 | /** 103 | * Http操作. 104 | * 105 | * @param timeoutMS 默认超时时间 106 | * @param autoRedirect 302状态下是否自动跳转 107 | * @return HTTP操作实例 http helper 108 | */ 109 | public static HttpHelper http(int timeoutMS, boolean autoRedirect) { 110 | return new HttpHelper(timeoutMS, autoRedirect); 111 | } 112 | 113 | /** 114 | * 脚本处理. 115 | *

116 | * 包含预编译,适用于脚本复用性的场景 117 | * 118 | * @param scriptKind the script kind 119 | * @param scriptFunsCode the script funs code 120 | * @param addCommonCode 是否添加dew-common包到脚本 121 | * @return 脚本操作实例 script helper 122 | */ 123 | public static ScriptHelper script(ScriptHelper.ScriptKind scriptKind, String scriptFunsCode, boolean addCommonCode) { 124 | return ScriptHelper.build(scriptKind, scriptFunsCode, addCommonCode); 125 | } 126 | 127 | /** 128 | * 脚本处理. 129 | *

130 | * 包含预编译,适用于脚本复用性的场景,默认添加dew-common包到脚本 131 | * 132 | * @param scriptKind the script kind 133 | * @param scriptFunsCode the script funs code 134 | * @return 脚本操作实例 script helper 135 | */ 136 | public static ScriptHelper script(ScriptHelper.ScriptKind scriptKind, String scriptFunsCode) { 137 | return ScriptHelper.build(scriptKind, scriptFunsCode, true); 138 | } 139 | 140 | /** 141 | * 脚本处理. 142 | *

143 | * 适用于简单的脚本的执行 144 | * 145 | * @param the type parameter 146 | * @param scriptKind the script kind 147 | * @param returnClazz the return clazz 148 | * @param scriptCode the script code 149 | * @return 脚本执行结果 object 150 | */ 151 | public static T eval(ScriptHelper.ScriptKind scriptKind, Class returnClazz, String scriptCode) { 152 | return ScriptHelper.eval(scriptKind, returnClazz, scriptCode); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/InterceptorTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.Resp; 5 | import com.ecfront.dew.common.interceptor.DewInterceptContext; 6 | import com.ecfront.dew.common.interceptor.DewInterceptor; 7 | import org.junit.jupiter.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import java.util.HashMap; 11 | 12 | /** 13 | * The type Interceptor test. 14 | * 15 | * @author gudaoxuri 16 | */ 17 | public class InterceptorTest { 18 | 19 | /** 20 | * Test interceptor. 21 | */ 22 | @Test 23 | public void testInterceptor() { 24 | // 没有注册拦截器的情况 25 | Resp> resp = $.interceptor.process("none", new Obj("1"), new HashMap<>(), context -> { 26 | // 业务逻辑,只做简单将input对象copy到output对象 27 | context.setOutput(new Obj(context.getInput().getF())); 28 | return Resp.success(context); 29 | }); 30 | Assertions.assertTrue(resp.ok()); 31 | Assertions.assertEquals("1", resp.getBody().getOutput().getF()); 32 | // 注册了一个拦截器A 33 | $.interceptor.register("test", new InterceptorA()); 34 | resp = $.interceptor.process("test", new Obj("1"), new HashMap<>(), context -> { 35 | // 业务逻辑,只做简单将input对象copy到output对象 36 | context.setOutput(new Obj(context.getInput().getF())); 37 | return Resp.success(context); 38 | }); 39 | Assertions.assertTrue(resp.ok()); 40 | Assertions.assertEquals("2", resp.getBody().getInput().getF()); 41 | Assertions.assertEquals("3", resp.getBody().getOutput().getF()); 42 | // 注册了另一个拦截器B,假设B执行会报错 43 | $.interceptor.register("test", new InterceptorB()); 44 | resp = $.interceptor.process("test", new Obj("11"), new HashMap<>(), context -> { 45 | // 业务逻辑,只做简单将input对象copy到output对象 46 | context.setOutput(new Obj(context.getInput().getF())); 47 | return Resp.success(context); 48 | }); 49 | Assertions.assertFalse(resp.ok()); 50 | } 51 | 52 | 53 | /** 54 | * The type Obj. 55 | */ 56 | public static class Obj { 57 | private String f; 58 | 59 | /** 60 | * Instantiates a new Obj. 61 | */ 62 | public Obj() { 63 | } 64 | 65 | /** 66 | * Instantiates a new Obj. 67 | * 68 | * @param f the f 69 | */ 70 | public Obj(String f) { 71 | this.f = f; 72 | } 73 | 74 | /** 75 | * Gets f. 76 | * 77 | * @return the f 78 | */ 79 | public String getF() { 80 | return f; 81 | } 82 | 83 | /** 84 | * Sets f. 85 | * 86 | * @param f the f 87 | */ 88 | public void setF(String f) { 89 | this.f = f; 90 | } 91 | } 92 | 93 | /** 94 | * The type Interceptor a. 95 | */ 96 | public static class InterceptorA implements DewInterceptor { 97 | 98 | @Override 99 | public String getCategory() { 100 | return "test"; 101 | } 102 | 103 | @Override 104 | public String getName() { 105 | return "A"; 106 | } 107 | 108 | @Override 109 | public Resp> before(DewInterceptContext context) { 110 | context.getInput().setF("2"); 111 | return Resp.success(context); 112 | } 113 | 114 | @Override 115 | public Resp> after(DewInterceptContext context) { 116 | context.getOutput().setF("3"); 117 | return Resp.success(context); 118 | } 119 | 120 | } 121 | 122 | /** 123 | * The type Interceptor b. 124 | */ 125 | public static class InterceptorB implements DewInterceptor { 126 | 127 | @Override 128 | public String getCategory() { 129 | return "test"; 130 | } 131 | 132 | @Override 133 | public String getName() { 134 | return "B"; 135 | } 136 | 137 | @Override 138 | public Resp> before(DewInterceptContext context) { 139 | return Resp.badRequest("some error"); 140 | } 141 | 142 | @Override 143 | public Resp> after(DewInterceptContext context) { 144 | return Resp.success(context); 145 | } 146 | 147 | @Override 148 | public void error(DewInterceptContext context) { 149 | context.getInput().setF("error"); 150 | } 151 | } 152 | 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/ShellHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.ReportHandler; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.concurrent.CountDownLatch; 12 | import java.util.concurrent.ExecutionException; 13 | 14 | /** 15 | * The type Shell helper test. 16 | * 17 | * @author gudaoxuri 18 | */ 19 | public class ShellHelperTest { 20 | 21 | /** 22 | * Test env. 23 | * 24 | * @throws InterruptedException the interrupted exception 25 | * @throws ExecutionException the execution exception 26 | */ 27 | @Test 28 | public void testENV() throws InterruptedException, ExecutionException { 29 | $.shell.execute("cd xxx && npm run build:uat", new HashMap<>() { 30 | { 31 | put("NODE_ENV", "uat"); 32 | } 33 | }, null, null, false, new ReportHandler() { 34 | @Override 35 | public void outputlog(String line) { 36 | System.out.println("O:" + line); 37 | } 38 | 39 | @Override 40 | public void fail(String message) { 41 | System.out.println("F:" + message); 42 | } 43 | 44 | @Override 45 | public void errorlog(String line) { 46 | System.out.println("E:" + line); 47 | } 48 | }).get(); 49 | } 50 | 51 | /** 52 | * Test. 53 | */ 54 | @Test 55 | public void test() { 56 | // Error test 57 | Assertions.assertTrue($.shell.execute("abc").getMessage().contains("Abnormal termination")); 58 | // Normal test 59 | List result; 60 | if ($.file.isWindows()) { 61 | result = $.shell.execute("dir").getBody(); 62 | } else { 63 | result = $.shell.execute("ls -l").getBody(); 64 | } 65 | Assertions.assertFalse(result.isEmpty()); 66 | result = $.shell.execute("git remote -v").getBody(); 67 | Assertions.assertTrue(result.stream().anyMatch(i -> i.contains("dew-common.git"))); 68 | } 69 | 70 | /** 71 | * Test bash. 72 | *

73 | * NOTE: travis-ci 中执行有问题 74 | * 75 | * @throws InterruptedException the interrupted exception 76 | */ 77 | @Test 78 | public void testBash() throws InterruptedException { 79 | if (!$.file.isWindows()) { 80 | final List statusResult = new ArrayList<>(); 81 | CountDownLatch cdl = new CountDownLatch(1); 82 | String testFilePath = this.getClass().getResource("/").getPath(); 83 | $.shell.execute("chmod 777 " + testFilePath + "shell-test.sh"); 84 | $.shell.execute(testFilePath + "shell-test.sh", // 执行脚本 85 | "done!", // 成功标识,只要捕捉到此标识就视为成功,为null时不会调用ReportHandler的success方法 86 | "step", // 进度标识,只要捕捉到此标识就更新进度,格式为 空格,如: progress 40,为null时不会调用ReportHandler的progress方法 87 | true, // 是否返回结果(输出内容,包含标准输出stdout及错误输出stderr),为true时会返回结果到ReportHandler的complete方法中,结果暂存于内存中,对输出内容过多的脚本需要考虑占用内存的大小 88 | new ReportHandler() { 89 | 90 | @Override 91 | public void success() { 92 | statusResult.add("Success"); 93 | } 94 | 95 | @Override 96 | public void fail(String message) { 97 | statusResult.add("Fail:" + message); 98 | } 99 | 100 | @Override 101 | public void progress(int progress) { 102 | statusResult.add("Progress:" + progress); 103 | } 104 | 105 | @Override 106 | public void complete(List output, List error) { 107 | Assertions.assertEquals("Start", statusResult.get(0)); 108 | Assertions.assertEquals("Progress:10", statusResult.get(1)); 109 | Assertions.assertEquals("Progress:70", statusResult.get(2)); 110 | Assertions.assertEquals("Success", statusResult.get(3)); 111 | 112 | Assertions.assertEquals("Hello", output.get(1)); 113 | Assertions.assertEquals("World", output.get(3)); 114 | 115 | Assertions.assertEquals("some error", error.get(0)); 116 | cdl.countDown(); 117 | } 118 | }); 119 | statusResult.add("Start"); 120 | cdl.await(); 121 | } 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/Page.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | import java.util.function.Function; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * 分页对象. 10 | * 11 | * @param the type parameter 12 | * @author gudaoxuri 13 | */ 14 | public class Page implements Serializable { 15 | 16 | /** 17 | * 当前页,从1开始. 18 | */ 19 | private long pageNumber; 20 | /** 21 | * 每页记录数. 22 | */ 23 | private long pageSize; 24 | /** 25 | * 总页数. 26 | */ 27 | private long pageTotal; 28 | /** 29 | * 总记录数. 30 | */ 31 | private long recordTotal; 32 | /** 33 | * 实际对象. 34 | */ 35 | private List objects; 36 | 37 | /** 38 | * Build page. 39 | * 40 | * @param the type parameter 41 | * @param pageNumber the page number 42 | * @param pageSize the page size 43 | * @param recordTotal the record total 44 | * @param objects the objects 45 | * @return the page 46 | */ 47 | public static Page build(long pageNumber, long pageSize, long recordTotal, List objects) { 48 | Page dto = new Page<>(); 49 | dto.pageNumber = pageNumber; 50 | dto.pageSize = pageSize; 51 | dto.recordTotal = recordTotal; 52 | dto.pageTotal = (recordTotal + pageSize - 1) / pageSize; 53 | dto.objects = objects; 54 | return dto; 55 | } 56 | 57 | /** 58 | * Convert page. 59 | * 60 | * @param the type parameter 61 | * @param converter the converter 62 | * @return the page 63 | */ 64 | public Page convert(Function converter) { 65 | Page page = new Page<>(); 66 | page.setPageNumber(this.getPageNumber()); 67 | page.setPageSize(this.getPageSize()); 68 | page.setPageTotal(this.getPageTotal()); 69 | page.setRecordTotal(this.getRecordTotal()); 70 | if (this.getObjects() != null) { 71 | page.setObjects(this.getObjects().stream() 72 | .map(converter) 73 | .collect(Collectors.toList())); 74 | } else { 75 | page.setObjects(null); 76 | } 77 | return page; 78 | } 79 | 80 | /** 81 | * Is first page. 82 | * 83 | * @return the boolean 84 | */ 85 | public boolean isFirstPage() { 86 | return pageNumber == 1; 87 | } 88 | 89 | /** 90 | * Is last page. 91 | * 92 | * @return the boolean 93 | */ 94 | public boolean isLastPage() { 95 | return pageNumber == pageTotal; 96 | } 97 | 98 | /** 99 | * Has next page. 100 | * 101 | * @return the boolean 102 | */ 103 | public boolean hasNextPage() { 104 | return pageNumber < pageTotal; 105 | } 106 | 107 | /** 108 | * Gets page number. 109 | * 110 | * @return the page number 111 | */ 112 | public long getPageNumber() { 113 | return pageNumber; 114 | } 115 | 116 | /** 117 | * Sets page number. 118 | * 119 | * @param pageNumber the page number 120 | */ 121 | public void setPageNumber(long pageNumber) { 122 | this.pageNumber = pageNumber; 123 | } 124 | 125 | /** 126 | * Gets page size. 127 | * 128 | * @return the page size 129 | */ 130 | public long getPageSize() { 131 | return pageSize; 132 | } 133 | 134 | /** 135 | * Sets page size. 136 | * 137 | * @param pageSize the page size 138 | */ 139 | public void setPageSize(long pageSize) { 140 | this.pageSize = pageSize; 141 | } 142 | 143 | /** 144 | * Gets page total. 145 | * 146 | * @return the page total 147 | */ 148 | public long getPageTotal() { 149 | return pageTotal; 150 | } 151 | 152 | /** 153 | * Sets page total. 154 | * 155 | * @param pageTotal the page total 156 | */ 157 | public void setPageTotal(long pageTotal) { 158 | this.pageTotal = pageTotal; 159 | } 160 | 161 | /** 162 | * Gets record total. 163 | * 164 | * @return the record total 165 | */ 166 | public long getRecordTotal() { 167 | return recordTotal; 168 | } 169 | 170 | /** 171 | * Sets record total. 172 | * 173 | * @param recordTotal the record total 174 | */ 175 | public void setRecordTotal(long recordTotal) { 176 | this.recordTotal = recordTotal; 177 | } 178 | 179 | /** 180 | * Gets objects. 181 | * 182 | * @return the objects 183 | */ 184 | public List getObjects() { 185 | return objects; 186 | } 187 | 188 | /** 189 | * Sets objects. 190 | * 191 | * @param objects the objects 192 | */ 193 | public void setObjects(List objects) { 194 | this.objects = objects; 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/ScriptHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.exception.RTScriptException; 4 | import org.graalvm.polyglot.Context; 5 | import org.graalvm.polyglot.Source; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * The type Script helper. 12 | * 13 | * @author gudaoxuri 14 | */ 15 | public final class ScriptHelper { 16 | 17 | private final Context context; 18 | private final ScriptKind scriptKind; 19 | private ScriptHelper(Context context, ScriptKind scriptKind) { 20 | this.context = context; 21 | this.scriptKind = scriptKind; 22 | } 23 | 24 | /** 25 | * Build script helper. 26 | * 27 | * @param scriptKind the script kind 28 | * @param scriptFunsCode the script funs code 29 | * @param addCommonCode the add common code 30 | * @return the script helper 31 | * @throws RTScriptException the rt script exception 32 | */ 33 | public static ScriptHelper build(ScriptKind scriptKind, String scriptFunsCode, boolean addCommonCode) throws RTScriptException { 34 | try { 35 | Context context = Context.newBuilder().allowAllAccess(true).build(); 36 | if (addCommonCode) { 37 | switch (scriptKind) { 38 | case JS: 39 | scriptFunsCode = "const $ = Java.type('com.ecfront.dew.common.$')\r\n" + scriptFunsCode; 40 | break; 41 | case PYTHON: 42 | // TODO 43 | scriptFunsCode = "import java\r\n$ = java.type(\"com.ecfront.dew.common.$\")\r\n" + scriptFunsCode; 44 | break; 45 | case RUBY: 46 | // TODO 47 | scriptFunsCode = "$ = Java.type('com.ecfront.dew.common.$')\r\n" + scriptFunsCode; 48 | break; 49 | case R: 50 | // TODO 51 | scriptFunsCode = "$ <- java.type('com.ecfront.dew.common.$')\r\n" + scriptFunsCode; 52 | break; 53 | default: 54 | throw new RTScriptException("Script kind {" + scriptKind + "} NOT exist."); 55 | } 56 | } 57 | context.eval(Source.newBuilder(scriptKind.toString(), scriptFunsCode, "src.js").build()); 58 | return new ScriptHelper(context, scriptKind); 59 | } catch (IOException e) { 60 | throw new RTScriptException(e); 61 | } 62 | } 63 | 64 | /** 65 | * Eval object. 66 | * 67 | * @param the type parameter 68 | * @param scriptKind the script kind 69 | * @param returnClazz the return clazz 70 | * @param scriptCode the script code 71 | * @return the object 72 | * @throws RTScriptException the rt script exception 73 | */ 74 | public static T eval(ScriptKind scriptKind, Class returnClazz, String scriptCode) { 75 | try (Context context = Context.newBuilder().allowAllAccess(true).build()) { 76 | return context.eval(scriptKind.toString(), scriptCode).as(returnClazz); 77 | } 78 | } 79 | 80 | /** 81 | * Execute. 82 | * 83 | * @param the type parameter 84 | * @param funName the fun name 85 | * @param returnClazz the return clazz 86 | * @param args the args 87 | * @return the t 88 | */ 89 | public T execute(String funName, Class returnClazz, Object... args) { 90 | return context.getBindings(scriptKind.toString()).getMember(funName).execute(args).as(returnClazz); 91 | } 92 | 93 | /** 94 | * The enum Script kind. 95 | */ 96 | public enum ScriptKind { 97 | /** 98 | * Js script kind. 99 | */ 100 | JS("js"), 101 | /** 102 | * Python script kind. 103 | */ 104 | PYTHON("python"), 105 | /** 106 | * Ruby script kind. 107 | */ 108 | RUBY("ruby"), 109 | /** 110 | * R script kind. 111 | */ 112 | R("r"); 113 | 114 | private final String code; 115 | 116 | ScriptKind(String code) { 117 | this.code = code; 118 | } 119 | 120 | /** 121 | * Parse script kind. 122 | * 123 | * @param code the code 124 | * @return the script kind 125 | */ 126 | public static ScriptKind parse(String code) { 127 | return Arrays.stream(ScriptKind.values()) 128 | .filter(item -> item.code.equalsIgnoreCase(code)) 129 | .findFirst() 130 | .orElseThrow(() -> new RTScriptException("Script kind {" + code + "} NOT exist.")); 131 | } 132 | 133 | @Override 134 | public String toString() { 135 | return code; 136 | } 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/InterceptorHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.interceptor.DewInterceptContext; 4 | import com.ecfront.dew.common.interceptor.DewInterceptExec; 5 | import com.ecfront.dew.common.interceptor.DewInterceptor; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * 拦截器栈执行器. 16 | * 17 | * @author gudaoxuri 18 | */ 19 | public class InterceptorHelper { 20 | 21 | private static final Logger LOGGER = LoggerFactory.getLogger(InterceptorHelper.class); 22 | 23 | private static final Map>> CONTAINER = new HashMap<>(); 24 | 25 | /** 26 | * Instantiates a new Interceptor helper. 27 | */ 28 | InterceptorHelper() { 29 | } 30 | 31 | private static Resp> doProcess(DewInterceptContext context, 32 | List> interceptors, boolean isBefore) { 33 | Resp> result = Resp.success(context); 34 | for (DewInterceptor interceptor : interceptors) { 35 | LOGGER.trace("[DewInterceptorProcessor] Process interceptor [{}]:{}-{}", 36 | interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after"); 37 | DewInterceptor interceptorE = (DewInterceptor) interceptor; 38 | try { 39 | if (isBefore) { 40 | result = interceptorE.before(context); 41 | } else { 42 | result = interceptorE.after(context); 43 | } 44 | if (!result.ok()) { 45 | LOGGER.warn("[DewInterceptorProcessor] Process interceptor error [{}]:{}-{},[{}]{}", 46 | interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after", result.getCode(), result.getMessage()); 47 | interceptorE.error(context); 48 | return result; 49 | } 50 | } catch (Throwable e) { 51 | result = Resp.serverError(e.getMessage()); 52 | LOGGER.error("[DewInterceptorProcessor] Process interceptor error [{}]:{}-{},[{}]{}", 53 | interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after", result.getCode(), result.getMessage()); 54 | interceptorE.error(context); 55 | return result; 56 | } 57 | } 58 | return result; 59 | } 60 | 61 | /** 62 | * 注册拦截器栈. 63 | * 64 | * @param category 拦截类型 65 | * @param interceptor 拦截器 66 | */ 67 | public void register(String category, DewInterceptor interceptor) { 68 | if (!CONTAINER.containsKey(category)) { 69 | CONTAINER.put(category, new ArrayList<>()); 70 | } 71 | CONTAINER.get(category).add(interceptor); 72 | } 73 | 74 | /** 75 | * 注册拦截器栈. 76 | * 77 | * @param category 拦截类型 78 | * @param interceptors 拦截器列表 79 | */ 80 | public void register(String category, List> interceptors) { 81 | CONTAINER.put(category, interceptors); 82 | } 83 | 84 | /** 85 | * 拦截器栈处理方法. 86 | * 87 | * @param the type parameter 88 | * @param the type parameter 89 | * @param category 拦截类型 90 | * @param input 初始入栈对象 91 | * @param fun 实际执行方法 92 | * @return the resp 93 | */ 94 | public Resp> process(String category, I input, DewInterceptExec fun) { 95 | return process(category, input, new HashMap<>(), fun); 96 | } 97 | 98 | /** 99 | * 拦截器栈处理方法. 100 | * 101 | * @param the type parameter 102 | * @param the type parameter 103 | * @param category 拦截类型 104 | * @param input 初始入栈对象 105 | * @param args 初始入栈参数 106 | * @param fun 实际执行方法 107 | * @return the resp 108 | */ 109 | public Resp> process(String category, I input, Map args, DewInterceptExec fun) { 110 | DewInterceptContext context = new DewInterceptContext<>(); 111 | context.setInput(input); 112 | context.setArgs(args); 113 | LOGGER.debug("[DewInterceptorProcessor] Process [{}]", category); 114 | if (!CONTAINER.containsKey(category)) { 115 | return fun.exec(context); 116 | } 117 | List> interceptors = CONTAINER.get(category); 118 | Resp> beforeR = doProcess(context, interceptors, true); 119 | if (!beforeR.ok()) { 120 | return beforeR; 121 | } 122 | Resp> execR = fun.exec(beforeR.getBody()); 123 | if (!execR.ok()) { 124 | return execR; 125 | } 126 | return doProcess(execR.getBody(), interceptors, false); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/HttpHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.HttpHelper; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.io.File; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | * The type Http helper test. 15 | * 16 | * @author gudaoxuri 17 | */ 18 | public class HttpHelperTest { 19 | 20 | private String currentPath; 21 | 22 | { 23 | currentPath = HttpHelperTest.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 24 | File file = new File(currentPath); 25 | currentPath = file.getPath(); 26 | if (file.isFile()) { 27 | currentPath = file.getParentFile().getPath(); 28 | } 29 | System.out.println("Current Path:" + currentPath); 30 | } 31 | 32 | /** 33 | * Test http. 34 | */ 35 | @Test 36 | public void testHttp() { 37 | // get 38 | String result = $.http.get("https://httpbin.org/get"); 39 | Assertions.assertEquals("httpbin.org", $.json.toJson(result).get("headers").get("Host").asText()); 40 | result = $.http.get("https://httpbin.org/get", new HashMap<>() { 41 | { 42 | put("Customer-A", "AAA"); 43 | put("Accept", "json"); 44 | put("Date", "xx"); 45 | } 46 | }); 47 | Assertions.assertEquals("AAA", $.json.toJson(result).get("headers").get("Customer-A").asText()); 48 | Assertions.assertEquals("json", $.json.toJson(result).get("headers").get("Accept").asText()); 49 | result = $.http.get("https://httpbin.org/get", new HashMap<>() { 50 | { 51 | put("Customer-A", "AAA"); 52 | put("Accept", "json"); 53 | } 54 | }, "application/json; charset=utf-8", "utf-8", 5000); 55 | Assertions.assertEquals("AAA", $.json.toJson(result).get("headers").get("Customer-A").asText()); 56 | Assertions.assertEquals("json", $.json.toJson(result).get("headers").get("Accept").asText()); 57 | Assertions.assertEquals("application/json; charset=utf-8", $.json.toJson(result).get("headers").get("Content-Type").asText()); 58 | // delete 59 | result = $.http.delete("https://httpbin.org/delete"); 60 | Assertions.assertEquals("httpbin.org", $.json.toJson(result).get("headers").get("Host").asText()); 61 | // post - data 62 | result = $.http.post("https://httpbin.org/post", "some data"); 63 | Assertions.assertEquals("some data", $.json.toJson(result).get("data").asText()); 64 | // post - form 65 | result = $.http.post("https://httpbin.org/post", new HashMap<>() { 66 | { 67 | put("a", "1"); 68 | } 69 | }, "application/x-www-form-urlencoded"); 70 | result = $.http.post("https://httpbin.org/post", "custname=%E5%8C%BF%E5%90%8D&size=small&topping=cheese&topping=onion", "application/x-www-form-urlencoded"); 71 | Assertions.assertEquals("匿名", $.json.toJson(result).get("form").get("custname").asText()); 72 | Assertions.assertEquals("small", $.json.toJson(result).get("form").get("size").asText()); 73 | Assertions.assertEquals("onion", $.json.toJson(result).get("form").get("topping").get(1).asText()); 74 | // post - file 75 | result = $.http.post("https://httpbin.org/post", new File(currentPath + "/conf1.json"), "multipart/form-data"); 76 | Assertions.assertEquals("1", $.json.toJson($.json.toJson(result).get("files").get("conf1.json").asText()).get("a").asText()); 77 | result = $.http.post("https://httpbin.org/post", new File(currentPath + "/conf1.json")); 78 | Assertions.assertEquals("1", $.json.toJson(result).get("json").get("a").asText()); 79 | // put - data 80 | result = $.http.put("https://httpbin.org/put", "some data"); 81 | Assertions.assertEquals("some data", $.json.toJson(result).get("data").asText()); 82 | // put - form 83 | result = $.http.put("https://httpbin.org/put", new HashMap<>() { 84 | { 85 | put("a", "1"); 86 | } 87 | }, "application/x-www-form-urlencoded"); 88 | Assertions.assertEquals("1", $.json.toJson(result).get("form").get("a").asText()); 89 | // put - file 90 | result = $.http.put("https://httpbin.org/put", new File(currentPath + "/conf1.json")); 91 | Assertions.assertEquals("1", $.json.toJson(result).get("json").get("a").asText()); 92 | // put with head 93 | HttpHelper.ResponseWrap responseWrap = $.http.putWrap("https://httpbin.org/put", new File(currentPath + "/conf1.json")); 94 | Assertions.assertEquals("1", $.json.toJson(result).get("json").get("a").asText()); 95 | Assertions.assertEquals("application/json", responseWrap.head.get("Content-Type").get(0)); 96 | // head 97 | Map> head = $.http.head("https://httpbin.org/get"); 98 | Assertions.assertEquals("application/json", head.get("Content-Type").get(0)); 99 | // options 100 | head = $.http.options("https://httpbin.org/get"); 101 | Assertions.assertTrue(head.get("Allow").get(0).contains("GET")); 102 | // patch - data 103 | result = $.http.patch("https://httpbin.org/patch", new HashMap<>() { 104 | { 105 | put("Customer-A", "AAA"); 106 | put("Accept", "json"); 107 | } 108 | }); 109 | Assertions.assertEquals("AAA", $.json.toJson($.json.toJson(result).get("data").asText()).get("Customer-A").asText()); 110 | Assertions.assertEquals("json", $.json.toJson($.json.toJson(result).get("data").asText()).get("Accept").asText()); 111 | 112 | result = $.http.post("https://httpbin.org/post", new File(currentPath + "/conf1.json")); 113 | Assertions.assertEquals("1", $.json.toJson(result).get("json").get("a").asText()); 114 | 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /it/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"com.ecfront.dew.common.$", 4 | "allPublicFields":true, 5 | "allPublicMethods":true, 6 | "allPublicConstructors":true 7 | }, 8 | { 9 | "name":"com.ecfront.dew.common.FieldHelper", 10 | "allPublicFields":true, 11 | "allPublicMethods":true, 12 | "allPublicConstructors":true 13 | }, 14 | { 15 | "name":"com.ecfront.dew.common.test.Ext", 16 | "allDeclaredFields":true, 17 | "allDeclaredMethods":true, 18 | "allDeclaredConstructors":true 19 | }, 20 | { 21 | "name":"com.ecfront.dew.common.test.GenericModel", 22 | "allDeclaredFields":true, 23 | "allDeclaredMethods":true, 24 | "allDeclaredConstructors":true 25 | }, 26 | { 27 | "name":"com.ecfront.dew.common.test.HttpHelperTest$5", 28 | "allDeclaredFields":true, 29 | "allDeclaredMethods":true 30 | }, 31 | { 32 | "name":"com.ecfront.dew.common.test.Id", 33 | "allDeclaredFields":true, 34 | "allDeclaredMethods":true 35 | }, 36 | { 37 | "name":"com.ecfront.dew.common.test.JsonHelperTest$1", 38 | "allDeclaredFields":true, 39 | "allDeclaredMethods":true 40 | }, 41 | { 42 | "name":"com.ecfront.dew.common.test.TestIdModel", 43 | "allDeclaredFields":true, 44 | "allDeclaredMethods":true, 45 | "allDeclaredConstructors":true 46 | }, 47 | { 48 | "name":"com.ecfront.dew.common.test.bean.BaseController", 49 | "allDeclaredFields":true, 50 | "allDeclaredMethods":true 51 | }, 52 | { 53 | "name":"com.ecfront.dew.common.test.bean.IdxController", 54 | "allDeclaredFields":true, 55 | "allDeclaredMethods":true 56 | }, 57 | { 58 | "name":"com.ecfront.dew.common.test.bean.User", 59 | "allDeclaredFields":true, 60 | "methods":[ 61 | {"name":"getAge","parameterTypes":[] }, 62 | {"name":"getName","parameterTypes":[] }, 63 | {"name":"getOthers","parameterTypes":[] }, 64 | {"name":"getStatus","parameterTypes":[] }, 65 | {"name":"getWorkAge","parameterTypes":[] }, 66 | {"name":"isEnable","parameterTypes":[] }, 67 | {"name":"setAge","parameterTypes":["int"] }, 68 | {"name":"setEnable","parameterTypes":["boolean"] }, 69 | {"name":"setName","parameterTypes":["java.lang.String"] }, 70 | {"name":"setOthers","parameterTypes":["long"] }, 71 | {"name":"setStatus","parameterTypes":["java.lang.Boolean"] }, 72 | {"name":"setWorkAge","parameterTypes":["java.lang.Integer"] } 73 | ] 74 | }, 75 | { 76 | "name":"com.fasterxml.jackson.core.JsonProcessingException" 77 | }, 78 | { 79 | "name":"com.fasterxml.jackson.databind.deser.Deserializers[]" 80 | }, 81 | { 82 | "name":"com.fasterxml.jackson.databind.deser.KeyDeserializers[]" 83 | }, 84 | { 85 | "name":"com.fasterxml.jackson.databind.deser.ValueInstantiators[]" 86 | }, 87 | { 88 | "name":"com.fasterxml.jackson.databind.ext.Java7HandlersImpl", 89 | "methods":[{"name":"","parameterTypes":[] }] 90 | }, 91 | { 92 | "name":"com.fasterxml.jackson.databind.ext.Java7SupportImpl", 93 | "methods":[{"name":"","parameterTypes":[] }] 94 | }, 95 | { 96 | "name":"com.fasterxml.jackson.databind.ser.Serializers[]" 97 | }, 98 | { 99 | "name":"java.io.File" 100 | }, 101 | { 102 | "name":"java.io.File[]" 103 | }, 104 | { 105 | "name":"java.io.PrintStream" 106 | }, 107 | { 108 | "name":"java.io.Serializable", 109 | "allDeclaredMethods":true 110 | }, 111 | { 112 | "name":"java.lang.Boolean" 113 | }, 114 | { 115 | "name":"java.lang.Boolean[]" 116 | }, 117 | { 118 | "name":"java.lang.Byte[]" 119 | }, 120 | { 121 | "name":"java.lang.Character[]" 122 | }, 123 | { 124 | "name":"java.lang.Class" 125 | }, 126 | { 127 | "name":"java.lang.ClassLoader", 128 | "methods":[{"name":"setDefaultAssertionStatus","parameterTypes":["boolean"] }] 129 | }, 130 | { 131 | "name":"java.lang.Class[]" 132 | }, 133 | { 134 | "name":"java.lang.Cloneable", 135 | "allDeclaredMethods":true 136 | }, 137 | { 138 | "name":"java.lang.Double[]" 139 | }, 140 | { 141 | "name":"java.lang.Float[]" 142 | }, 143 | { 144 | "name":"java.lang.Integer[]" 145 | }, 146 | { 147 | "name":"java.lang.Long[]" 148 | }, 149 | { 150 | "name":"java.lang.Object", 151 | "allDeclaredFields":true, 152 | "allDeclaredMethods":true 153 | }, 154 | { 155 | "name":"java.lang.Short[]" 156 | }, 157 | { 158 | "name":"java.lang.String" 159 | }, 160 | { 161 | "name":"java.lang.String[]" 162 | }, 163 | { 164 | "name":"java.lang.Throwable", 165 | "fields":[{"name":"cause"}], 166 | "methods":[{"name":"initCause","parameterTypes":["java.lang.Throwable"] }] 167 | }, 168 | { 169 | "name":"java.math.BigDecimal[]" 170 | }, 171 | { 172 | "name":"java.math.BigInteger[]" 173 | }, 174 | { 175 | "name":"java.net.URL[]" 176 | }, 177 | { 178 | "name":"java.sql.Date[]" 179 | }, 180 | { 181 | "name":"java.sql.Time[]" 182 | }, 183 | { 184 | "name":"java.sql.Timestamp[]" 185 | }, 186 | { 187 | "name":"java.util.AbstractMap", 188 | "allDeclaredFields":true, 189 | "allDeclaredMethods":true 190 | }, 191 | { 192 | "name":"java.util.Calendar[]" 193 | }, 194 | { 195 | "name":"java.util.Date[]" 196 | }, 197 | { 198 | "name":"java.util.HashMap", 199 | "allDeclaredFields":true, 200 | "allDeclaredMethods":true 201 | }, 202 | { 203 | "name":"java.util.HashSet", 204 | "allDeclaredMethods":true, 205 | "allDeclaredConstructors":true 206 | }, 207 | { 208 | "name":"java.util.List" 209 | }, 210 | { 211 | "name":"java.util.Map", 212 | "allDeclaredMethods":true 213 | }, 214 | { 215 | "name":"java.util.Properties" 216 | }, 217 | { 218 | "name":"org.apache.commons.beanutils.BeanUtilsBean" 219 | }, 220 | { 221 | "name":"org.apache.commons.logging.LogFactory" 222 | }, 223 | { 224 | "name":"org.apache.commons.logging.impl.Jdk14Logger", 225 | "methods":[{"name":"","parameterTypes":["java.lang.String"] }] 226 | }, 227 | { 228 | "name":"org.apache.commons.logging.impl.Log4JLogger" 229 | }, 230 | { 231 | "name":"org.apache.commons.logging.impl.LogFactoryImpl", 232 | "methods":[{"name":"","parameterTypes":[] }] 233 | }, 234 | { 235 | "name":"org.apache.commons.logging.impl.WeakHashtable", 236 | "methods":[{"name":"","parameterTypes":[] }] 237 | }, 238 | { 239 | "name":"org.junit.runner.RunWith" 240 | } 241 | ] 242 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/FieldHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.inner.IdcardUtils; 4 | 5 | import java.util.UUID; 6 | import java.util.regex.Pattern; 7 | 8 | /** 9 | * 常用字段操作. 10 | * 11 | * @author gudaoxuri 12 | */ 13 | public class FieldHelper { 14 | 15 | private static final Pattern EMAIL_ADDRESS_PATTERN = 16 | Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]*[A-Z0-9]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); 17 | 18 | private static final Pattern MOBILE_PATTERN = 19 | Pattern.compile("^[1](([3][0-9])|([4][5-9])|([5][0-3,5-9])|([6][5,6])|([7][0-8])|([8][0-9])|([9][1,8,9]))[0-9]{8}$"); 20 | 21 | private static final Pattern CHINESE_PATTERN = 22 | Pattern.compile("^[\u4e00-\u9fa5]+$"); 23 | 24 | private static final Pattern IPV4_PATTERN = 25 | Pattern.compile( 26 | "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"); 27 | 28 | private static final Pattern IPV6_STD_PATTERN = 29 | Pattern.compile( 30 | "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"); 31 | 32 | private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = 33 | Pattern.compile( 34 | "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); 35 | private static final String[] CHARS = {"a", "b", "c", "d", "e", "f", 36 | "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", 37 | "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", 38 | "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", 39 | "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", 40 | "W", "X", "Y", "Z"}; 41 | 42 | FieldHelper() { 43 | } 44 | 45 | /** 46 | * 验证邮箱格式是否合法. 47 | * 48 | * @param email 邮件 49 | * @return 邮箱是否合法 50 | */ 51 | public boolean validateEmail(String email) { 52 | return EMAIL_ADDRESS_PATTERN.matcher(email).matches(); 53 | } 54 | 55 | /** 56 | * 验证手机号格式是否合法. 57 | * 58 | * @param mobile 手机号 59 | * @return 手机号是否合法 60 | */ 61 | public boolean validateMobile(String mobile) { 62 | return MOBILE_PATTERN.matcher(mobile).matches(); 63 | } 64 | 65 | /** 66 | * 验证身份证是否合法. 67 | * 68 | * @param idNumber 身份编号 69 | * @return 身份证号验证是否通过 70 | */ 71 | public boolean validateIdNumber(String idNumber) { 72 | return IdcardUtils.validateCard(idNumber); 73 | } 74 | 75 | /** 76 | * 验证是否是IPv4. 77 | * 78 | * @param str 待校验字符串 79 | * @return 是否是IPv4 80 | */ 81 | public boolean isIPv4Address(String str) { 82 | return IPV4_PATTERN.matcher(str).matches(); 83 | } 84 | 85 | /** 86 | * 验证是否是IPv6. 87 | * 88 | * @param str 待校验字符串 89 | * @return 是否是IPv6 90 | */ 91 | public boolean isIPv6Address(String str) { 92 | return isIPv6StdAddress(str) || isIPv6HexCompressedAddress(str); 93 | } 94 | 95 | private boolean isIPv6StdAddress(String str) { 96 | return IPV6_STD_PATTERN.matcher(str).matches(); 97 | } 98 | 99 | private boolean isIPv6HexCompressedAddress(String str) { 100 | return IPV6_HEX_COMPRESSED_PATTERN.matcher(str).matches(); 101 | } 102 | 103 | /** 104 | * 是否是汉字. 105 | * 106 | * @param str 待校验字符串 107 | * @return 是否是汉字 108 | */ 109 | public boolean isChinese(String str) { 110 | return CHINESE_PATTERN.matcher(str).matches(); 111 | } 112 | 113 | /** 114 | * 根据身份编号获取年龄. 115 | * 116 | * @param idNumber 身份编号 117 | * @return 年龄 118 | */ 119 | public int getAgeByIdCard(String idNumber) { 120 | return IdcardUtils.getAgeByIdCard(idNumber); 121 | } 122 | 123 | /** 124 | * 根据身份编号获取生日. 125 | * 126 | * @param idNumber 身份编号 127 | * @return 生日(yyyyMMdd) 128 | */ 129 | public String getBirthByIdCard(String idNumber) { 130 | return IdcardUtils.getBirthByIdCard(idNumber); 131 | } 132 | 133 | /** 134 | * 根据身份编号获取生日年. 135 | * 136 | * @param idNumber 身份编号 137 | * @return 生日(yyyy) 138 | */ 139 | public Short getYearByIdCard(String idNumber) { 140 | return IdcardUtils.getYearByIdCard(idNumber); 141 | } 142 | 143 | /** 144 | * 根据身份编号获取生日月. 145 | * 146 | * @param idNumber 身份编号 147 | * @return 生日(MM) 148 | */ 149 | public Short getMonthByIdCard(String idNumber) { 150 | return IdcardUtils.getMonthByIdCard(idNumber); 151 | } 152 | 153 | /** 154 | * 根据身份编号获取生日天. 155 | * 156 | * @param idNumber 身份编号 157 | * @return 生日(dd) 158 | */ 159 | public Short getDateByIdCard(String idNumber) { 160 | return IdcardUtils.getDateByIdCard(idNumber); 161 | } 162 | 163 | /** 164 | * 根据身份编号获取性别. 165 | * 166 | * @param idNumber 身份编号 167 | * @return 性别(M - 男 , F - 女 , N - 未知) 168 | */ 169 | public String getGenderByIdCard(String idNumber) { 170 | return IdcardUtils.getGenderByIdCard(idNumber); 171 | } 172 | 173 | /** 174 | * 根据身份编号获取户籍省份. 175 | * 176 | * @param idNumber 身份编码 177 | * @return 省级编码 178 | */ 179 | public String getProvinceByIdCard(String idNumber) { 180 | return IdcardUtils.getProvinceByIdCard(idNumber); 181 | } 182 | 183 | /** 184 | * 获取UUID. 185 | * 186 | * @return UUID 187 | */ 188 | public String createUUID() { 189 | return UUID.randomUUID().toString().replace("-", ""); 190 | } 191 | 192 | /** 193 | * 获取短UUID. 194 | * 195 | * @return 短UUID 196 | */ 197 | public String createShortUUID() { 198 | StringBuilder shortBuffer = new StringBuilder(); 199 | String uuid = createUUID(); 200 | for (int i = 0; i < 8; i++) { 201 | String str = uuid.substring(i << 2, (i << 2) + 4); 202 | int x = Integer.parseInt(str, 16); 203 | shortBuffer.append(CHARS[x % 0x3E]); 204 | } 205 | return shortBuffer.toString(); 206 | } 207 | 208 | } 209 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/BeanHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.BeanHelper; 5 | import com.ecfront.dew.common.test.bean.IdxController; 6 | import com.ecfront.dew.common.test.bean.TestAnnotation; 7 | import com.ecfront.dew.common.test.bean.User; 8 | import org.junit.jupiter.api.Assertions; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.lang.reflect.Method; 12 | import java.util.HashSet; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.Objects; 16 | 17 | /** 18 | * The type Bean helper test. 19 | * 20 | * @author gudaoxuri 21 | */ 22 | public class BeanHelperTest { 23 | 24 | /** 25 | * Copy properties. 26 | */ 27 | @Test 28 | public void copyProperties() { 29 | User ori = new User(); 30 | ori.setName("张三"); 31 | User dest = new User(); 32 | dest.setAge(11); 33 | dest.setWorkAge(11); 34 | $.bean.copyProperties(dest, ori); 35 | Assertions.assertTrue(Objects.equals(dest.getName(), "张三") && dest.getAge() == 0 && dest.getWorkAge() == 11); 36 | } 37 | 38 | /** 39 | * Find class annotation. 40 | */ 41 | @Test 42 | public void findClassAnnotation() { 43 | TestAnnotation.RPC ann = $.bean.getClassAnnotation(IdxController.class, TestAnnotation.RPC.class); 44 | Assertions.assertEquals("/idx/", ann.path()); 45 | } 46 | 47 | /** 48 | * Find field info. 49 | */ 50 | @Test 51 | public void findFieldInfo() { 52 | Map fieldsInfo = $.bean.findFieldsInfo(IdxController.class, null, null, null, null); 53 | Assertions.assertEquals(2, fieldsInfo.size()); 54 | fieldsInfo = $.bean.findFieldsInfo(IdxController.class, null, new HashSet<>() { 55 | { 56 | add(Deprecated.class); 57 | } 58 | }, null, null); 59 | Assertions.assertEquals(1, fieldsInfo.size()); 60 | fieldsInfo = $.bean.findFieldsInfo(IdxController.class, new HashSet<>() { 61 | { 62 | add("parentField"); 63 | } 64 | }, new HashSet<>() { 65 | { 66 | add(Deprecated.class); 67 | } 68 | }, null, null); 69 | Assertions.assertEquals(0, fieldsInfo.size()); 70 | fieldsInfo = $.bean.findFieldsInfo(IdxController.class, null, null, null, new HashSet<>() { 71 | { 72 | add(Deprecated.class); 73 | } 74 | }); 75 | Assertions.assertEquals(1, fieldsInfo.size()); 76 | fieldsInfo = $.bean.findFieldsInfo(IdxController.class, null, null, new HashSet<>() { 77 | { 78 | add("parentField"); 79 | } 80 | }, new HashSet<>() { 81 | { 82 | add(TestAnnotation.RPC.class); 83 | } 84 | }); 85 | Assertions.assertEquals(1, fieldsInfo.size()); 86 | } 87 | 88 | /** 89 | * Find method info. 90 | */ 91 | @Test 92 | public void findMethodInfo() { 93 | List methodsInfo = $.bean.findMethodsInfo(IdxController.class, null, null, null, null); 94 | Assertions.assertEquals(methodsInfo.size(), 7); 95 | methodsInfo = $.bean.findMethodsInfo(IdxController.class, null, new HashSet<>() { 96 | { 97 | add(TestAnnotation.GET.class); 98 | } 99 | }, null, null); 100 | Assertions.assertEquals(methodsInfo.size(), 6); 101 | methodsInfo = $.bean.findMethodsInfo(IdxController.class, new HashSet<>() { 102 | { 103 | add("find"); 104 | } 105 | }, new HashSet<>() { 106 | { 107 | add(TestAnnotation.GET.class); 108 | } 109 | }, null, null); 110 | Assertions.assertEquals(methodsInfo.size(), 4); 111 | methodsInfo = $.bean.findMethodsInfo(IdxController.class, null, null, null, new HashSet<>() { 112 | { 113 | add(TestAnnotation.POST.class); 114 | } 115 | }); 116 | Assertions.assertEquals(methodsInfo.size(), 3); 117 | methodsInfo = $.bean.findMethodsInfo(IdxController.class, null, null, new HashSet<>() { 118 | { 119 | add("childFind"); 120 | } 121 | }, new HashSet<>() { 122 | { 123 | add(TestAnnotation.POST.class); 124 | } 125 | }); 126 | Assertions.assertEquals(methodsInfo.size(), 1); 127 | } 128 | 129 | /** 130 | * Parse rel field and method. 131 | */ 132 | @Test 133 | public void parseRelFieldAndMethod() { 134 | Map rel = $.bean.parseRelFieldAndMethod(User.class, null, null, null, null); 135 | Assertions.assertEquals(6, rel.size()); 136 | Assertions.assertEquals(2, rel.get("enable").length); 137 | } 138 | 139 | /** 140 | * Find values by rel. 141 | */ 142 | @Test 143 | public void findValuesByRel() { 144 | User user = new User(); 145 | user.setName("张三"); 146 | Map values = $.bean.findValuesByRel(user, $.bean.parseRelFieldAndMethod(User.class, null, null, null, null)); 147 | Assertions.assertEquals("张三", values.get("name")); 148 | } 149 | 150 | /** 151 | * Find values. 152 | */ 153 | @Test 154 | public void findValues() { 155 | User user = new User(); 156 | user.setName("张三"); 157 | Map values = $.bean.findValues(user, null, null, null, null); 158 | Assertions.assertEquals("张三", values.get("name")); 159 | } 160 | 161 | /** 162 | * Gets value. 163 | */ 164 | @Test 165 | public void getValue() { 166 | User user = new User(); 167 | user.setName("张三"); 168 | Assertions.assertEquals("张三", $.bean.getValue(user, "name")); 169 | user.setName("李四"); 170 | Assertions.assertEquals("李四", $.bean.getValue(user, "name")); 171 | } 172 | 173 | /** 174 | * Sets value. 175 | */ 176 | @Test 177 | public void setValue() { 178 | User user = new User(); 179 | $.bean.setValue(user, "name", "李四"); 180 | $.bean.setValue(user, "name", "张三"); 181 | Assertions.assertEquals("张三", user.getName()); 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/com.ecfront.dew/common/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"[B" 4 | }, 5 | { 6 | "name":"[C" 7 | }, 8 | { 9 | "name":"[D" 10 | }, 11 | { 12 | "name":"[F" 13 | }, 14 | { 15 | "name":"[I" 16 | }, 17 | { 18 | "name":"[J" 19 | }, 20 | { 21 | "name":"[Lcom.fasterxml.jackson.databind.deser.Deserializers;" 22 | }, 23 | { 24 | "name":"[Lcom.fasterxml.jackson.databind.deser.KeyDeserializers;" 25 | }, 26 | { 27 | "name":"[Lcom.fasterxml.jackson.databind.deser.ValueInstantiators;" 28 | }, 29 | { 30 | "name":"[Lcom.fasterxml.jackson.databind.ser.Serializers;" 31 | }, 32 | { 33 | "name":"[Ljava.io.File;" 34 | }, 35 | { 36 | "name":"[Ljava.lang.Boolean;" 37 | }, 38 | { 39 | "name":"[Ljava.lang.Byte;" 40 | }, 41 | { 42 | "name":"[Ljava.lang.Character;" 43 | }, 44 | { 45 | "name":"[Ljava.lang.Class;" 46 | }, 47 | { 48 | "name":"[Ljava.lang.Double;" 49 | }, 50 | { 51 | "name":"[Ljava.lang.Float;" 52 | }, 53 | { 54 | "name":"[Ljava.lang.Integer;" 55 | }, 56 | { 57 | "name":"[Ljava.lang.Long;" 58 | }, 59 | { 60 | "name":"[Ljava.lang.Short;" 61 | }, 62 | { 63 | "name":"[Ljava.lang.String;" 64 | }, 65 | { 66 | "name":"[Ljava.math.BigDecimal;" 67 | }, 68 | { 69 | "name":"[Ljava.math.BigInteger;" 70 | }, 71 | { 72 | "name":"[Ljava.net.URL;" 73 | }, 74 | { 75 | "name":"[Ljava.sql.Date;" 76 | }, 77 | { 78 | "name":"[Ljava.sql.Time;" 79 | }, 80 | { 81 | "name":"[Ljava.sql.Timestamp;" 82 | }, 83 | { 84 | "name":"[Ljava.util.Calendar;" 85 | }, 86 | { 87 | "name":"[Ljava.util.Date;" 88 | }, 89 | { 90 | "name":"[Ljava.util.HashMap$Node;" 91 | }, 92 | { 93 | "name":"[S" 94 | }, 95 | { 96 | "name":"[Z" 97 | }, 98 | { 99 | "name":"com.fasterxml.jackson.core.JsonProcessingException" 100 | }, 101 | { 102 | "name":"com.fasterxml.jackson.databind.ext.Java7SupportImpl", 103 | "methods":[{"name":"","parameterTypes":[] }] 104 | }, 105 | { 106 | "name":"com.sun.crypto.provider.AESCipher$General", 107 | "methods":[{"name":"","parameterTypes":[] }] 108 | }, 109 | { 110 | "name":"com.sun.crypto.provider.ARCFOURCipher", 111 | "methods":[{"name":"","parameterTypes":[] }] 112 | }, 113 | { 114 | "name":"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", 115 | "methods":[{"name":"","parameterTypes":[] }] 116 | }, 117 | { 118 | "name":"com.sun.crypto.provider.DESCipher", 119 | "methods":[{"name":"","parameterTypes":[] }] 120 | }, 121 | { 122 | "name":"com.sun.crypto.provider.DESedeCipher", 123 | "methods":[{"name":"","parameterTypes":[] }] 124 | }, 125 | { 126 | "name":"com.sun.crypto.provider.DHParameters", 127 | "methods":[{"name":"","parameterTypes":[] }] 128 | }, 129 | { 130 | "name":"com.sun.crypto.provider.GaloisCounterMode$AESGCM", 131 | "methods":[{"name":"","parameterTypes":[] }] 132 | }, 133 | { 134 | "name":"com.sun.crypto.provider.TlsKeyMaterialGenerator", 135 | "methods":[{"name":"","parameterTypes":[] }] 136 | }, 137 | { 138 | "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", 139 | "methods":[{"name":"","parameterTypes":[] }] 140 | }, 141 | { 142 | "name":"com.sun.crypto.provider.TlsPrfGenerator$V12", 143 | "methods":[{"name":"","parameterTypes":[] }] 144 | }, 145 | { 146 | "name":"java.io.File" 147 | }, 148 | { 149 | "name":"java.io.PrintStream" 150 | }, 151 | { 152 | "name":"java.io.Serializable", 153 | "queryAllDeclaredMethods":true 154 | }, 155 | { 156 | "name":"java.lang.Boolean" 157 | }, 158 | { 159 | "name":"java.lang.Class" 160 | }, 161 | { 162 | "name":"java.lang.ClassLoader", 163 | "methods":[{"name":"setDefaultAssertionStatus","parameterTypes":["boolean"] }] 164 | }, 165 | { 166 | "name":"java.lang.Cloneable", 167 | "queryAllDeclaredMethods":true 168 | }, 169 | { 170 | "name":"java.lang.Object" 171 | }, 172 | { 173 | "name":"java.lang.String" 174 | }, 175 | { 176 | "name":"java.lang.Thread", 177 | "fields":[{"name":"threadLocalRandomProbe"}] 178 | }, 179 | { 180 | "name":"java.lang.Throwable", 181 | "methods":[{"name":"initCause","parameterTypes":["java.lang.Throwable"] }] 182 | }, 183 | { 184 | "name":"java.lang.reflect.Field", 185 | "fields":[{"name":"modifiers"}] 186 | }, 187 | { 188 | "name":"java.security.AlgorithmParametersSpi" 189 | }, 190 | { 191 | "name":"java.security.SecureRandomParameters" 192 | }, 193 | { 194 | "name":"java.security.interfaces.ECPrivateKey" 195 | }, 196 | { 197 | "name":"java.security.interfaces.ECPublicKey" 198 | }, 199 | { 200 | "name":"java.security.interfaces.RSAPrivateKey" 201 | }, 202 | { 203 | "name":"java.security.interfaces.RSAPublicKey" 204 | }, 205 | { 206 | "name":"java.util.AbstractMap", 207 | "allDeclaredFields":true, 208 | "queryAllDeclaredMethods":true 209 | }, 210 | { 211 | "name":"java.util.HashMap", 212 | "allDeclaredFields":true, 213 | "queryAllDeclaredMethods":true 214 | }, 215 | { 216 | "name":"java.util.List" 217 | }, 218 | { 219 | "name":"java.util.Map", 220 | "queryAllDeclaredMethods":true 221 | }, 222 | { 223 | "name":"java.util.Properties" 224 | }, 225 | { 226 | "name":"java.util.concurrent.ForkJoinTask", 227 | "fields":[{"name":"aux"}, {"name":"status"}] 228 | }, 229 | { 230 | "name":"java.util.concurrent.atomic.AtomicBoolean", 231 | "fields":[{"name":"value"}] 232 | }, 233 | { 234 | "name":"java.util.concurrent.atomic.AtomicReference", 235 | "fields":[{"name":"value"}] 236 | }, 237 | { 238 | "name":"java.util.concurrent.atomic.Striped64", 239 | "fields":[{"name":"base"}, {"name":"cellsBusy"}] 240 | }, 241 | { 242 | "name":"javax.security.auth.x500.X500Principal", 243 | "fields":[{"name":"thisX500Name"}], 244 | "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] 245 | }, 246 | { 247 | "name":"jdk.internal.misc.Unsafe" 248 | }, 249 | { 250 | "name":"jdk.internal.net.http.common.Utils", 251 | "fields":[{"name":"DISALLOWED_HEADERS_SET"}] 252 | }, 253 | { 254 | "name":"org.apache.commons.beanutils.BeanUtilsBean" 255 | }, 256 | { 257 | "name":"org.apache.commons.logging.LogFactory" 258 | }, 259 | { 260 | "name":"org.apache.commons.logging.impl.Jdk14Logger", 261 | "methods":[{"name":"","parameterTypes":["java.lang.String"] }, {"name":"setLogFactory","parameterTypes":["org.apache.commons.logging.LogFactory"] }] 262 | }, 263 | { 264 | "name":"org.apache.commons.logging.impl.Log4JLogger" 265 | }, 266 | { 267 | "name":"org.apache.commons.logging.impl.LogFactoryImpl", 268 | "methods":[{"name":"","parameterTypes":[] }] 269 | }, 270 | { 271 | "name":"org.apache.commons.logging.impl.WeakHashtable", 272 | "methods":[{"name":"","parameterTypes":[] }] 273 | } 274 | ] 275 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/ClassScanHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | 4 | import com.ecfront.dew.common.exception.RTException; 5 | import com.ecfront.dew.common.exception.RTIOException; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.lang.annotation.Annotation; 10 | import java.net.JarURLConnection; 11 | import java.net.URL; 12 | import java.net.URLDecoder; 13 | import java.nio.charset.StandardCharsets; 14 | import java.util.Enumeration; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | import java.util.jar.JarEntry; 18 | import java.util.jar.JarFile; 19 | import java.util.regex.Pattern; 20 | 21 | /** 22 | * Java Class扫描操作. 23 | * 24 | * @author gudaoxuri 25 | */ 26 | public class ClassScanHelper { 27 | 28 | /** 29 | * Instantiates a new Class scan helper. 30 | */ 31 | ClassScanHelper() { 32 | } 33 | 34 | private static Set> findAndAddClassesByFile(String currentPackage, File currentFile, 35 | Set> annotations, Set classNames) { 36 | Set> result = new HashSet<>(); 37 | if (currentFile.exists() && currentFile.isDirectory()) { 38 | File[] files = currentFile.listFiles(file -> file.isDirectory() || file.getName().endsWith(".class")); 39 | for (File file : files) { 40 | if (file.isDirectory()) { 41 | result.addAll(findAndAddClassesByFile(currentPackage + "." + file.getName(), file, annotations, classNames)); 42 | } else { 43 | String className = file.getName().substring(0, file.getName().length() - 6); 44 | try { 45 | Class clazz = Thread.currentThread().getContextClassLoader().loadClass(currentPackage + '.' + className); 46 | if (isMatch(clazz, annotations, classNames)) { 47 | result.add(clazz); 48 | } 49 | } catch (Throwable e) { 50 | // Ignore NoClassDefFoundError when class extends/implements some not import class. 51 | } 52 | } 53 | } 54 | } 55 | return result; 56 | } 57 | 58 | private static Set> findAndAddClassesByJar(JarFile jar, String currentPath, 59 | Set> annotations, Set classNames) { 60 | Set> result = new HashSet<>(); 61 | Enumeration entries = jar.entries(); 62 | JarEntry jarEntry; 63 | String jarName; 64 | while (entries.hasMoreElements()) { 65 | jarEntry = entries.nextElement(); 66 | jarName = jarEntry.getName(); 67 | if (jarName.charAt(0) == '/') { 68 | jarName = jarName.substring(1); 69 | } 70 | if (jarName.startsWith(currentPath)) { 71 | int idx = jarName.lastIndexOf('/'); 72 | if (jarName.endsWith(".class") 73 | && !jarEntry.isDirectory()) { 74 | String className = jarName.substring(jarName.lastIndexOf('/') + 1, 75 | jarName.length() - 6); 76 | try { 77 | Class clazz = Class.forName(jarName.substring(0, idx).replace('/', '.') + '.' + className); 78 | if (isMatch(clazz, annotations, classNames)) { 79 | result.add(clazz); 80 | } 81 | } catch (Throwable e) { 82 | // Ignore NoClassDefFoundError when class extends/implements some not import class. 83 | } 84 | } 85 | } 86 | } 87 | return result; 88 | } 89 | 90 | private static boolean isMatch(Class clazz, Set> annotations, Set classNames) { 91 | return matchAnnotation(clazz, annotations) && matchClassName(clazz, classNames); 92 | } 93 | 94 | private static boolean matchAnnotation(Class clazz, Set> annotations) { 95 | if (annotations == null || annotations.isEmpty()) { 96 | return true; 97 | } 98 | for (Class annotation : annotations) { 99 | if (clazz.isAnnotationPresent(annotation)) { 100 | return true; 101 | } 102 | } 103 | return false; 104 | } 105 | 106 | private static boolean matchClassName(Class clazz, Set classNames) { 107 | if (classNames == null || classNames.isEmpty()) { 108 | return true; 109 | } 110 | for (String className : classNames) { 111 | if (Pattern.compile(className) 112 | .matcher(clazz.getSimpleName()).find()) { 113 | return true; 114 | } 115 | } 116 | return false; 117 | } 118 | 119 | /** 120 | * 扫描获取指定包下符合条件的class类. 121 | *

122 | * IMPORTANT: 此方法不支持 Native Image https://github.com/oracle/graal/issues/1108 123 | * 124 | * @param basePackage 要扫描的根包名 125 | * @param includeAnnotations 要包含的注解,默认为全部 126 | * @param includeNames 要包含的class名称(支持正则),默认为全部 127 | * @return 符合条件的class类集合 set 128 | */ 129 | public Set> scan(String basePackage, 130 | Set> includeAnnotations, Set includeNames) throws RTIOException { 131 | Set> result = new HashSet<>(); 132 | String packageDir = basePackage.replace('.', '/'); 133 | try { 134 | Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packageDir); 135 | while (urls.hasMoreElements()) { 136 | URL url = urls.nextElement(); 137 | switch (url.getProtocol()) { 138 | case "file": 139 | result.addAll( 140 | findAndAddClassesByFile( 141 | basePackage, new File(URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8)), 142 | includeAnnotations, includeNames) 143 | ); 144 | break; 145 | case "jar": 146 | result.addAll( 147 | findAndAddClassesByJar( 148 | ((JarURLConnection) url.openConnection()).getJarFile(), 149 | packageDir, includeAnnotations, includeNames) 150 | ); 151 | break; 152 | default: 153 | break; 154 | } 155 | } 156 | } catch (IOException e) { 157 | throw new RTException(e); 158 | } 159 | return result; 160 | } 161 | 162 | } 163 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/JsonHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.fasterxml.jackson.core.JsonParser; 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import java.text.SimpleDateFormat; 10 | import java.time.LocalDate; 11 | import java.time.LocalDateTime; 12 | import java.time.LocalTime; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.Optional; 16 | 17 | /** 18 | * The type Json helper test. 19 | * 20 | * @author gudaoxuri 21 | */ 22 | public class JsonHelperTest { 23 | 24 | private static final SimpleDateFormat DF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 25 | 26 | /** 27 | * Test path. 28 | */ 29 | @Test 30 | public void testPath() { 31 | JsonNode jsonNode = $.json.toJson("{'a_key':'a_val','child':{'c_key':'c_val'}}"); 32 | Assertions.assertEquals("a_val", $.json.path(jsonNode, "a_key").asText()); 33 | Assertions.assertEquals("c_val", $.json.path(jsonNode, "child.c_key").asText()); 34 | } 35 | 36 | /** 37 | * To json string. 38 | */ 39 | @Test 40 | public void toJsonString() { 41 | Assertions.assertEquals("{\"\":{\"a_key\":\"a_val\"}}", 42 | $.json.toJsonString($.json.createObjectNode().set("", $.json.createObjectNode().put("a_key", "a_val")))); 43 | } 44 | 45 | /** 46 | * To json. 47 | */ 48 | @Test 49 | public void toJson() { 50 | Assertions.assertEquals("a_val", $.json.toJson("{'a_key':'a_val'}").get("a_key").asText()); 51 | Assertions.assertEquals("a_val", $.json.toJson("{\r\n'a_key':'a_val' // 注释\r\n}").get("a_key").asText()); 52 | } 53 | 54 | /** 55 | * To list. 56 | */ 57 | @Test 58 | public void toList() { 59 | TestIdModel model = 60 | $.json.toList("[{'name':'sunisle','createTime':123456789,'cid':'1','date':'2016-07-12 12:00:00'}]", TestIdModel.class).get(0); 61 | Assertions.assertEquals("sunisle", model.getName()); 62 | Assertions.assertEquals("1", model.getCid()); 63 | Assertions.assertEquals("123456789", model.getCreateTime()); 64 | Assertions.assertEquals("2016-07-12 12:00:00", DF.format(model.getDate())); 65 | } 66 | 67 | /** 68 | * To set. 69 | */ 70 | @Test 71 | public void toSet() { 72 | TestIdModel model = 73 | $.json.toSet("[{'name':'sunisle','createTime':123456789,'cid':'1','date':'2016-07-12 12:00:00'}]", TestIdModel.class) 74 | .iterator().next(); 75 | Assertions.assertEquals("sunisle", model.getName()); 76 | Assertions.assertEquals("1", model.getCid()); 77 | Assertions.assertEquals("123456789", model.getCreateTime()); 78 | Assertions.assertEquals("2016-07-12 12:00:00", DF.format(model.getDate())); 79 | } 80 | 81 | /** 82 | * To map. 83 | */ 84 | @Test 85 | public void toMap() { 86 | Map model = 87 | $.json.toMap("{'sunisle':{'name':'sunisle','createTime':123456789,'cid':'1','date':'2016-07-12 12:00:00'}}", 88 | String.class, TestIdModel.class); 89 | Assertions.assertEquals("sunisle", model.keySet().iterator().next()); 90 | TestIdModel val = model.get("sunisle"); 91 | Assertions.assertEquals("1", val.getCid()); 92 | Assertions.assertEquals("123456789", val.getCreateTime()); 93 | Assertions.assertEquals("2016-07-12 12:00:00", DF.format(val.getDate())); 94 | } 95 | 96 | /** 97 | * To object. 98 | */ 99 | @Test 100 | public void toObject() { 101 | TestIdModel model = $.json.toObject("{'name':'sunisle','createTime':123456789,'cid':'1','date':'2016-07-12 12:00:00'}", TestIdModel.class); 102 | Assertions.assertEquals("sunisle", model.getName()); 103 | Assertions.assertEquals("1", model.getCid()); 104 | Assertions.assertEquals("123456789", model.getCreateTime()); 105 | Assertions.assertEquals("2016-07-12 12:00:00", DF.format(model.getDate())); 106 | } 107 | 108 | /** 109 | * To generic object. 110 | */ 111 | @Test 112 | public void toGenericObject() { 113 | GenericModel model = 114 | $.json.toObject( 115 | "{'strs':['sunisle'],'exts':[{'createTime':'123456789','cid':'1'}],'extMap':{'a':{'createTime':'123456789','cid':'1'}}}", 116 | GenericModel.class); 117 | Assertions.assertEquals("sunisle", model.getStrs().get(0)); 118 | Assertions.assertEquals("1", model.getExts().get(0).getCid()); 119 | Assertions.assertEquals("123456789", model.getExts().get(0).getCreateTime()); 120 | Assertions.assertEquals("1", model.getExtMap().get("a").getCid()); 121 | Assertions.assertEquals("123456789", model.getExtMap().get("a").getCreateTime()); 122 | } 123 | 124 | /** 125 | * Test local date time. 126 | */ 127 | @Test 128 | public void testLocalDateTime() { 129 | TestIdModel model = new TestIdModel(); 130 | model.setLocalDateTime(LocalDateTime.now()); 131 | model.setLocalDate(LocalDate.now()); 132 | model.setLocalTime(LocalTime.now()); 133 | TestIdModel model2 = $.json.toObject($.json.toJsonString(model), TestIdModel.class); 134 | Assertions.assertTrue(model.getLocalDateTime().isEqual(model2.getLocalDateTime())); 135 | Assertions.assertTrue(model.getLocalDate().isEqual(model2.getLocalDate())); 136 | Assertions.assertEquals(model.getLocalTime().toString(), model2.getLocalTime().toString()); 137 | } 138 | 139 | /** 140 | * Test optional. 141 | */ 142 | @Test 143 | public void testOptional() { 144 | TestIdModel model = new TestIdModel(); 145 | TestIdModel model2 = $.json.toObject($.json.toJsonString(model), TestIdModel.class); 146 | Assertions.assertFalse(model2.getOpt().isPresent()); 147 | 148 | model = new TestIdModel(); 149 | model.setOpt(Optional.empty()); 150 | model2 = $.json.toObject($.json.toJsonString(model), TestIdModel.class); 151 | Assertions.assertFalse(model2.getOpt().isPresent()); 152 | 153 | model = new TestIdModel(); 154 | model.setOpt(Optional.of(new HashMap<>() { 155 | { 156 | put("h", "001"); 157 | } 158 | })); 159 | model2 = $.json.toObject($.json.toJsonString(model), TestIdModel.class); 160 | Assertions.assertEquals("001", model2.getOpt().get().get("h")); 161 | } 162 | 163 | /** 164 | * Custom mapper. 165 | */ 166 | @Test 167 | public void customMapper() { 168 | // Normal operation 169 | Assertions.assertEquals("1", $.json.toJson("{'a':'1'}").get("a").asText()); 170 | // Custom Mapper operation 171 | $.json("otherInst").getMapper().configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, false); 172 | try { 173 | $.json("otherInst").toJson("{'a':'1'}"); 174 | Assertions.fail(); 175 | } catch (RuntimeException e) { 176 | Assertions.assertTrue(e.getMessage().contains("com.fasterxml.jackson.core.JsonParseException: Unexpected character")); 177 | } 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/test/java/com/ecfront/dew/common/test/SecurityHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common.test; 2 | 3 | import com.ecfront.dew.common.$; 4 | import com.ecfront.dew.common.exception.RTException; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.nio.charset.StandardCharsets; 9 | import java.security.PrivateKey; 10 | import java.security.PublicKey; 11 | 12 | /** 13 | * The type Security helper test. 14 | * 15 | * @author gudaoxuri 16 | */ 17 | public class SecurityHelperTest { 18 | 19 | /** 20 | * Digest. 21 | */ 22 | @Test 23 | public void digest() { 24 | Assertions.assertEquals("70c0cc2b7bf8a8ebcd7b59c49ddda9a1e551122ba5d7ab3b7b02141d4ce4c626".toLowerCase(), 25 | $.security.digest.digest("gudaoxuri", "SHA-256")); 26 | Assertions.assertEquals("7d9def92860187bf1150ebb6ec342becb50bc5d5".toLowerCase(), 27 | $.security.digest.digest("gudaoxuri", "SHA1")); 28 | Assertions.assertEquals(("e2806245bd7235d0a8b76ca489d2984aabc5a71a9b1d39abfd6bf24980cd808333f15788c0ef9a1e0c8" 29 | + "afcec7a427f74a6f39da47d282810028d113a0ea5b11a").toLowerCase(), 30 | $.security.digest.digest("gudaoxuri", "SHA-512")); 31 | Assertions.assertEquals("0ef841c028908fca6e78c51490e4a0cf".toLowerCase(), 32 | $.security.digest.digest("gudaoxuri", "MD5")); 33 | 34 | Assertions.assertEquals("300ef751875b206d9001a1fc5695ef4403e249ae".toLowerCase(), 35 | $.security.digest.digest("gudaoxuri", "test", "HmacSHA1")); 36 | Assertions.assertEquals("5a6d9c078d427b752754a731016a3f0c5753a2117bd274712d31c9990477d35f".toLowerCase(), 37 | $.security.digest.digest("gudaoxuri", "test", "HmacSHA256")); 38 | Assertions.assertEquals(("a958eafd9b36d3b90bc35f9c13fd6f82c0ad535022e4572e36f2e266b78eb44d0858d5ba1ac80baa2295a8" 39 | + "b50804aa4c1f44a710375bc821d94dc799d2fc1193").toLowerCase(), 40 | $.security.digest.digest("gudaoxuri", "test", "HmacSHA512")); 41 | Assertions.assertEquals("8e03e0f7c20e19c58a636a043b9296ae".toLowerCase(), 42 | $.security.digest.digest("gudaoxuri", "test", "HmacMD5")); 43 | 44 | Assertions.assertTrue($.security.digest.validate("gudaoxuri", 45 | $.security.digest.digest("gudaoxuri", "SHA-256"), "SHA-256")); 46 | Assertions.assertTrue($.security.digest.validate("gudaoxuri", "test", 47 | $.security.digest.digest("gudaoxuri", "test", "HmacSHA256"), "HmacSHA256")); 48 | Assertions.assertTrue($.security.digest.validate("password", $.security.digest.digest("password", "SHA-512"), 49 | "SHA-512")); 50 | Assertions.assertTrue($.security.digest.validate("password", $.security.digest.digest("password", "bcrypt"), 51 | "bcrypt")); 52 | } 53 | 54 | /** 55 | * Symmetric. 56 | */ 57 | @Test 58 | public void symmetric() { 59 | try { 60 | Assertions.assertNotEquals("gudaoxuri", $.security.symmetric.decrypt($.security.symmetric.encrypt("gudaoxuri", "pwd", "aes"), "pwd2", 61 | "aes")); 62 | Assertions.assertEquals(1, 2); 63 | } catch (RTException e) { 64 | Assertions.assertEquals(1, 1); 65 | } 66 | Assertions.assertEquals("gudaoxuri", $.security.symmetric.decrypt($.security.symmetric.encrypt("gudaoxuri", "pwd", "aes"), "pwd", "aes")); 67 | String d = "Scala是一门多范式的编程语言,一种类似java的编程语言[1]  ,设计初衷是实现可伸缩的语言[2]  、" + "并集成面向对象编程和函数式编程的各种特性。Scala是一门多范式的编程语言,一种类似java的编程语言[1]  ," + 68 | "设计初衷是实现可伸缩的语言[2]  、并集成面向对象编程和函数式编程的各种特性。Scala是一门多范式的编程语言," + "一种类似java的编程语言[1]  ,设计初衷是实现可伸缩的语言[2]  、并集成面向对象编程和函数式编程的各种特性。"; 69 | try { 70 | Assertions.assertNotEquals(d, $.security.symmetric.decrypt($.security.symmetric.encrypt(d, 71 | "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALjt0CEssHfGENZxyASF6pNtGKYCGW43", "aes"), "pwd2", "aes")); 72 | Assertions.assertEquals(1, 2); 73 | } catch (RTException e) { 74 | Assertions.assertEquals(1, 1); 75 | } 76 | Assertions.assertEquals(d, $.security.symmetric.decrypt($.security.symmetric.encrypt(d, 77 | "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALjt0CEssHfGENZxyASF6pNtGKYCGW43", "aes"), 78 | "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALjt0CEssHfGENZxyASF6pNtGKYCGW43", "aes")); 79 | } 80 | 81 | /** 82 | * Asymmetric. 83 | */ 84 | @Test 85 | public void asymmetric() { 86 | String privateStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALjt0CEssHfGENZxyASF6pNtGKYCGW43+LE" + 87 | "3JhT8y8TE39vDK22GJZWJFXYfWwasavknIfepBIVrnuMidtcPqUY3bhrDZN+J6MtYaSPSEwRcS2" + "PgF/065CEdSbLy6cvKA64GUiG188un1xIsGBVUdu3fdu41OQvt" + 88 | "+90TZT0HclXJAgMBAAECgYEAj" + "XFndVhHCPU3P637PGppBqW06pREeybYUkNKH1dTS4cBaYcXmke2S290OMq2xp3tm++wbUqbKKkt" + 89 | "97AOkWNrJfq8Ecpdw9s3c7yQGWaPuwiX38Cgtq6r0utjT20YgR6etGpqafoBt93RZpEm0eEzFPU" + "nS7qYc86HprL0RJ0" + 90 | "/i7kCQQDaOmvO82cYIK1ESkA0GdDVQoz2A1V8HvEWOsccRGqlWuasLUccyB" + "nx1G/LDZUxcPOraDyxI8sdl7VbweLR0H9LAkEA2O/rWXwnSYKqdpt" + 91 | "+OhpUBHNnMs3IMvRzefJ1z" + "ObnIMyYR3KXtpQ/fL4gEquNwJgFIaPJVg5/3zHISEw3e8XOuwJAIDrGl07tZ+vTiyVoLAmwBP8K" + "MH83jdhIBN9zbqJQGdG+Bam" + 92 | "+Oer3ofac+CEuapni8uq3I/ZEVj+EomOVKyWe1wJAATztROd2ee7" + "q9h5RDBfWXughsKKH" + 93 | "//JxLkL59R9kNkW0oMPApeQWsKmNGU4tUuoLLXP31CvlAusPz4nPzz8DvQ" + "JBAJXpICPNJw84fONzS0raRqlFoZMMI0cqeGtPIiCHKaRHyzQv" + 94 | "/FFu2KxUcCrod8PngaBFRselz" + "rwZILmXHqrHc1M="; 95 | String publicStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC47dAhLLB3xhDWccgEheqTbRimAhluN/ixNyYU/MvExN/" + 96 | "bwytthiWViRV2H1sGrGr5JyH3qQSFa57jInbXD6lGN24aw2TfiejLWGkj0hMEXEtj4Bf9OuQhHU" + 97 | "my8unLygOuBlIhtfPLp9cSLBgVVHbt33buNTkL7fvdE2U9B3JVyQIDAQAB"; 98 | 99 | String d = "Scala是一门多范式的编程语言,一种类似java的编程语言[1]  ,设计初衷是实现可伸缩的语言[2]  、并集成面向对象编程和函数式编程的各种特性。" + "Scala是一门多范式的编程语言,一种类似java的编程语言[1]  " + 100 | ",设计初衷是实现可伸缩的语言[2]  、并集成面向对象编程和函数式编程的各种特性。" + "Scala是一门多范式的编程语言,一种类似java的编程语言[1]  ,设计初衷是实现可伸缩的语言[2]  、并集成面向对象编程和函数式编程的各种特性。"; 101 | // 生成公钥密钥 102 | $.security.asymmetric.generateKeys("RSA", 1024); 103 | PublicKey publicKey = $.security.asymmetric.getPublicKey(publicStr, "RSA"); 104 | PrivateKey privateKey = $.security.asymmetric.getPrivateKey(privateStr, "RSA"); 105 | 106 | // 公钥加密/私钥解密 107 | byte[] encryptByPub = $.security.asymmetric.encrypt(d.getBytes(StandardCharsets.UTF_8), publicKey, 1024, "RSA"); 108 | String result = new String($.security.asymmetric.decrypt(encryptByPub, privateKey, 1024, "RSA"), StandardCharsets.UTF_8); 109 | Assertions.assertEquals(result, d); 110 | 111 | // 私钥加密/公钥解密 112 | byte[] encryptByPriv = $.security.asymmetric.encrypt(d.getBytes(StandardCharsets.UTF_8), privateKey, 1024, "RSA"); 113 | byte[] decryptByPub = $.security.asymmetric.decrypt(encryptByPriv, publicKey, 1024, "RSA"); 114 | Assertions.assertEquals(new String(decryptByPub, StandardCharsets.UTF_8), d); 115 | Assertions.assertTrue($.security.asymmetric.verify(publicKey, decryptByPub, $.security.asymmetric.sign(privateKey, 116 | d.getBytes(StandardCharsets.UTF_8), "SHA1withRSA"), "SHA1withRSA")); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/JsonHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.exception.RTException; 4 | import com.ecfront.dew.common.exception.RTIOException; 5 | import com.fasterxml.jackson.core.JsonParser; 6 | import com.fasterxml.jackson.databind.*; 7 | import com.fasterxml.jackson.databind.node.ArrayNode; 8 | import com.fasterxml.jackson.databind.node.MissingNode; 9 | import com.fasterxml.jackson.databind.node.ObjectNode; 10 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; 11 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 12 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 13 | 14 | import java.io.IOException; 15 | import java.time.LocalDateTime; 16 | import java.time.format.DateTimeFormatter; 17 | import java.util.*; 18 | 19 | /** 20 | * Json与Java对象互转. 21 | *

22 | * 为方便在Java8 Stream中使用,操作返回的异常都是运行时异常 23 | * 24 | * @author gudaoxuri 25 | */ 26 | public final class JsonHelper { 27 | 28 | private static final Map INSTANCES = new HashMap<>(); 29 | 30 | private ObjectMapper mapper; 31 | 32 | private JsonHelper() { 33 | if (DependencyHelper.hasDependency("com.fasterxml.jackson.core.JsonProcessingException")) { 34 | mapper = new ObjectMapper(); 35 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 36 | mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); 37 | mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 38 | mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 39 | JavaTimeModule javaTimeModule = new JavaTimeModule(); 40 | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)); 41 | mapper.registerModule(javaTimeModule); 42 | mapper.registerModule(new Jdk8Module()); 43 | mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 44 | setTimeZone(Calendar.getInstance().getTimeZone()); 45 | } 46 | } 47 | 48 | /** 49 | * Pick json helper. 50 | * 51 | * @param instanceId the instance id 52 | * @return the json helper 53 | */ 54 | static JsonHelper pick(String instanceId) { 55 | return INSTANCES.computeIfAbsent(instanceId, k -> new JsonHelper()); 56 | } 57 | 58 | /** 59 | * 设置时区. 60 | * 61 | * @param tz 时区 62 | */ 63 | public void setTimeZone(TimeZone tz) { 64 | mapper.setTimeZone(tz); 65 | } 66 | 67 | /** 68 | * Java对象转成Json字符串. 69 | * 70 | * @param obj Java对象 71 | * @return Json字符串 string 72 | */ 73 | public String toJsonString(Object obj) { 74 | if (obj instanceof String) { 75 | return (String) obj; 76 | } else { 77 | try { 78 | return mapper.writeValueAsString(obj); 79 | } catch (Exception e) { 80 | throw new RTException(e); 81 | } 82 | } 83 | } 84 | 85 | /** 86 | * Java对象转成JsonNode. 87 | * 88 | * @param obj Java对象 89 | * @return JsonNode json node 90 | */ 91 | public JsonNode toJson(Object obj) { 92 | if (obj instanceof String) { 93 | try { 94 | return mapper.readTree((String) obj); 95 | } catch (IOException e) { 96 | throw new RTIOException(e); 97 | } 98 | } else { 99 | return mapper.valueToTree(obj); 100 | } 101 | } 102 | 103 | /** 104 | * 转成List泛型对象. 105 | * 106 | * @param the type parameter 107 | * @param obj 源数据,可以是Json字符串、JsonNode或其它Java对象 108 | * @param clazz 目标对象类型 109 | * @return 目标对象 list 110 | */ 111 | public List toList(Object obj, Class clazz) { 112 | return (List) toGeneric(obj, List.class, clazz); 113 | } 114 | 115 | /** 116 | * 转成Set泛型对象. 117 | * 118 | * @param the type parameter 119 | * @param obj 源数据,可以是Json字符串、JsonNode或其它Java对象 120 | * @param clazz 目标对象类型 121 | * @return 目标对象 set 122 | */ 123 | public Set toSet(Object obj, Class clazz) { 124 | return (Set) toGeneric(obj, Set.class, clazz); 125 | } 126 | 127 | /** 128 | * 转成Map泛型对象. 129 | * 130 | * @param the type parameter 131 | * @param the type parameter 132 | * @param obj 源数据,可以是Json字符串、JsonNode或其它Java对象 133 | * @param keyClazz 目标对象类型Key 134 | * @param valueClazz 目标对象类型Value 135 | * @return 目标对象 map 136 | */ 137 | public Map toMap(Object obj, Class keyClazz, Class valueClazz) { 138 | return (Map) toGeneric(obj, Map.class, keyClazz, valueClazz); 139 | } 140 | 141 | /** 142 | * 转成泛型对象. 143 | * 144 | * @param obj 源数据,可以是Json字符串、JsonNode或其它Java对象 145 | * @param parametrized 目标对象类型 146 | * @param parameterClasses 目标对象泛型类型 147 | * @return 目标对象 object 148 | */ 149 | public Object toGeneric(Object obj, Class parametrized, Class... parameterClasses) { 150 | JavaType type = mapper.getTypeFactory().constructParametricType(parametrized, parameterClasses); 151 | return toGeneric(obj, type); 152 | } 153 | 154 | private Object toGeneric(Object obj, JavaType type) { 155 | try { 156 | if (obj instanceof String) { 157 | return mapper.readValue((String) obj, type); 158 | } else if (obj instanceof JsonNode) { 159 | return mapper.readValue(obj.toString(), type); 160 | } else { 161 | return mapper.readValue(mapper.writeValueAsString(obj), type); 162 | } 163 | } catch (IOException e) { 164 | throw new RTIOException(e); 165 | } 166 | } 167 | 168 | /** 169 | * 转成目标对象. 170 | * 171 | * @param the type parameter 172 | * @param obj 源数据,可以是Json字符串、JsonNode或其它Java对象 173 | * @param clazz 目标对象类型 174 | * @return 目标对象 e 175 | */ 176 | public E toObject(Object obj, Class clazz) { 177 | try { 178 | if (obj instanceof String) { 179 | if (clazz == String.class) { 180 | return (E) obj; 181 | } else { 182 | return mapper.readValue((String) obj, clazz); 183 | } 184 | } else if (obj instanceof JsonNode) { 185 | return mapper.readValue(obj.toString(), clazz); 186 | } else { 187 | return mapper.readValue(mapper.writeValueAsString(obj), clazz); 188 | } 189 | } catch (IOException e) { 190 | throw new RTIOException(e); 191 | } 192 | } 193 | 194 | /** 195 | * 获取对应路径下的Json. 196 | * 197 | * @param jsonNode Json对象 198 | * @param pathStr 路径 199 | * @return 对应的Json对象 json node 200 | */ 201 | public JsonNode path(JsonNode jsonNode, String pathStr) { 202 | String[] splitPaths = pathStr.split("\\."); 203 | jsonNode = jsonNode.path(splitPaths[0]); 204 | if (jsonNode instanceof MissingNode) { 205 | return null; 206 | } else if (splitPaths.length == 1) { 207 | return jsonNode; 208 | } else { 209 | return path(jsonNode, pathStr.substring(pathStr.indexOf(".") + 1)); 210 | } 211 | } 212 | 213 | /** 214 | * 创建ObjectNode. 215 | * 216 | * @return objectNode object node 217 | */ 218 | public ObjectNode createObjectNode() { 219 | return mapper.createObjectNode(); 220 | } 221 | 222 | /** 223 | * 创建ArrayNode. 224 | * 225 | * @return arrayNode array node 226 | */ 227 | public ArrayNode createArrayNode() { 228 | return mapper.createArrayNode(); 229 | } 230 | 231 | /** 232 | * 获取Jackson底层操作. 233 | * 234 | * @return Jackson ObjectMapper 235 | */ 236 | public ObjectMapper getMapper() { 237 | return mapper; 238 | } 239 | 240 | } 241 | -------------------------------------------------------------------------------- /checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 81 | 82 | 83 | 85 | 86 | 88 | 89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 143 | 144 | 145 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 157 | 158 | 160 | 161 | 162 | 164 | 165 | 166 | 167 | 168 | 170 | 171 | 172 | 173 | 174 | 175 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /it/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 4.0.0 7 | 8 | com.ecfront.dew 9 | common-it 10 | Dew Common integration test 11 | https://github.com/gudaoxuri/dew-common 12 | jar 13 | 3.0.0 14 | 15 | 16 | 21 17 | UTF-8 18 | ${project.build.sourceEncoding} 19 | ${project.build.sourceEncoding} 20 | ${java.version} 21 | ${java.version} 22 | ${java.version} 23 | 24 | true 25 | true 26 | 5.10.2 27 | 28 | 21.2.0 29 | 30 | com.ecfront.dew.common.test.graalvm.NativeImageMain 31 | NativeImageTest 32 | 33 | 34 | 35 | 36 | com.ecfront.dew 37 | common 38 | 4.0.0-rc.1 39 | 40 | 41 | 42 | org.graalvm.truffle 43 | truffle-api 44 | 45 | 46 | org.graalvm.js 47 | js 48 | 49 | 50 | org.graalvm.js 51 | js-scriptengine 52 | 53 | 54 | 55 | 56 | org.junit.jupiter 57 | junit-jupiter 58 | ${junit.version} 59 | test 60 | 61 | 62 | 63 | 64 | ../src/test/java 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-resources-plugin 69 | 70 | 71 | copy-resources-to-test-classes 72 | validate 73 | 74 | copy-resources 75 | 76 | 77 | ${basedir}/target/test-classes 78 | 79 | 80 | ../src/test/resources 81 | 82 | 83 | 84 | 85 | 86 | copy-resources-to-classes 87 | validate 88 | 89 | copy-resources 90 | 91 | 92 | ${basedir}/target/classes 93 | 94 | 95 | ../src/test/resources 96 | 97 | 98 | 99 | 100 | 101 | copy-resources-to-target 102 | validate 103 | 104 | copy-resources 105 | 106 | 107 | ${basedir}/target 108 | 109 | 110 | ../src/test/resources 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | fatjar 123 | 124 | 125 | 126 | org.apache.maven.plugins 127 | maven-assembly-plugin 128 | 129 | 130 | 131 | ${mainClass} 132 | 133 | 134 | 135 | jar-with-dependencies 136 | 137 | 138 | 139 | 140 | assemble-all 141 | package 142 | 143 | single 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | native 153 | 154 | 155 | 156 | org.apache.maven.plugins 157 | maven-surefire-plugin 158 | 159 | 160 | -agentlib:native-image-agent=access-filter-file=${project.basedir}/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/agent-access-filter.json,config-output-dir=${project.basedir}/src/main/resources/META-INF/native-image/com.ecfront.dew/common-it/ 161 | 162 | 163 | 164 | 165 | org.graalvm.nativeimage 166 | native-image-maven-plugin 167 | ${graalvm.version} 168 | 169 | 170 | 171 | native-image 172 | 173 | package 174 | 175 | 176 | 177 | false 178 | ${mainClass} 179 | ${imageName} 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/FileHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.exception.RTIOException; 4 | 5 | import java.io.*; 6 | import java.nio.charset.Charset; 7 | import java.nio.file.*; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | /** 13 | * 常用文件操作. 14 | * 15 | * @author gudaoxuri 16 | */ 17 | public class FileHelper { 18 | 19 | /** 20 | * Instantiates a new File helper. 21 | */ 22 | FileHelper() { 23 | } 24 | 25 | /** 26 | * 根据文件路径名读取文件所有内容. 27 | * 28 | * @param pathName 文件路径名 29 | * @param encode 编码 30 | * @return 文件内容 31 | * @throws RTIOException the rtio exception 32 | */ 33 | public String readAllByPathName(String pathName, String encode) throws RTIOException { 34 | return readAllByPathName(pathName, Charset.forName(encode)); 35 | } 36 | 37 | /** 38 | * 根据文件路径名读取文件所有内容. 39 | * 40 | * @param pathName 文件路径名 41 | * @param encode 编码 42 | * @return 文件内容 43 | * @throws RTIOException the rtio exception 44 | */ 45 | public String readAllByPathName(String pathName, Charset encode) throws RTIOException { 46 | try { 47 | return Files.readString(Paths.get(pathName), encode); 48 | } catch (IOException e) { 49 | throw new RTIOException(e); 50 | } 51 | } 52 | 53 | /** 54 | * 根据文件读取文件所有内容. 55 | * 56 | * @param file 文件 57 | * @param encode 编码 58 | * @return 文件内容 string 59 | * @throws RTIOException the rtio exception 60 | */ 61 | public String readAllByFile(File file, String encode) throws RTIOException { 62 | return readAllByFile(file, Charset.forName(encode)); 63 | } 64 | 65 | /** 66 | * 根据文件读取文件所有内容. 67 | * 68 | * @param file 文件 69 | * @param encode 编码 70 | * @return 文件内容 71 | * @throws RTIOException the rtio exception 72 | */ 73 | public String readAllByFile(File file, Charset encode) throws RTIOException { 74 | try { 75 | return Files.readString(file.toPath(), encode); 76 | } catch (IOException e) { 77 | throw new RTIOException(e); 78 | } 79 | } 80 | 81 | /** 82 | * 根据文件路径读取文件所有内容. 83 | * 84 | * @param path 文件路径 85 | * @param encode 编码 86 | * @return 文件内容 87 | * @throws RTIOException the rtio exception 88 | */ 89 | public String readAllByPath(Path path, String encode) throws RTIOException { 90 | return readAllByPath(path, Charset.forName(encode)); 91 | } 92 | 93 | /** 94 | * 根据文件路径读取文件所有内容. 95 | * 96 | * @param path 文件路径 97 | * @param encode 编码 98 | * @return 文件内容 99 | * @throws RTIOException the rtio exception 100 | */ 101 | public String readAllByPath(Path path, Charset encode) throws RTIOException { 102 | try { 103 | return Files.readString(path, encode); 104 | } catch (IOException e) { 105 | throw new RTIOException(e); 106 | } 107 | } 108 | 109 | /** 110 | * 根据classpath读取文件所有内容(jar包外路径优先). 111 | *

112 | * 113 | * @param classpath classpath,先找jar外的文件,找不到再去读jar包内文件 114 | * @param encode 编码 115 | * @return 文件内容 116 | * @throws RTIOException the rtio exception 117 | */ 118 | public String readAllByClassPath(String classpath, String encode) throws RTIOException { 119 | return readAllByClassPath(classpath, Charset.forName(encode)); 120 | } 121 | 122 | /** 123 | * 根据classpath读取文件所有内容(jar包外路径优先). 124 | *

125 | * 126 | * @param classpath classpath,先找jar外的文件,找不到再去读jar包内文件 127 | * @param encode 编码 128 | * @return 文件内容 129 | * @throws RTIOException the rtio exception 130 | */ 131 | public String readAllByClassPath(String classpath, Charset encode) throws RTIOException { 132 | var path = ClassLoader.getSystemResource(""); 133 | if (path != null) { 134 | File file = new File(path + classpath); 135 | if (file.exists()) { 136 | return readAllByFile(file, encode); 137 | } 138 | } 139 | File file = new File(FileHelper.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 140 | if (file.isFile()) { 141 | file = file.getParentFile(); 142 | file = new File(file.getPath() + File.separator + classpath); 143 | if (file.exists()) { 144 | return readAllByFile(file, encode); 145 | } 146 | } 147 | InputStream in = null; 148 | BufferedReader buffer = null; 149 | try { 150 | in = Thread.currentThread().getContextClassLoader().getResourceAsStream(classpath); 151 | if (in == null) { 152 | in = this.getClass().getResourceAsStream(classpath); 153 | } 154 | if (in == null) { 155 | return null; 156 | } 157 | buffer = new BufferedReader(new InputStreamReader(in)); 158 | return buffer.lines().collect(Collectors.joining("\n")); 159 | } finally { 160 | try { 161 | if (buffer != null) { 162 | buffer.close(); 163 | } 164 | if (in != null) { 165 | in.close(); 166 | } 167 | } catch (IOException e) { 168 | throw new RTIOException(e); 169 | } 170 | } 171 | } 172 | 173 | /** 174 | * 从流中复制文件到磁盘,不支持目录. 175 | * 176 | * @param source 流,支持jar内文件复制 177 | * e.g. Test.class.getResourceAsStream("/LICENSE-junit.txt") 178 | * @param destPath 磁盘路径 179 | * @throws RTIOException the rtio exception 180 | */ 181 | public void copyStreamToPath(InputStream source, String destPath) throws RTIOException { 182 | try { 183 | Files.copy(source, Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING); 184 | source.close(); 185 | } catch (IOException e) { 186 | throw new RTIOException(e); 187 | } 188 | } 189 | 190 | /** 191 | * 判断是否是Windows系统. 192 | * 193 | * @return 是否是Windows系统 boolean 194 | */ 195 | public boolean isWindows() { 196 | return System.getProperty("os.name", "linux").toLowerCase().startsWith("windows"); 197 | } 198 | 199 | 200 | /** 201 | * Glob模式文件过滤器. 202 | * 203 | * @param files 要过滤的文件列表 204 | * @param mathRules Glob过滤规则列表 205 | * @return 过滤后的文件列表 list 206 | * @see Glob过滤规则 207 | */ 208 | public List mathFilter(List files, List mathRules) { 209 | if (mathRules.isEmpty()) { 210 | return files; 211 | } 212 | List matchers = convertGlobMatchers(mathRules); 213 | return convertPaths(files) 214 | .filter(path -> matchers.stream().anyMatch(mather -> mather.matches(path))) 215 | .map(Path::toString) 216 | .collect(Collectors.toList()); 217 | } 218 | 219 | /** 220 | * 使用Glob模式过滤规则检查是否有匹配到的文件. 221 | * 222 | * @param files 要匹配的文件列表 223 | * @param mathRules Glob过滤规则列表 224 | * @return 是否有匹配到的文件 boolean 225 | * @see Glob过滤规则 226 | */ 227 | public boolean anyMath(List files, List mathRules) { 228 | if (files.isEmpty()) { 229 | return false; 230 | } 231 | if (mathRules.isEmpty()) { 232 | return true; 233 | } 234 | List matchers = convertGlobMatchers(mathRules); 235 | return convertPaths(files).anyMatch(path -> matchers.stream().anyMatch(mather -> mather.matches(path))); 236 | } 237 | 238 | /** 239 | * 使用Glob模式过滤规则检查是否有未匹配到的文件. 240 | * 241 | * @param files 要匹配的文件列表 242 | * @param mathRules Glob过滤规则列表 243 | * @return 是否有未匹配到的文件 boolean 244 | * @see Glob过滤规则 245 | */ 246 | public boolean noneMath(List files, List mathRules) { 247 | if (files.isEmpty()) { 248 | return true; 249 | } 250 | if (mathRules.isEmpty()) { 251 | return false; 252 | } 253 | List matchers = convertGlobMatchers(mathRules); 254 | return convertPaths(files).anyMatch(path -> matchers.stream().noneMatch(mather -> mather.matches(path))); 255 | } 256 | 257 | private List convertGlobMatchers(List mathRules) { 258 | return mathRules.stream().map(rule -> FileSystems.getDefault().getPathMatcher("glob:" + rule)).collect(Collectors.toList()); 259 | } 260 | 261 | private Stream convertPaths(List files) { 262 | return files.stream().map(Paths::get); 263 | } 264 | 265 | } 266 | -------------------------------------------------------------------------------- /src/main/java/com/ecfront/dew/common/ShellHelper.java: -------------------------------------------------------------------------------- 1 | package com.ecfront.dew.common; 2 | 3 | import com.ecfront.dew.common.exception.RTIOException; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.InputStreamReader; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.concurrent.*; 15 | 16 | /** 17 | * Shell脚本操作. 18 | * 19 | * @author gudaoxuri 20 | */ 21 | public class ShellHelper { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(ShellHelper.class); 24 | 25 | private static final ExecutorService POOL = Executors.newCachedThreadPool(); 26 | 27 | ShellHelper() { 28 | } 29 | 30 | /** 31 | * 执行入口,如执行成功,此方法只返回output(标准输出). 32 | * 33 | * @param cmd 命令,包含参数 34 | * @return 执行结果(每行输出内容) 35 | */ 36 | public Resp> execute(String cmd) { 37 | return execute(cmd, null); 38 | } 39 | 40 | /** 41 | * 执行入口,如执行成功,此方法只返回output(标准输出). 42 | * 43 | * @param cmd 命令,包含参数 44 | * @param env 执行环境 45 | * @return 执行结果(每行输出内容) 46 | */ 47 | public Resp> execute(String cmd, Map env) { 48 | var reportHandler = new ReportHandler() { 49 | }; 50 | try { 51 | execute(cmd, env, null, null, true, reportHandler).get(); 52 | if (!reportHandler.isFail()) { 53 | return Resp.success(reportHandler.getOutput()); 54 | } else { 55 | return Resp.customFail("", reportHandler.getFailMessage()); 56 | } 57 | } catch (InterruptedException e) { 58 | Thread.currentThread().interrupt(); 59 | LOGGER.error("Execute fail: ", e); 60 | return Resp.customFail("", e.getMessage()); 61 | } catch (Exception e) { 62 | LOGGER.error("Execute fail: ", e); 63 | return Resp.customFail("", e.getMessage()); 64 | } 65 | } 66 | 67 | /** 68 | * 执行入口. 69 | * 70 | * @param cmd 命令或脚本,包含参数 71 | * @param successFlag 成功标识,只要捕捉到此标识就视为成功, 72 | * 为null时不会调用ReportHandler的success方法 73 | * @param progressFlag 进度标识,只要捕捉到此标识就更新进度, 74 | * 格式为: progressFlag 空格 progress ,如: progress 40, 75 | * 为null时不会调用ReportHandler的progress方法 76 | * @param returnResult 是否返回结果(输出内容,包含标准输出stdin及标准错误stderr), 77 | * 为true时会返回结果到ReportHandler的complete方法中, 78 | * 结果暂存于内存中,对输出内容过多的脚本需要考虑占用内存的大小 79 | * @param reportHandler 任务报告实例 80 | * @return 执行结果(Future) 81 | */ 82 | public Future execute(String cmd, 83 | String successFlag, String progressFlag, 84 | boolean returnResult, 85 | ReportHandler reportHandler) throws RTIOException { 86 | return execute(cmd, null, successFlag, progressFlag, returnResult, reportHandler); 87 | } 88 | 89 | /** 90 | * 执行入口. 91 | * 92 | * @param cmd 命令或脚本,包含参数 93 | * @param env 执行环境 94 | * @param successFlag 成功标识,只要捕捉到此标识就视为成功, 95 | * 为null时不会调用ReportHandler的success方法 96 | * @param progressFlag 进度标识,只要捕捉到此标识就更新进度, 97 | * 格式为: progressFlag 空格 progress ,如: progress 40, 98 | * 为null时不会调用ReportHandler的progress方法 99 | * @param returnResult 是否返回结果(输出内容,包含标准输出stdin及标准错误stderr), 100 | * 为true时会返回结果到ReportHandler的complete方法中, 101 | * 结果暂存于内存中,对输出内容过多的脚本需要考虑占用内存的大小 102 | * @param reportHandler 任务报告实例 103 | * @return 执行结果(Future) 104 | */ 105 | public Future execute(String cmd, Map env, 106 | String successFlag, String progressFlag, 107 | boolean returnResult, 108 | ReportHandler reportHandler) throws RTIOException { 109 | ProcessBuilder processBuilder = new ProcessBuilder(); 110 | if (env != null && !env.isEmpty()) { 111 | processBuilder.environment().putAll(env); 112 | } 113 | if ($.file.isWindows()) { 114 | processBuilder.command("cmd.exe", "/c", cmd); 115 | } else { 116 | processBuilder.command("bash", "-c", cmd); 117 | } 118 | Process process; 119 | try { 120 | process = processBuilder.start(); 121 | } catch (IOException e) { 122 | throw new RTIOException(e); 123 | } 124 | return POOL.submit(new ProcessReadTask(process, cmd, 125 | successFlag, progressFlag, returnResult, reportHandler)); 126 | } 127 | 128 | private static class ProcessReadTask implements Callable { 129 | private final Process process; 130 | private final InputStream errorStream; 131 | private final InputStream outputStream; 132 | private final String cmd; 133 | private final String successFlag; 134 | private final String progressFlag; 135 | private final boolean returnResult; 136 | private final ReportHandler reportHandler; 137 | 138 | ProcessReadTask(Process process, String cmd, String successFlag, String progressFlag, boolean returnResult, ReportHandler reportHandler) { 139 | this.process = process; 140 | this.errorStream = process.getErrorStream(); 141 | this.outputStream = process.getInputStream(); 142 | this.cmd = cmd; 143 | this.successFlag = successFlag; 144 | this.progressFlag = progressFlag; 145 | this.returnResult = returnResult; 146 | this.reportHandler = reportHandler; 147 | } 148 | 149 | @Override 150 | public Void call() throws InterruptedException, ExecutionException { 151 | Future> outputResultF = POOL.submit( 152 | new ProcessReader(outputStream, successFlag, progressFlag, returnResult, reportHandler, true)); 153 | Future> errorResultF = POOL.submit( 154 | new ProcessReader(errorStream, successFlag, progressFlag, returnResult, reportHandler, false)); 155 | List outputResult = outputResultF.get(); 156 | List errorResult = errorResultF.get(); 157 | reportHandler.onComplete(outputResult, errorResult); 158 | return null; 159 | } 160 | 161 | private class ProcessReader implements Callable> { 162 | 163 | private final InputStream stream; 164 | private final String successFlag; 165 | private final String progressFlag; 166 | private final boolean returnResult; 167 | private final ReportHandler reportHandler; 168 | private final boolean isOutput; 169 | 170 | ProcessReader(InputStream stream, String successFlag, String progressFlag, 171 | boolean returnResult, ReportHandler reportHandler, boolean isOutput) { 172 | this.stream = stream; 173 | this.successFlag = successFlag; 174 | this.progressFlag = progressFlag; 175 | this.returnResult = returnResult; 176 | this.reportHandler = reportHandler; 177 | this.isOutput = isOutput; 178 | } 179 | 180 | @Override 181 | public List call() throws Exception { 182 | BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 183 | List result = new ArrayList<>(); 184 | String message; 185 | boolean stop = false; 186 | try { 187 | while (!stop && (message = reader.readLine()) != null) { 188 | if (isOutput) { 189 | reportHandler.outputlog(message); 190 | LOGGER.trace("Shell output content:" + message); 191 | } else { 192 | reportHandler.errorlog(message); 193 | LOGGER.trace("Shell error content:" + message); 194 | } 195 | if (returnResult) { 196 | result.add(message); 197 | } 198 | if (successFlag != null 199 | && message.toLowerCase().contains(successFlag.toLowerCase())) { 200 | reportHandler.onSuccess(); 201 | stop = true; 202 | } 203 | if (progressFlag != null 204 | && message.toLowerCase().contains(progressFlag.toLowerCase())) { 205 | reportHandler.onProgress( 206 | Integer.parseInt(message.substring(message.indexOf(progressFlag) + progressFlag.length()).trim())); 207 | } 208 | } 209 | } catch (IOException e) { 210 | String error = e.getMessage() + ", cmd : " + cmd 211 | + "\r\n" + String.join("\r\n", result); 212 | LOGGER.error("Execute fail: " + error, e); 213 | reportHandler.onFail(error); 214 | } finally { 215 | if (0 != process.waitFor()) { 216 | String error = "Abnormal termination , cmd : " + cmd 217 | + "\r\n" + String.join("\r\n", result); 218 | LOGGER.warn("Execute fail: " + error); 219 | reportHandler.onFail(error); 220 | } 221 | } 222 | return result; 223 | } 224 | } 225 | } 226 | 227 | } 228 | --------------------------------------------------------------------------------