diff options
| author | fangshunjian <[email protected]> | 2024-06-26 15:36:41 +0800 |
|---|---|---|
| committer | fangshunjian <[email protected]> | 2024-06-26 15:36:41 +0800 |
| commit | 6698150959ccc888631e3161fb998ce2ebb0f115 (patch) | |
| tree | fa9f8b90a71aac186d8bb11e891e36a96aeade6d | |
| -rw-r--r-- | .gitignore | 207 | ||||
| -rw-r--r-- | pom.xml | 88 | ||||
| -rw-r--r-- | src/main/java/net/geedge/ASWRunner.java | 189 | ||||
| -rw-r--r-- | src/main/java/net/geedge/executor/Executor.java | 39 | ||||
| -rw-r--r-- | src/main/java/net/geedge/executor/JobInfo.java | 35 | ||||
| -rw-r--r-- | src/main/java/net/geedge/util/RunnerContext.java | 148 | ||||
| -rw-r--r-- | src/main/java/net/geedge/util/RunnerYml.java | 28 | ||||
| -rw-r--r-- | src/main/java/net/geedge/util/T.java | 1483 | ||||
| -rw-r--r-- | src/main/java/net/geedge/ws/VncClient.java | 40 | ||||
| -rw-r--r-- | src/main/resources/runner.yml | 11 | ||||
| -rw-r--r-- | src/test/java/net/geedge/test/ConfigTest.java | 29 | ||||
| -rw-r--r-- | src/test/resources/runner.yml | 11 |
12 files changed, 2308 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa4acf6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,207 @@ +/target/ +/.mvn/ +#!.mvn/wrapper/maven-wrapper.jar +mvnw +mvnw.cmd +HELP.md + + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + + +# Created by https://www.gitignore.io/api/git,java,maven,eclipse,windows + +### Eclipse ### + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Java ### +# Compiled class file +*.class + +# Log file +*.log +/log/ + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Some additional ignores (sort later) +*.DS_Store +*.sw? +.#* +*# +*~ +.classpath +.project +.settings +bin +build +target +dependency-reduced-pom.xml +*.sublime-* +/scratch +.gradle +README.html +*.iml +.idea +.exercism
\ No newline at end of file @@ -0,0 +1,88 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>net.geedge</groupId> + <artifactId>asw-runner</artifactId> + <version>1.0</version> + <name>asw-runner</name> + <description>AppSketch Works Runner</description> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.encoding>UTF-8</maven.compiler.encoding> + <java.version>21</java.version> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + </properties> + <dependencies> + <dependency> + <groupId>cn.hutool</groupId> + <artifactId>hutool-all</artifactId> + <version>5.8.16</version> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.8.0</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.java-websocket</groupId> + <artifactId>Java-WebSocket</artifactId> + <version>1.5.6</version> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>1.5.6</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <finalName>${project.artifactId}</finalName> + <resources> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <archive> + <manifest> + <mainClass> + net.geedge.ASWRunner + </mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/src/main/java/net/geedge/ASWRunner.java b/src/main/java/net/geedge/ASWRunner.java new file mode 100644 index 0000000..9f338e0 --- /dev/null +++ b/src/main/java/net/geedge/ASWRunner.java @@ -0,0 +1,189 @@ +package net.geedge; + +import java.io.File; +import java.util.Map; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; + +import cn.hutool.core.lang.Dict; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.log.Log; +import cn.hutool.setting.yaml.YamlUtil; +import net.geedge.executor.Executor; +import net.geedge.executor.JobInfo; +import net.geedge.util.RunnerContext; +import net.geedge.util.RunnerContext.Parameters; +import net.geedge.util.RunnerYml; +import net.geedge.util.RunnerYml.ExecutorConfig; +import net.geedge.util.T; + +/** + * 程序主要包括两个线程 </br> + * 1、心跳线程 </br> + * + * 2、任务请求线程 </br> + * + */ +public class ASWRunner { + private static final Log log = Log.get(); + + public static void main(String[] args) { + // 解析命令行参数 + Parameters param = parseArgs(args); + RunnerContext.setParameters(param); + // 加载配置文件并校验 + loadConfig(); + // 注册登录,阻塞直到注册成功 + register(); + // 启动心跳线程 + startHeartBeatThread(); + + } + + private static Parameters parseArgs(String[] args) { + Option configOption = Option.builder("c").longOpt("config_path").hasArg(true).desc("config file path") + .required(false).build(); + Option intervalOption = Option.builder("t").longOpt("heartbeat_interval").hasArg(true) + .desc("heart beat interval milliseconds").required(false).build(); + // 解析命令行参数 + Options options = new Options(); + options.addOption(configOption); + options.addOption(intervalOption); + CommandLine cli = null; + CommandLineParser cliParser = new DefaultParser(); + HelpFormatter helpFormatter = new HelpFormatter(); + + try { + cli = cliParser.parse(options, args); + } catch (Exception e) { + // 解析失败是用 HelpFormatter 打印 帮助信息 + helpFormatter.printHelp("AppSketch Works Runners", options); + log.error(e, "args parse error"); + System.exit(1); + } + // 配置文件路径 + String configPath = T.StrUtil.isNotBlank(cli.getOptionValue(configOption)) ? cli.getOptionValue(configOption) + : RunnerContext.DEFAULT_CONFIG_PATH; + // 心跳周期间隔时间 + Integer heartBeatInterval = T.StrUtil.isNotBlank(cli.getOptionValue(intervalOption)) + ? T.NumberUtil.parseInt(cli.getOptionValue(intervalOption)) + : RunnerContext.DEFAULT_HEARTBEAT_INTERVAL; + log.debug("config path: {}", configPath); + log.debug("heartbeat interval: {}ms", heartBeatInterval); + return new Parameters(configPath, heartBeatInterval); + } + + /** + * 加载配置文件 + */ + private static void loadConfig() { + try { + String configPath = RunnerContext.getParameters().configPath(); + if(!T.FileUtil.isAbsolutePath(configPath)) { + // 获取当前JAR包的路径 + String jarPath = ASWRunner.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); + // 创建File对象并获取目录 + configPath = T.FileUtil.file(T.FileUtil.file(jarPath).getParentFile(), configPath).getAbsolutePath(); + } + log.info("load config file, absolute path : {}", configPath); + Dict dict = YamlUtil.loadByPath(configPath); + RunnerYml runnerYml = T.BeanUtil.copyProperties(dict, RunnerYml.class); + RunnerContext.setRunnerYml(runnerYml); + String registerUrl = runnerYml.getRegister().getUrl(); + if (T.StrUtil.isBlank(registerUrl)) { + throw new RuntimeException("register url is blank"); + } + if (T.CollUtil.isEmpty(runnerYml.getExecutors())) { + throw new RuntimeException("no executor"); + } + log.debug("config content: {}", T.JSONUtil.toJsonStr(runnerYml)); + } catch (Exception e) { + log.error(e, "load config error"); + System.exit(2); + } + } + + /** + * 注册登录 + * + * @param url + * @param token + * @return + */ + private static void register() { + while (RunnerContext.getRunFlag()) { + try { + String url = RunnerContext.getRegisterPath(); + String token = RunnerContext.getRegisterToken(); + log.info("start register,url:{}", url); + HttpRequest request = T.HttpUtil.createPost(url); + request.addHeaders(T.MapUtil.of("Authorization", token)); + HttpResponse response = request.execute(); + int status = response.getStatus(); + log.info("register status: {}", status); + if (status == 200) { + log.info("register success"); + break; + } + } catch (Exception e) { + log.error(e, "register error"); + } + T.ThreadUtil.sleep(5000); + } + } + + /** + * 心跳线程 + */ + private static void startHeartBeatThread() { + T.ThreadUtil.execAsync(() -> { + Thread.currentThread().setName("heartbeat-thread"); + while (RunnerContext.getRunFlag()) { + try { + // 获取当前运行状态 + Map<String, Integer> freeExecutorNum = RunnerContext.getFreeExecutorNum(); + if (log.isDebugEnabled()) { + log.debug("heart beat body: {}", T.JSONUtil.toJsonStr(freeExecutorNum)); + } + // 发送http请求 + HttpRequest request = T.HttpUtil.createPost(RunnerContext.getheartbeatPath()); + request.addHeaders(T.MapUtil.of("Authorization", RunnerContext.getRegisterToken())); + request.body(T.JSONUtil.toJsonStr(freeExecutorNum)); + HttpResponse response = request.execute(); + // 解析http响应,创建任务 + int status = response.getStatus(); + log.info("heart beat status: {}", status); + String body = response.body(); + log.debug("heart beat response body: {}", body); + if (status == 200 && T.StrUtil.isNotBlank(body)) { + JobInfo jobInfo = T.JSONUtil.toBean(body, JobInfo.class); + String platform = jobInfo.getPkg().getPlatform(); + log.info("jobinfo id: {}, packageId: {}, platform: {}", jobInfo.getId(), + jobInfo.getPkg().getId(), platform); + ExecutorConfig executorConfig = RunnerContext.getFreeExecutorByPlatform(platform); + if (executorConfig == null) { + throw new RuntimeException(T.StrUtil.format("no free executor, platform: {} ", platform)); + } + Executor exec = new Executor(); + exec.setJobInfo(jobInfo); + exec.setExecutorConfig(executorConfig); + T.ThreadUtil.execute(exec); + } + } catch (Exception e) { + log.error(e, "heart beat error"); + } + /* + * 心跳线程下次继续 + */ + T.ThreadUtil.sleep(RunnerContext.getHeartbeatInterval()); + } + }); + } + +} diff --git a/src/main/java/net/geedge/executor/Executor.java b/src/main/java/net/geedge/executor/Executor.java new file mode 100644 index 0000000..494ef2f --- /dev/null +++ b/src/main/java/net/geedge/executor/Executor.java @@ -0,0 +1,39 @@ +package net.geedge.executor; + +import cn.hutool.log.Log; +import lombok.Data; +import net.geedge.util.RunnerContext; +import net.geedge.util.RunnerYml.ExecutorConfig; + +@Data +public class Executor implements Runnable{ + private ExecutorConfig executorConfig; + private JobInfo jobInfo; + Log log = Log.get(); + + @Override + public void run() { + Thread.currentThread().setName("job-excutor-"+jobInfo.getId()); + log.info("job executor start"); + RunnerContext.addActiveExecutors(this); + try { + log.info("job executor run job start"); + this.runJob(); + log.info("job executor run job end"); + } finally { + RunnerContext.removeActiveExecutors(this); + log.info("job executor run jobend"); + } + } + + /** + * 运行playbook + * @param path playbook文件路径 + * @param config executor配置 + */ + void runJob() { + + }; + + +} diff --git a/src/main/java/net/geedge/executor/JobInfo.java b/src/main/java/net/geedge/executor/JobInfo.java new file mode 100644 index 0000000..7fcedaa --- /dev/null +++ b/src/main/java/net/geedge/executor/JobInfo.java @@ -0,0 +1,35 @@ +package net.geedge.executor; + +import java.util.List; + +import lombok.Data; + +@Data +public class JobInfo { + private String id; + private Playbook playbook; + private Package pkg; + private List<Signature> signatures; + + @Data + public class Package { + String id; + String platform; + String version; + String identifier; + } + + @Data + public class Playbook { + String id; + String name; + String tags; + } + + @Data + public class Signature { + String id; + String name; + String conditions; + } +} diff --git a/src/main/java/net/geedge/util/RunnerContext.java b/src/main/java/net/geedge/util/RunnerContext.java new file mode 100644 index 0000000..f3c093f --- /dev/null +++ b/src/main/java/net/geedge/util/RunnerContext.java @@ -0,0 +1,148 @@ +package net.geedge.util; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; + +import net.geedge.executor.Executor; +import net.geedge.util.RunnerYml.ExecutorConfig; + +public class RunnerContext { + /** + * 默认配置文件路径 + */ + public static final String DEFAULT_CONFIG_PATH = "./runner.yml"; + /** + * 默认心跳间隔 5s + */ + public static final Integer DEFAULT_HEARTBEAT_INTERVAL = 5000; + public static final String REGISTER_PATH = "/register"; + /** + * 心跳接口路径 + */ + private static final String HEARTBEAT_PATH = "/heartbeat"; + /** + * 程序运行标识 + */ + private volatile static boolean runFlag = true; + + /** + * 命令行参数 + */ + public record Parameters(String configPath, Integer heartbeatInterval) { + }; + + /** + * 保存命令行参数 + */ + private volatile static Parameters parameters; + /** + * 保存配置文件参数 + */ + private volatile static RunnerYml runnerYml; + /** + * 记录当前正在运行的 executor + */ + private volatile static List<Executor> activeExecutors = T.ListUtil.toCopyOnWriteArrayList(null); + + + public static boolean getRunFlag() { + return runFlag; + } + + public static String getRegisterPath() { + return REGISTER_PATH; + } + + public static String getheartbeatPath() { + return HEARTBEAT_PATH; + } + + public static String getRegisterToken() { + return HEARTBEAT_PATH; + } + + public static void setParameters(Parameters param) { + parameters = param; + } + + public static Parameters getParameters() { + return parameters; + } + + public static Integer getHeartbeatInterval() { + return parameters.heartbeatInterval(); + } + + public static String getConfigPath() { + return parameters.configPath(); + } + + public static RunnerYml getRunnerYml() { + return runnerYml; + } + + public static void setRunnerYml(RunnerYml yml) { + runnerYml = yml; + } + + /** + * 获取空闲 executor 数量 + * + * platform:num + * + * @return + */ + public static List<ExecutorConfig> getFreeExecutor() { + List<ExecutorConfig> result = T.ListUtil.list(false); + // 记录每个平台可以提供几个运行实例 + runnerYml.getExecutors().forEach(e -> { + result.add(e); + }); + // 减去现有的运行实例 + activeExecutors.forEach(ae -> { + ExecutorConfig config = ae.getExecutorConfig(); + result.forEach(e -> { + if (e.getType().equals(config.getType()) && e.getPlatform().equals(config.getPlatform())) { + e.setConcurrent(e.getConcurrent() - 1); + } + }); + }); + return result; + } + + public static ExecutorConfig getFreeExecutorByPlatform(String platform) { + List<ExecutorConfig> freeExecutor = getFreeExecutor(); + for (ExecutorConfig e : freeExecutor) { + if(e.getPlatform().equals(platform)) { + return e; + } + } + return null; + } + + public static Map<String, Integer> getFreeExecutorNum() { + List<ExecutorConfig> list = getFreeExecutor(); + Map<String,Integer> result = T.MapUtil.newHashMap(); + list.forEach(c -> { + Integer num = result.getOrDefault(c.getPlatform(), 0); + result.put(c.getPlatform(), num+c.getConcurrent()); + }); + return result; + } + + public static void addActiveExecutors(Executor e) { + activeExecutors.add(e); + } + + public static void removeActiveExecutors(Executor e) { + Iterator<Executor> ite = activeExecutors.iterator(); + while(ite.hasNext()) { + Executor next = ite.next(); + if(next.getJobInfo().getId().equals(e.getJobInfo().getId())) { + ite.remove(); + } + } + } +} diff --git a/src/main/java/net/geedge/util/RunnerYml.java b/src/main/java/net/geedge/util/RunnerYml.java new file mode 100644 index 0000000..1ed0cfe --- /dev/null +++ b/src/main/java/net/geedge/util/RunnerYml.java @@ -0,0 +1,28 @@ +package net.geedge.util; + +import java.util.List; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +public class RunnerYml { + + private Register register; + private List<ExecutorConfig> executors; + + @Data + public class Register { + String url; + String token; + } + + @Data + public class ExecutorConfig { + String type; + String platform; + Integer concurrent; + String image; + } + +} diff --git a/src/main/java/net/geedge/util/T.java b/src/main/java/net/geedge/util/T.java new file mode 100644 index 0000000..0f659b1 --- /dev/null +++ b/src/main/java/net/geedge/util/T.java @@ -0,0 +1,1483 @@ +package net.geedge.util; + +import java.awt.Graphics; +import java.awt.Robot; +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.time.LocalDateTime; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.util.Calendar; +import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; + +import cn.hutool.core.date.DateTime; + +public class T { + + public static final Pattern REGEX_SPECIAL_DATE = Pattern + .compile("(\\d{4}-\\d{1,2}-\\d{1,2}[T]\\d{1,2}:\\d{1,2}:\\d{1,2})(.\\d{1,10})((\\+\\d{1,2}:\\d{1,2})|(Z))"); + /** + * 数据库操作工具类 + */ + public final static cn.hutool.db.DbUtil DbUtil = new cn.hutool.db.DbUtil(); + /** + * 安全相关工具类<br> + * 加密分为三种:<br> + * 1、对称加密(symmetric),例如:AES、DES等<br> + * 2、非对称加密(asymmetric),例如:RSA、DSA等<br> + * 3、摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等<br> + */ + public final static cn.hutool.crypto.SecureUtil SecureUtil = new cn.hutool.crypto.SecureUtil(); + /** + * 代理工具类 + */ + public final static cn.hutool.aop.ProxyUtil ProxyUtil = new cn.hutool.aop.ProxyUtil(); + /** + * 敏感词工具类 + */ + public final static cn.hutool.dfa.SensitiveUtil SensitiveUtil = new cn.hutool.dfa.SensitiveUtil(); + + /** + * json 工具类 + */ + public static class JSONUtil extends cn.hutool.json.JSONUtil { + } + + /** + * 数据库元数据信息工具类 + * + * <p> + * 需要注意的是,此工具类在某些数据库(比如Oracle)下无效,此时需要手动在数据库配置中增加: + * + * <pre> + * remarks = true + * useInformationSchema = true + * </pre> + * + * @author looly + */ + public static class MetaUtil extends cn.hutool.db.meta.MetaUtil { + } + + /** + * 异常工具类 + * + * @author Looly + */ + public static class ExceptionUtil extends cn.hutool.core.exceptions.ExceptionUtil { + } + + /** + * 正则相关工具类<br> + * 常用正则请见 {@link cn.hutool.core.lang.Validator} + * + * @author xiaoleilu + */ + public static class ReUtil extends cn.hutool.core.util.ReUtil { + } + + /** + * SOAP相关工具类 + * + * @author looly + * @since 4.5.7 + */ + public static class SoapUtil extends cn.hutool.http.webservice.SoapUtil { + } + + /** + * 脚本工具类 + * + * @author Looly + */ + public static class ScriptUtil extends cn.hutool.script.ScriptUtil { + } + + /** + * 提供Unicode字符串和普通字符串之间的转换 + * + * @author 兜兜毛毛, looly + * @since 4.0.0 + */ + public static class UnicodeUtil extends cn.hutool.core.text.UnicodeUtil { + } + + /** + * 时间工具类 + * + * @author xiaoleilu + */ + public static class DateUtil extends cn.hutool.core.date.DateUtil { + /** + * 为了处理 2021-05-21T12:06:29.272986526+08:00 格式时间 + * + * @param utcString + * @return + */ + public static DateTime parseUTC(String utcString) { + if (StrUtil.isBlank(utcString)) { + return null; + } + if (utcString.length() > 29) { + Matcher matcher = REGEX_SPECIAL_DATE.matcher(utcString); + if (matcher.matches()) { + utcString = T.StrUtil.concat(true, matcher.group(1), matcher.group(3)); + } + } + return cn.hutool.core.date.DateUtil.parseUTC(utcString); + } + + } + + /** + * EC密钥参数相关工具类封装 + * + * @author looly + * @since 5.4.3 + */ + public static class ECKeyUtil extends cn.hutool.crypto.ECKeyUtil { + } + + /** + * 枚举工具类 + * + * @author looly + * @since 3.3.0 + */ + public static class EnumUtil extends cn.hutool.core.util.EnumUtil { + } + + /** + * 数学相关方法工具类<br> + * 此工具类与{@link cn.hutool.core.util.NumberUtil}属于一类工具,NumberUtil偏向于简单数学计算的封装,MathUtil偏向复杂数学计算 + * + * @author looly + * @since 4.0.7 + */ + public static class MathUtil extends cn.hutool.core.math.MathUtil { + } + + /** + * Sax方式读取Excel相关工具类 + * + * @author looly + */ + public static class ExcelSaxUtil extends cn.hutool.poi.excel.sax.ExcelSaxUtil { + } + + /** + * 数字工具类<br> + * 对于精确值计算应该使用 {@link BigDecimal}<br> + * JDK7中<strong>BigDecimal(double val)</strong>构造方法的结果有一定的不可预知性,例如: + * + * <pre> + * new BigDecimal(0.1) + * </pre> + * <p> + * 表示的不是<strong>0.1</strong>而是<strong>0.1000000000000000055511151231257827021181583404541015625</strong> + * + * <p> + * 这是因为0.1无法准确的表示为double。因此应该使用<strong>new BigDecimal(String)</strong>。 + * </p> + * 相关介绍: + * <ul> + * <li>http://www.oschina.net/code/snippet_563112_25237</li> + * <li>https://github.com/venusdrogon/feilong-core/wiki/one-jdk7-bug-thinking</li> + * </ul> + * + * @author Looly + */ + public static class NumberUtil extends cn.hutool.core.util.NumberUtil { + } + + /** + * Jsch工具类<br> + * Jsch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。<br> + * 它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等。<br> + * + * @author Looly + * @since 4.0.0 + */ + public static class JschUtil extends cn.hutool.extra.ssh.JschUtil { + } + + /** + * 线程池工具 + * + * @author luxiaolei + */ + public static class ThreadUtil extends cn.hutool.core.thread.ThreadUtil { + } + + /** + * Oshi库封装的工具类,通过此工具类,可获取系统、硬件相关信息 + * + * <pre> + * 1、系统信息 + * 2、硬件信息 + * </pre> + * + * 相关内容见:https://github.com/oshi/oshi + * + * @author Looly + * @since 4.6.4 + */ + public static class OshiUtil extends cn.hutool.system.oshi.OshiUtil { + } + + /** + * URL(Uniform Resource Locator)统一资源定位符相关工具类 + * + * <p> + * 统一资源定位符,描述了一台特定服务器上某资源的特定位置。 + * </p> + * URL组成: + * + * <pre> + * 协议://主机名[:端口]/ 路径/[:参数] [?查询]#Fragment + * protocol :// hostname[:port] / path / [:parameters][?query]#fragment + * </pre> + * + * @author xiaoleilu + */ + public static class URLUtil extends cn.hutool.core.util.URLUtil { + } + + /** + * ID生成器工具类,此工具类中主要封装: + * + * <pre> + * 1. 唯一性ID生成器:UUID、ObjectId(MongoDB)、Snowflake + * </pre> + * + * <p> + * ID相关文章见:http://calvin1978.blogcn.com/articles/uuid.html + * + * @author looly + * @since 4.1.13 + */ + public static class IdUtil extends cn.hutool.core.util.IdUtil { + } + + /** + * Http请求工具类 + * + * @author xiaoleilu + */ + public static class HttpUtil extends cn.hutool.http.HttpUtil { + } + + /** + * 桌面相关工具(平台相关)<br> + * Desktop 类允许 Java 应用程序启动已在本机桌面上注册的关联应用程序,以处理 URI 或文件。 + * + * @author looly + * @since 4.5.7 + */ + public static class DesktopUtil extends cn.hutool.core.swing.DesktopUtil { + } + + /** + * 图片处理工具类:<br> + * 功能:缩放图像、切割图像、旋转、图像类型转换、彩色转黑白、文字水印、图片水印等 <br> + * 参考:http://blog.csdn.net/zhangzhikaixinya/article/details/8459400 + * + * @author Looly + */ + public static class ImgUtil extends cn.hutool.core.img.ImgUtil { + } + + /** + * HTML工具类 + * + * <p> + * 比如我们在使用爬虫爬取HTML页面后,需要对返回页面的HTML内容做一定处理,<br> + * 比如去掉指定标签(例如广告栏等)、去除JS、去掉样式等等,这些操作都可以使用此工具类完成。 + * + * @author xiaoleilu + * + */ + public static class HtmlUtil extends cn.hutool.http.HtmlUtil { + } + + /** + * PEM(Privacy Enhanced Mail)格式相关工具类。(基于Bouncy Castle) + * + * <p> + * PEM一般为文本格式,以 -----BEGIN... 开头,以 -----END... 结尾,中间的内容是 BASE64 编码。 + * <p> + * 这种格式可以保存证书和私钥,有时我们也把PEM格式的私钥的后缀改为 .key 以区别证书与私钥。 + * + * @author looly + * @since 5.1.6 + */ + public static class PemUtil extends cn.hutool.crypto.PemUtil { + } + + /** + * 分词工具类 + * + * @author looly + * @since 4.3.3 + */ + public static class TokenizerUtil extends cn.hutool.extra.tokenizer.TokenizerUtil { + } + + /** + * ExcelExtractor工具封装 + * + * @author looly + * @since 5.4.4 + */ + public static class ExcelExtractorUtil extends cn.hutool.poi.excel.ExcelExtractorUtil { + } + + /** + * 邮件工具类,基于javax.mail封装 + * + * @author looly + * @since 3.1.2 + */ + public static class MailUtil extends cn.hutool.extra.mail.MailUtil { + } + + /** + * NIO中Path对象操作封装 + * + * @author looly + * @since 5.4.1 + */ + public static class PathUtil extends cn.hutool.core.io.file.PathUtil { + } + + /** + * 邮件内部工具类 + * + * @author looly + * @since 3.2.3 + */ + public static class InternalMailUtil extends cn.hutool.extra.mail.InternalMailUtil { + } + + /** + * 定时任务工具类<br> + * 此工具持有一个全局{@link cn.hutool.cron.Scheduler},所有定时任务在同一个调度器中执行<br> + * {@link #setMatchSecond(boolean)} + * 方法用于定义是否使用秒匹配模式,如果为true,则定时任务表达式中的第一位为秒,否则为分,默认是分 + * + * @author xiaoleilu + * + */ + public static class CronUtil extends cn.hutool.cron.CronUtil { + } + + /** + * Java的System类封装工具类。<br> + * 参考:http://blog.csdn.net/zhongweijian/article/details/7619383 + * + * @author Looly + */ + public static class SystemUtil extends cn.hutool.system.SystemUtil { + } + + /** + * 压缩工具类<br> + * 基于commons-compress的压缩解压封装 + * + * @author looly + * @since 5.5.0 + */ + public static class CompressUtil extends cn.hutool.extra.compress.CompressUtil { + } + + /** + * {@link ClassLoader}工具类 + * + * @author Looly + * @since 3.0.9 + */ + public static class ClassLoaderUtil extends cn.hutool.core.util.ClassLoaderUtil { + } + + /** + * {@link Spliterator}相关工具类 + * + * @author looly + * @since 5.4.3 + */ + public static class SpliteratorUtil extends cn.hutool.core.collection.SpliteratorUtil { + } + + /** + * 监听工具类<br> + * 主要负责文件监听器的快捷创建 + * + * @author Looly + * @since 3.1.0 + */ + public static class WatchUtil extends cn.hutool.core.io.watch.WatchUtil { + } + + /** + * Excel样式工具类 + * + * @author looly + * @since 4.0.0 + */ + public static class StyleUtil extends cn.hutool.poi.excel.style.StyleUtil { + } + + /** + * 系统剪贴板工具类 + * + * @author looly + * @since 3.2.0 + */ + public static class ClipboardUtil extends cn.hutool.core.swing.clipboard.ClipboardUtil { + } + + /** + * 文件类型判断工具类 + * + * <p> + * 此工具根据文件的前几位bytes猜测文件类型,对于文本、zip判断不准确,对于视频、图片类型判断准确 + * </p> + * + * <p> + * 需要注意的是,xlsx、docx等Office2007格式,全部识别为zip,因为新版采用了OpenXML格式,这些格式本质上是XML文件打包为zip + * </p> + * + * @author Looly + */ + public static class FileTypeUtil extends cn.hutool.core.io.FileTypeUtil { + } + + /** + * 引用工具类,主要针对{@link Reference} 工具化封装<br> + * 主要封装包括: + * + * <pre> + * 1. {@link SoftReference} 软引用,在GC报告内存不足时会被GC回收 + * 2. {@link WeakReference} 弱引用,在GC时发现弱引用会回收其对象 + * 3. {@link PhantomReference} 虚引用,在GC时发现虚引用对象,会将{@link PhantomReference}插入{@link ReferenceQueue}。 此时对象未被真正回收,要等到{@link ReferenceQueue}被真正处理后才会被回收。 + * </pre> + * + * @author looly + * @since 3.1.2 + */ + public static class ReferenceUtil extends cn.hutool.core.util.ReferenceUtil { + } + + /** + * 布隆过滤器工具 + * + * @author looly + * @since 4.1.5 + */ + public static class BloomFilterUtil extends cn.hutool.bloomfilter.BloomFilterUtil { + } + + /** + * 修饰符工具类 + * + * @author looly + * @since 4.0.5 + */ + public static class ModifierUtil extends cn.hutool.core.util.ModifierUtil { + } + + /** + * 集合的stream操作封装 + * + * @author [email protected] + * @since 5.5.2 + */ + public static class CollStreamUtil extends cn.hutool.core.collection.CollStreamUtil { + } + + /** + * 摘要算法工具类 + * + * @author Looly + */ + public static class DigestUtil extends cn.hutool.crypto.digest.DigestUtil { + } + + /** + * 对象工具类,包括判空、克隆、序列化等操作 + * + * @author Looly + */ + public static class ObjectUtil extends cn.hutool.core.util.ObjectUtil { + } + + /** + * Hash算法大全<br> + * 推荐使用FNV1算法 + * + * @author Goodzzp, Looly + */ + public static class HashUtil extends cn.hutool.core.util.HashUtil { + } + + /** + * Bouncy Castle相关工具类封装 + * + * @author looly + * @since 4.5.0 + */ + public static class BCUtil extends cn.hutool.crypto.BCUtil { + } + + /** + * 针对 {@link Type} 的工具类封装<br> + * 最主要功能包括: + * + * <pre> + * 1. 获取方法的参数和返回值类型(包括Type和Class) + * 2. 获取泛型参数类型(包括对象的泛型参数或集合元素的泛型类型) + * </pre> + * + * @author Looly + * @since 3.0.8 + */ + public static class TypeUtil extends cn.hutool.core.util.TypeUtil { + } + + /** + * Excel文件工具类 + * + * @author looly + * @since 4.2.1 + */ + public static class ExcelFileUtil extends cn.hutool.poi.excel.ExcelFileUtil { + } + + /** + * NIO工具类 + * + * @since 5.4.0 + */ + public static class NioUtil extends cn.hutool.socket.nio.NioUtil { + } + + /** + * 类工具类 <br> + * + * @author xiaoleilu + */ + public static class ClassUtil extends cn.hutool.core.util.ClassUtil { + } + + /** + * 针对{@link Calendar} 对象封装工具类 + * + * @author looly + * @since 5.3.0 + */ + public static class CalendarUtil extends cn.hutool.core.date.CalendarUtil { + } + + /** + * 网络相关工具 + * + */ + public static class NetUtil extends cn.hutool.core.net.NetUtil { + + public static String getLocalIPBySocket(String host, Integer port) { + Socket socket = null; + try { + socket = new Socket(host, port); + return socket.getLocalAddress().getHostAddress(); + } catch (Exception e) { + return T.NetUtil.getLocalhostStr(); + } finally { + T.IoUtil.close(socket); + } + } + + } + + /** + * 源码编译工具类,主要封装{@link JavaCompiler} 相关功能 + * + * @author looly + * @since 5.5.2 + */ + public static class CompilerUtil extends cn.hutool.core.compiler.CompilerUtil { + } + + /** + * 锁相关工具 + * + * @author looly + * @since 5.2.5 + */ + public static class LockUtil extends cn.hutool.core.thread.lock.LockUtil { + } + + /** + * 文件名相关工具类 + * + * @author looly + * @since 5.4.1 + */ + public static class FileNameUtil extends cn.hutool.core.io.file.FileNameUtil { + } + + /** + * SM国密算法工具类<br> + * 此工具类依赖org.bouncycastle:bcpkix-jdk15on + * + * @author looly + * @since 4.3.2 + */ + public static class SmUtil extends cn.hutool.crypto.SmUtil { + } + + /** + * Props工具类<br> + * 提供静态方法获取配置文件 + * + * @author looly + * @since 5.1.3 + */ + public static class PropsUtil extends cn.hutool.setting.dialect.PropsUtil { + } + + /** + * XML工具类<br> + * 此工具使用w3c dom工具,不需要依赖第三方包。<br> + * 工具类封装了XML文档的创建、读取、写出和部分XML操作 + * + * @author xiaoleilu + */ + public static class XmlUtil extends cn.hutool.core.util.XmlUtil { + } + + /** + * Velocity模板引擎工具类<br> + * 使用前必须初始化工具类 + * + * @author xiaoleilu + * @deprecated 使用TemplateUtil替代 + */ + public static class VelocityEngine extends cn.hutool.extra.template.engine.velocity.VelocityEngine { + } + + /** + * {@link ByteBuffer} 工具类<br> + * 此工具来自于 t-io 项目以及其它项目的相关部分收集<br> + * ByteBuffer的相关介绍见:https://www.cnblogs.com/ruber/p/6857159.html + * + * @author tanyaowu, looly + * @since 4.0.0 + * + */ + public static class BufferUtil extends cn.hutool.core.io.BufferUtil { + } + + /** + * 表达式引擎工具类 + * + * @author looly + * @since 5.5.0 + */ + public static class ExpressionUtil extends cn.hutool.extra.expression.ExpressionUtil { + } + + /** + * 驱动相关工具类,包括自动获取驱动类名 + * + * @author looly + * @since 4.0.10 + */ + public static class DriverUtil extends cn.hutool.db.dialect.DriverUtil { + } + + /** + * IO工具类<br> + * IO工具类只是辅助流的读写,并不负责关闭流。原因是流可能被多次读写,读写关闭后容易造成问题。 + * + * @author xiaoleilu + */ + public static class IoUtil extends cn.hutool.core.io.IoUtil { + } + + /** + * JDK8+中的{@link LocalDateTime} 工具类封装 + * + * @author looly + * @since 5.3.9 + */ + public static class LocalDateTimeUtil extends cn.hutool.core.date.LocalDateTimeUtil { + } + + /** + * 规范化对象生成工具 + * + * @author looly + * @since 5.4.3 + */ + public static class InternUtil extends cn.hutool.core.lang.intern.InternUtil { + } + + /** + * 压缩工具类 + * + * @author Looly + */ + public static class ZipUtil extends cn.hutool.core.util.ZipUtil { + } + + /** + * 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。<br> + * 例如十进制数57,在二进制写作111001,在16进制写作39。<br> + * 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br> + * <p> + * 参考:https://my.oschina.net/xinxingegeya/blog/287476 + * + * @author Looly + */ + public static class HexUtil extends cn.hutool.core.util.HexUtil { + } + + /** + * 数据大小工具类 + * + * @author looly + * @since 5.3.10 + */ + public static class DataSizeUtil extends cn.hutool.core.io.unit.DataSizeUtil { + } + + /** + * User-Agent工具类 + * + * @author looly + * + */ + public static class UserAgentUtil extends cn.hutool.http.useragent.UserAgentUtil { + } + + /** + * 统一社会信用代码工具类 + * + * <pre> + * 第一部分:登记管理部门代码1位 (数字或大写英文字母) + * 第二部分:机构类别代码1位 (数字或大写英文字母) + * 第三部分:登记管理机关行政区划码6位 (数字) + * 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母) + * 第五部分:校验码1位 (数字或大写英文字母) + * </pre> + * + * @author looly + * @since 5.2.4 + */ + public static class CreditCodeUtil extends cn.hutool.core.util.CreditCodeUtil { + } + + /** + * {@link Temporal} 工具类封装 + * + * @author looly + * @since 5.4.5 + */ + public static class TemporalUtil extends cn.hutool.core.date.TemporalUtil { + } + + /** + * Setting工具类<br> + * 提供静态方法获取配置文件 + * + * @author looly + */ + public static class SettingUtil extends cn.hutool.setting.SettingUtil { + } + + /** + * Statement和PreparedStatement工具类 + * + * @author looly + * @since 4.0.10 + */ + public static class StatementUtil extends cn.hutool.db.StatementUtil { + } + + /** + * 基于https://github.com/vdurmont/emoji-java的Emoji表情工具类 + * <p> + * emoji-java文档以及别名列表见:https://github.com/vdurmont/emoji-java + * + * @author looly + * @since 4.2.1 + */ + public static class EmojiUtil extends cn.hutool.extra.emoji.EmojiUtil { + } + + /** + * Bean工具类 + * + * <p> + * 把一个拥有对属性进行set和get方法的类,我们就可以称之为JavaBean。 + * </p> + * + * @author Looly + * @since 3.1.2 + */ + public static class BeanUtil extends cn.hutool.core.bean.BeanUtil { + } + + /** + * Servlet相关工具类封装 + * + * @author looly + * @since 3.2.0 + */ + public static class ServletUtil extends cn.hutool.extra.servlet.ServletUtil { + } + + /** + * java bean 校验工具类,此工具类基于validation-api(jakarta.validation-api)封装 + * + * <p> + * 在实际使用中,用户需引入validation-api的实现,如:hibernate-validator + * </p> + * <p> + * 注意:hibernate-validator还依赖了javax.el,需自行引入。 + * </p> + * + * @author chengqiang + * @since 5.5.0 + */ + public static class ValidationUtil extends cn.hutool.extra.validation.ValidationUtil { + } + + /** + * Excel工作簿相关工具类 + * + * @author looly + * @since 4.0.7 + * + */ + public static class WorkbookUtil extends cn.hutool.poi.excel.WorkbookUtil { + } + + /** + * 拼音工具类,封装了TinyPinyin、JPinyin、Pinyin4j,通过SPI自动识别。 + * + * @author looly + */ + public static class PinyinUtil extends cn.hutool.extra.pinyin.PinyinUtil { + } + + /** + * 调用者。可以通过此类的方法获取调用者、多级调用者以及判断是否被调用 + * + * @author Looly + * @since 4.1.6 + */ + public static class CallerUtil extends cn.hutool.core.lang.caller.CallerUtil { + } + + /** + * 定时任务表达式工具类 + * + * @author looly + * + */ + public static class CronPatternUtil extends cn.hutool.cron.pattern.CronPatternUtil { + } + + /** + * 系统运行时工具类,用于执行系统命令的工具 + * + * @author Looly + * @since 3.1.1 + */ + public static class RuntimeUtil extends cn.hutool.core.util.RuntimeUtil { + } + + /** + * {@link TemporalAccessor} 工具类封装 + * + * @author looly + * @since 5.3.9 + */ + public static class TemporalAccessorUtil extends cn.hutool.core.date.TemporalAccessorUtil { + } + + /** + * 图形验证码工具 + * + * @author looly + * @since 3.1.2 + */ + public static class CaptchaUtil extends cn.hutool.captcha.CaptchaUtil { + } + + /** + * 反射工具类 + * + * @author Looly + * @since 3.0.9 + */ + public static class ReflectUtil extends cn.hutool.core.util.ReflectUtil { + } + + /** + * IPV4地址工具类 + * + * <p> + * pr自:https://gitee.com/loolly/hutool/pulls/161 + * </p> + * + * @author ZhuKun + * @since 5.4.1 + */ + public static class Ipv4Util extends cn.hutool.core.net.Ipv4Util { + } + + /** + * {@link Robot} 封装工具类,提供截屏等工具 + * + * @author looly + * @since 4.1.14 + */ + public static class RobotUtil extends cn.hutool.core.swing.RobotUtil { + } + + /** + * {@link Graphics}相关工具类 + * + * @author looly + * @since 4.5.2 + */ + public static class GraphicsUtil extends cn.hutool.core.img.GraphicsUtil { + } + + /** + * Cglib工具类 + * + * @author looly + * @since 5.4.1 + */ + public static class CglibUtil extends cn.hutool.extra.cglib.CglibUtil { + } + + /** + * 转义和反转义工具类Escape / Unescape<br> + * escape采用ISO Latin字符集对指定的字符串进行编码。<br> + * 所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。 + * + * @author xiaoleilu + */ + public static class EscapeUtil extends cn.hutool.core.util.EscapeUtil { + } + + /** + * 诊断工具类 + * + * @author looly + * @since 5.5.2 + */ + public static class DiagnosticUtil extends cn.hutool.core.compiler.DiagnosticUtil { + } + + /** + * Excel中的行封装工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class RowUtil extends cn.hutool.poi.excel.RowUtil { + } + + /** + * 密钥工具类 + * + * <p> + * 包括: + * + * <pre> + * 1、生成密钥(单密钥、密钥对) + * 2、读取密钥文件 + * </pre> + * + * @author looly, Gsealy + * @since 4.4.1 + */ + public static class KeyUtil extends cn.hutool.crypto.KeyUtil { + } + + /** + * 基于Zxing的二维码工具类 + * + * @author looly + * @since 4.0.2 + */ + public static class QrCodeUtil extends cn.hutool.extra.qrcode.QrCodeUtil { + } + + /** + * SQL相关工具类,包括相关SQL语句拼接等 + * + * @author looly + * @since 4.0.10 + */ + public static class SqlUtil extends cn.hutool.db.sql.SqlUtil { + } + + /** + * Excel工具类,不建议直接使用index直接操作sheet,在wps/excel中sheet显示顺序与index无关,还有隐藏sheet + * + * @author Looly + * + */ + public static class ExcelUtil extends cn.hutool.poi.excel.ExcelUtil { + } + + /** + * 缓存工具类 + * + * @author Looly + * @since 3.0.1 + */ + public static class CacheUtil extends cn.hutool.cache.CacheUtil { + } + + /** + * Word工具类 + * + * @author Looly + * @since 4.5.16 + */ + public static class WordUtil extends cn.hutool.poi.word.WordUtil { + } + + /** + * 注解工具类<br> + * 快速获取注解对象、注解值等工具封装 + * + * @author looly + * @since 4.0.9 + */ + public static class AnnotationUtil extends cn.hutool.core.annotation.AnnotationUtil { + } + + /** + * Excel图片工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class ExcelPicUtil extends cn.hutool.poi.excel.ExcelPicUtil { + } + + /** + * 屏幕相关(当前显示设置)工具类 + * + * @author looly + * @since 4.1.14 + */ + public static class ScreenUtil extends cn.hutool.core.swing.ScreenUtil { + } + + /** + * 文件工具类 + * + * @author looly + */ + public static class FileUtil extends cn.hutool.core.io.FileUtil { + } + + /** + * Word Document工具 + * + * @author looly + * @since 4.4.1 + */ + public static class DocUtil extends cn.hutool.poi.word.DocUtil { + } + + /** + * 比较工具类 + * + * @author looly + */ + public static class CompareUtil extends cn.hutool.core.comparator.CompareUtil { + } + + /** + * Boolean类型相关工具类 + * + * @author looly + * @since 4.1.16 + */ + public static class BooleanUtil extends cn.hutool.core.util.BooleanUtil { + } + + /** + * {@link Iterable} 和 {@link Iterator} 相关工具类 + * + * @author Looly + * @since 3.1.0 + */ + public static class IterUtil extends cn.hutool.core.collection.IterUtil { + } + + /** + * 树工具类 + * + * @author liangbaikai + */ + public static class TreeUtil extends cn.hutool.core.lang.tree.TreeUtil { + } + + /** + * 身份证相关工具类<br> + * see https://www.oschina.net/code/snippet_1611_2881 + * + * <p> + * 本工具并没有对行政区划代码做校验,如有需求,请参阅(2018年10月): + * http://www.mca.gov.cn/article/sj/xzqh/2018/201804-12/20181011221630.html + * </p> + * + * @author Looly + * @since 3.0.4 + */ + public static class IdcardUtil extends cn.hutool.core.util.IdcardUtil { + } + + /** + * 字符工具类<br> + * 部分工具来自于Apache Commons系列 + * + * @author looly + * @since 4.0.1 + */ + public static class CharUtil extends cn.hutool.core.util.CharUtil { + } + + /** + * Socket相关工具类 + * + * @author looly + * @since 4.5.0 + */ + public static class SocketUtil extends cn.hutool.socket.SocketUtil { + } + + /** + * 手机号工具类 + * + * @author dahuoyzs + * @since 5.3.11 + */ + public static class PhoneUtil extends cn.hutool.core.util.PhoneUtil { + } + + /** + * 模板工具类 + * + * @author looly + * @since 4.1.0 + */ + public static class TemplateUtil extends cn.hutool.extra.template.TemplateUtil { + } + + /** + * 集合相关工具类 + * <p> + * 此工具方法针对{@link Collection}及其实现类封装的工具。 + * <p> + * 由于{@link Collection} 实现了{@link Iterable}接口,因此部分工具此类不提供,而是在{@link IterUtil} + * 中提供 + * + * @author xiaoleilu + * @see IterUtil + * @since 3.1.1 + */ + public static class CollUtil extends cn.hutool.core.collection.CollUtil { + } + + /** + * {@link JavaFileObject} 相关工具类封装 + * + * @author lzpeng, looly + * @since 5.5.2 + */ + public static class JavaFileObjectUtil extends cn.hutool.core.compiler.JavaFileObjectUtil { + } + + /** + * 数组工具类 + * + * @author Looly + */ + public static class ArrayUtil extends cn.hutool.core.util.ArrayUtil { + } + + /** + * SSL(Secure Sockets Layer 安全套接字协议)相关工具封装 + * + * @author looly + * @since 5.5.2 + */ + public static class SSLUtil extends cn.hutool.core.net.SSLUtil { + } + + /** + * 集合相关工具类,包括数组,是{@link CollUtil} 的别名工具类类 + * + * @author xiaoleilu + * @see CollUtil + */ + public static class CollectionUtil extends cn.hutool.core.collection.CollectionUtil { + } + + /** + * Excel表格中单元格工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class CellUtil extends cn.hutool.poi.excel.cell.CellUtil { + } + + /** + * 字符集工具类 + * + * @author xiaoleilu + */ + public static class CharsetUtil extends cn.hutool.core.util.CharsetUtil { + } + + /** + * 字符串工具类 + * + * @author xiaoleilu + */ + public static class StrUtil extends cn.hutool.core.util.StrUtil { + + /** + * 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。<br> + * 例如:hello_world=》helloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @param symbol 连接符 + * @return 转换后的驼峰式命名的字符串 + */ + public static String toCamelCase(CharSequence name, char symbol) { + if (null == name) { + return null; + } + String symbolStr = symbol + ""; + String name2 = name.toString(); + if (name2.contains(symbolStr)) { + final StringBuilder sb = new StringBuilder(name2.length()); + boolean upperCase = false; + for (int i = 0; i < name2.length(); i++) { + char c = name2.charAt(i); + + if (c == symbol) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(Character.toLowerCase(c)); + } + } + return sb.toString(); + } else { + return name2; + } + } + + private static final String[] LIKE_SPECIAL_CHAR = { "%", "_" }; + + /** + * 转义 msyql like 特殊字符 + * + * @param cs + * @return + */ + public static String likeEscape(String cs) { + if (StrUtil.isBlank(cs)) { + return null; + } + cs = StrUtil.replace(cs, "\\", "\\\\"); + for (String s : LIKE_SPECIAL_CHAR) { + cs = StrUtil.replace(cs, s, "\\" + s); + } + return cs; + } + + } + + /** + * Map相关工具类 + * + * @author Looly + * @since 3.1.1 + */ + public static class MapUtil extends cn.hutool.core.map.MapUtil { + } + + /** + * SPI机制中的服务加载工具类,流程如下 + * + * <pre> + * 1、创建接口,并创建实现类 + * 2、ClassPath/META-INF/services下创建与接口全限定类名相同的文件 + * 3、文件内容填写实现类的全限定类名 + * </pre> + * + * 相关介绍见:https://www.jianshu.com/p/3a3edbcd8f24 + * + * @author looly + * @since 5.1.6 + */ + public static class ServiceLoaderUtil extends cn.hutool.core.util.ServiceLoaderUtil { + } + + /** + * 随机工具类 + * + * @author xiaoleilu + */ + public static class RandomUtil extends cn.hutool.core.util.RandomUtil { + } + + public static class ListUtil extends cn.hutool.core.collection.ListUtil { + } + + /** + * Resource资源工具类 + * + * @author Looly + * + */ + public static class ResourceUtil extends cn.hutool.core.io.resource.ResourceUtil { + } + + /** + * AWT中字体相关工具类 + * + * @author looly + * @since 5.3.6 + */ + public static class FontUtil extends cn.hutool.core.img.FontUtil { + } + + /** + * CSV工具 + * + * @author looly + * @since 4.0.5 + */ + public static class CsvUtil extends cn.hutool.core.text.csv.CsvUtil { + } + + /** + * Word中表格相关工具 + * + * @author Looly + * @since 4.5.14 + */ + public static class TableUtil extends cn.hutool.poi.word.TableUtil { + } + + /** + * 原始类型数组工具类 + * + * @author looly + * @since 5.5.2 + */ + public static class PrimitiveArrayUtil extends cn.hutool.core.util.PrimitiveArrayUtil { + } + + public static class AesUtil { + + private static final String KEY_ALGORITHM = "AES"; + private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";// 默认的加密算法 + + public static String encrypt(String content, byte[] key) { + try { + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器 + + byte[] byteContent = content.getBytes("utf-8"); + + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器 + + byte[] result = cipher.doFinal(byteContent);// 加密 + + return cn.hutool.core.util.HexUtil.encodeHexStr(result); + } catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static String decrypt(String content, byte[] key) { + + try { + // 实例化 + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); + + // 使用密钥初始化,设置为解密模式 + cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key)); + + // 执行操作 + byte[] result = cipher.doFinal(cn.hutool.core.util.HexUtil.decodeHex(content)); + String s = new String(result, "utf-8"); + return s; + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + private static SecretKeySpec getSecretKey(byte[] key) { + // 返回生成指定算法密钥生成器的 KeyGenerator 对象 + KeyGenerator kg = null; + try { + kg = KeyGenerator.getInstance(KEY_ALGORITHM); + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + random.setSeed(key); + // AES 要求密钥长度为 128 + kg.init(128, random); + // 生成一个密钥 + SecretKey secretKey = kg.generateKey(); + return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥 + } catch (NoSuchAlgorithmException ex) { + ex.printStackTrace(); + } + return null; + } + + } + +} diff --git a/src/main/java/net/geedge/ws/VncClient.java b/src/main/java/net/geedge/ws/VncClient.java new file mode 100644 index 0000000..ffb829f --- /dev/null +++ b/src/main/java/net/geedge/ws/VncClient.java @@ -0,0 +1,40 @@ +package net.geedge.ws; + +import java.net.URI; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; + +public class VncClient extends WebSocketClient{ + + public VncClient(URI serverUri) { + super(serverUri); + // TODO Auto-generated constructor stub + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + // TODO Auto-generated method stub + + } + + @Override + public void onMessage(String message) { + // TODO Auto-generated method stub + + } + + @Override + public void onClose(int code, String reason, boolean remote) { + // TODO Auto-generated method stub + + } + + @Override + public void onError(Exception ex) { + // TODO Auto-generated method stub + + } + + +} diff --git a/src/main/resources/runner.yml b/src/main/resources/runner.yml new file mode 100644 index 0000000..b045ceb --- /dev/null +++ b/src/main/resources/runner.yml @@ -0,0 +1,11 @@ +register: + url: http://asw.geedge.net + token: T_kahaafa +executors: + - type: local + platform: android + concurrent: 1 + - type: docker + platform: android + image: docker-android/docker-android:v11 + concurrent: 2
\ No newline at end of file diff --git a/src/test/java/net/geedge/test/ConfigTest.java b/src/test/java/net/geedge/test/ConfigTest.java new file mode 100644 index 0000000..39af25d --- /dev/null +++ b/src/test/java/net/geedge/test/ConfigTest.java @@ -0,0 +1,29 @@ +package net.geedge.test; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import cn.hutool.core.lang.Dict; +import cn.hutool.setting.yaml.YamlUtil; +import net.geedge.util.RunnerYml; +import net.geedge.util.T; + +public class ConfigTest { + + @Test + public void loadConfig() { + Dict dict = YamlUtil.load(T.FileUtil.getUtf8Reader("./runner.yml")); + RunnerYml runnerYml = T.BeanUtil.copyProperties(dict, RunnerYml.class); + String url = runnerYml.getRegister().getUrl(); + assertEquals(url, "http://asw.geedge.net"); + System.out.println(T.JSONUtil.toJsonStr(runnerYml)); + } + + @Test + public void testClassPath() { + String classPath = T.ClassUtil.getClassPath(); + System.out.println(classPath); + } + +} diff --git a/src/test/resources/runner.yml b/src/test/resources/runner.yml new file mode 100644 index 0000000..b045ceb --- /dev/null +++ b/src/test/resources/runner.yml @@ -0,0 +1,11 @@ +register: + url: http://asw.geedge.net + token: T_kahaafa +executors: + - type: local + platform: android + concurrent: 1 + - type: docker + platform: android + image: docker-android/docker-android:v11 + concurrent: 2
\ No newline at end of file |
