From f173f255354e2d7dd94750779a95de8e0ab40b34 Mon Sep 17 00:00:00 2001 From: smallchill Date: Mon, 24 Dec 2018 11:58:45 +0800 Subject: [PATCH] :tada: Initial commit. --- .editorconfig | 21 + .gitignore | 27 + LICENSE | 64 + README.md | 59 + blade-core-boot/pom.xml | 122 ++ .../config/BladeBootAutoConfiguration.java | 75 + .../boot/config/BladeWebMvcConfiguration.java | 59 + .../boot/config/MybatisPlusConfiguration.java | 55 + .../core/boot/config/RetryConfiguration.java | 46 + .../core/boot/ctrl/BladeController.java | 209 +++ .../BladeFeignRequestHeaderInterceptor.java | 57 + .../FeignHystrixConcurrencyStrategy.java | 131 ++ .../springblade/core/boot/file/BladeFile.java | 171 ++ .../core/boot/file/BladeFileProxyFactory.java | 91 + .../core/boot/file/BladeFileUtil.java | 200 +++ .../springblade/core/boot/file/FileMaker.java | 209 +++ .../core/boot/file/FileProxyManager.java | 45 + .../core/boot/file/IFileProxy.java | 43 + .../core/boot/logger/RequestLogAspect.java | 132 ++ .../springblade/core/boot/node/BaseNode.java | 35 + .../core/boot/node/ForestNode.java | 37 + .../core/boot/node/ForestNodeManager.java | 62 + .../core/boot/node/ForestNodeMerger.java | 45 + .../org/springblade/core/boot/node/INode.java | 33 + .../springblade/core/boot/node/NodeTest.java | 34 + .../boot/resolver/TokenArgumentResolver.java | 63 + .../META-INF/spring-devtools.properties | 1 + .../main/resources/META-INF/spring.factories | 6 + blade-core-boot/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 87 + .../src/main/resources/config/ehcache.xml | 69 + .../src/main/resources/log/logback_dev.xml | 81 + .../src/main/resources/log/logback_prod.xml | 89 + .../src/main/resources/log/logback_test.xml | 89 + .../src/main/resources/static/favicon.ico | Bin 0 -> 67646 bytes blade-core-launch/pom.xml | 36 + .../core/launch/BladeApplication.java | 109 ++ .../core/launch/BladeLineRunner.java | 32 + .../core/launch/StartEventListener.java | 29 + ...adeConsulServiceRegistryConfiguration.java | 52 + .../config/BladeLaunchConfiguration.java | 50 + .../core/launch/constant/AppConstant.java | 146 ++ .../consul/BladeConsulServiceRegistry.java | 44 + .../launch/consul/ConsulLauncherService.java | 24 + .../core/launch/props/BladeProperties.java | 210 +++ .../core/launch/server/ServerInfo.java | 62 + .../core/launch/service/LauncherService.java | 33 + ...gblade.core.launch.service.LauncherService | 1 + .../spring-configuration-metadata.json | 37 + .../META-INF/spring-devtools.properties | 1 + .../main/resources/META-INF/spring.factories | 4 + blade-core-log/pom.xml | 43 + .../core/log/annotation/ApiLog.java | 35 + .../core/log/aspect/ApiLogAspect.java | 50 + .../BladeErrorMvcAutoConfiguration.java | 63 + .../config/BladeLogToolAutoConfiguration.java | 69 + .../core/log/constant/EventConstant.java | 32 + .../core/log/error/BladeErrorAttributes.java | 59 + .../core/log/error/BladeErrorController.java | 51 + .../error/BladeRestExceptionTranslator.java | 160 ++ .../core/log/event/ApiLogEvent.java | 32 + .../core/log/event/ApiLogListener.java | 73 + .../core/log/event/BladeLogEvent.java | 32 + .../core/log/event/BladeLogListener.java | 70 + .../core/log/event/ErrorLogEvent.java | 32 + .../core/log/event/ErrorLogListener.java | 68 + .../core/log/exception/ServiceException.java | 60 + .../core/log/feign/ILogClient.java | 64 + .../core/log/logger/BladeLogger.java | 53 + .../springblade/core/log/model/LogApi.java | 121 ++ .../springblade/core/log/model/LogBlade.java | 103 ++ .../springblade/core/log/model/LogError.java | 118 ++ .../core/log/publisher/ApiLogPublisher.java | 50 + .../core/log/publisher/BladeLogPublisher.java | 46 + .../core/log/publisher/ErrorLogPublisher.java | 56 + .../META-INF/spring-devtools.properties | 1 + .../main/resources/META-INF/spring.factories | 4 + blade-core-mybatis/pom.xml | 33 + .../core/mp/BladeMetaObjectHandler.java | 38 + .../springblade/core/mp/base/BaseEntity.java | 78 + .../springblade/core/mp/base/BaseService.java | 32 + .../core/mp/base/BaseServiceImpl.java | 83 + .../core/mp/support/BaseEntityWrapper.java | 38 + .../core/mp/support/Condition.java | 74 + .../springblade/core/mp/support/Query.java | 53 + blade-core-secure/pom.xml | 33 + .../org/springblade/core/secure/AuthInfo.java | 42 + .../springblade/core/secure/BladeUser.java | 52 + .../core/secure/annotation/PreAuth.java | 40 + .../core/secure/aspect/AuthAspect.java | 118 ++ .../springblade/core/secure/auth/AuthFun.java | 75 + .../secure/config/RegistryConfiguration.java | 38 + .../secure/config/SecureConfiguration.java | 50 + .../secure/exception/SecureException.java | 50 + .../secure/interceptor/SecureInterceptor.java | 58 + .../core/secure/registry/SecureRegistry.java | 62 + .../core/secure/utils/SecureUtil.java | 184 +++ .../META-INF/spring-devtools.properties | 1 + .../main/resources/META-INF/spring.factories | 3 + blade-core-swagger/pom.xml | 49 + .../swagger/SwaggerAutoConfiguration.java | 134 ++ .../core/swagger/SwaggerProperties.java | 139 ++ .../spring-configuration-metadata.json | 136 ++ .../main/resources/META-INF/spring.factories | 2 + blade-core-tool/pom.xml | 77 + .../core/tool/api/IResultCode.java | 29 + .../java/org/springblade/core/tool/api/R.java | 188 +++ .../springblade/core/tool/api/ResultCode.java | 105 ++ .../tool/config/JacksonConfiguration.java | 73 + .../tool/config/MessageConfiguration.java | 70 + .../core/tool/config/ToolConfiguration.java | 39 + .../core/tool/constant/BladeConstant.java | 83 + .../core/tool/constant/RoleConstant.java | 35 + .../core/tool/constant/SystemConstant.java | 100 ++ .../core/tool/date/BetweenFormater.java | 157 ++ .../core/tool/date/ConcurrentDateFormat.java | 70 + .../core/tool/date/DateBetween.java | 153 ++ .../core/tool/date/DateException.java | 31 + .../springblade/core/tool/date/DateField.java | 130 ++ .../core/tool/date/DatePattern.java | 71 + .../springblade/core/tool/date/DateTime.java | 753 +++++++++ .../springblade/core/tool/date/DateUnit.java | 33 + .../springblade/core/tool/date/DateUtil.java | 1471 +++++++++++++++++ .../org/springblade/core/tool/date/Month.java | 118 ++ .../springblade/core/tool/date/Season.java | 61 + .../core/tool/date/SystemClock.java | 94 ++ .../core/tool/date/TimeInterval.java | 109 ++ .../org/springblade/core/tool/date/Week.java | 120 ++ .../tool/date/format/AbstractDateBasic.java | 64 + .../core/tool/date/format/DateBasic.java | 33 + .../core/tool/date/format/DateParser.java | 68 + .../core/tool/date/format/DatePrinter.java | 78 + .../core/tool/date/format/FastDateFormat.java | 392 +++++ .../core/tool/date/format/FastDateParser.java | 822 +++++++++ .../tool/date/format/FastDatePrinter.java | 1320 +++++++++++++++ .../core/tool/date/format/FormatCache.java | 252 +++ ...ReadWriteJackson2HttpMessageConverter.java | 141 ++ .../jackson/BladeBeanSerializerModifier.java | 122 ++ .../tool/jackson/BladeJavaTimeModule.java | 49 + .../core/tool/jackson/JsonUtil.java | 328 ++++ ...appingApiJackson2HttpMessageConverter.java | 99 ++ .../core/tool/support/BeanProperty.java | 14 + .../springblade/core/tool/support/CMap.java | 198 +++ .../tool/support/CaseInsensitiveHashMap.java | 68 + .../core/tool/support/FastStringWriter.java | 103 ++ .../core/tool/support/IMultiOutputStream.java | 33 + .../core/tool/support/ImagePosition.java | 124 ++ .../core/tool/support/StrFormatter.java | 67 + .../core/tool/support/StrSpliter.java | 499 ++++++ .../springblade/core/tool/support/Try.java | 29 + .../core/tool/support/xss/HTMLFilter.java | 554 +++++++ .../core/tool/support/xss/SQLFilter.java | 56 + .../core/tool/support/xss/XssFilter.java | 49 + .../xss/XssHttpServletRequestWrapper.java | 174 ++ .../springblade/core/tool/utils/AESUtil.java | 126 ++ .../core/tool/utils/Base64Util.java | 114 ++ .../springblade/core/tool/utils/BeanUtil.java | 200 +++ .../springblade/core/tool/utils/Charsets.java | 50 + .../core/tool/utils/ClassUtil.java | 104 ++ .../core/tool/utils/CollectionUtil.java | 75 + .../core/tool/utils/DateTimeUtil.java | 117 ++ .../core/tool/utils/DigestUtil.java | 116 ++ .../core/tool/utils/Exceptions.java | 79 + .../org/springblade/core/tool/utils/Func.java | 1412 ++++++++++++++++ .../springblade/core/tool/utils/IOUtil.java | 100 ++ .../core/tool/utils/ImageUtil.java | 428 +++++ .../org/springblade/core/tool/utils/Lazy.java | 69 + .../core/tool/utils/NumberUtil.java | 208 +++ .../core/tool/utils/OKHttpUtil.java | 191 +++ .../core/tool/utils/ObjectUtil.java | 34 + .../springblade/core/tool/utils/PathUtil.java | 70 + .../core/tool/utils/ProtostuffUtil.java | 90 + .../core/tool/utils/RandomType.java | 28 + .../core/tool/utils/RegexUtil.java | 112 ++ .../core/tool/utils/ResourceUtil.java | 69 + .../core/tool/utils/SpringUtil.java | 67 + .../core/tool/utils/StringPool.java | 81 + .../core/tool/utils/StringUtil.java | 1336 +++++++++++++++ .../core/tool/utils/SuffixFileFilter.java | 59 + .../springblade/core/tool/utils/URLUtil.java | 66 + .../springblade/core/tool/utils/WebUtil.java | 270 +++ .../springblade/core/tool/utils/XmlUtil.java | 267 +++ .../META-INF/spring-devtools.properties | 1 + .../main/resources/META-INF/spring.factories | 4 + pic/jx.png | Bin 0 -> 73163 bytes pic/springblade-admin1.png | Bin 0 -> 96045 bytes pic/springblade-admin2.png | Bin 0 -> 53720 bytes pic/springblade-consul-nodes1.png | Bin 0 -> 46542 bytes pic/springblade-consul-nodes2.png | Bin 0 -> 45919 bytes pic/springblade-consul.png | Bin 0 -> 52536 bytes pic/springblade-harbor.png | Bin 0 -> 57542 bytes pic/springblade-k8s.png | Bin 0 -> 31817 bytes pic/springblade-swagger1.png | Bin 0 -> 76370 bytes pic/springblade-swagger2.png | Bin 0 -> 82357 bytes pic/springblade-traefik-health.png | Bin 0 -> 53756 bytes pic/springblade-traefik.png | Bin 0 -> 99762 bytes pic/sword-dict.png | Bin 0 -> 70569 bytes pic/sword-locale-cn.png | Bin 0 -> 116794 bytes pic/sword-locale-us.png | Bin 0 -> 109096 bytes pic/sword-log.png | Bin 0 -> 91205 bytes pic/sword-menu-edit.png | Bin 0 -> 73355 bytes pic/sword-menu-icon.png | Bin 0 -> 87481 bytes pic/sword-menu.png | Bin 0 -> 95498 bytes pic/sword-role.png | Bin 0 -> 89396 bytes pic/sword-user.png | Bin 0 -> 76295 bytes pom.xml | 204 +++ 206 files changed, 22720 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 blade-core-boot/pom.xml create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeBootAutoConfiguration.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeWebMvcConfiguration.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/config/MybatisPlusConfiguration.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/config/RetryConfiguration.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/ctrl/BladeController.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/feign/BladeFeignRequestHeaderInterceptor.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/feign/FeignHystrixConcurrencyStrategy.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFile.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileProxyFactory.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileUtil.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/FileMaker.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/FileProxyManager.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/file/IFileProxy.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/logger/RequestLogAspect.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/BaseNode.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNode.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeManager.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeMerger.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/INode.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/node/NodeTest.java create mode 100644 blade-core-boot/src/main/java/org/springblade/core/boot/resolver/TokenArgumentResolver.java create mode 100644 blade-core-boot/src/main/resources/META-INF/spring-devtools.properties create mode 100644 blade-core-boot/src/main/resources/META-INF/spring.factories create mode 100644 blade-core-boot/src/main/resources/banner.txt create mode 100644 blade-core-boot/src/main/resources/bootstrap.yml create mode 100644 blade-core-boot/src/main/resources/config/ehcache.xml create mode 100644 blade-core-boot/src/main/resources/log/logback_dev.xml create mode 100644 blade-core-boot/src/main/resources/log/logback_prod.xml create mode 100644 blade-core-boot/src/main/resources/log/logback_test.xml create mode 100644 blade-core-boot/src/main/resources/static/favicon.ico create mode 100644 blade-core-launch/pom.xml create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/BladeLineRunner.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/StartEventListener.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeConsulServiceRegistryConfiguration.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeLaunchConfiguration.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/constant/AppConstant.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/consul/BladeConsulServiceRegistry.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/consul/ConsulLauncherService.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/props/BladeProperties.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/server/ServerInfo.java create mode 100644 blade-core-launch/src/main/java/org/springblade/core/launch/service/LauncherService.java create mode 100644 blade-core-launch/src/main/resources/META-INF/services/org.springblade.core.launch.service.LauncherService create mode 100644 blade-core-launch/src/main/resources/META-INF/spring-configuration-metadata.json create mode 100644 blade-core-launch/src/main/resources/META-INF/spring-devtools.properties create mode 100644 blade-core-launch/src/main/resources/META-INF/spring.factories create mode 100644 blade-core-log/pom.xml create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/annotation/ApiLog.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/aspect/ApiLogAspect.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/config/BladeErrorMvcAutoConfiguration.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/config/BladeLogToolAutoConfiguration.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/constant/EventConstant.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorAttributes.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorController.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/error/BladeRestExceptionTranslator.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogEvent.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogListener.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogEvent.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogListener.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogEvent.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogListener.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/exception/ServiceException.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/feign/ILogClient.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/logger/BladeLogger.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/model/LogApi.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/model/LogBlade.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/model/LogError.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/publisher/ApiLogPublisher.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/publisher/BladeLogPublisher.java create mode 100644 blade-core-log/src/main/java/org/springblade/core/log/publisher/ErrorLogPublisher.java create mode 100644 blade-core-log/src/main/resources/META-INF/spring-devtools.properties create mode 100644 blade-core-log/src/main/resources/META-INF/spring.factories create mode 100644 blade-core-mybatis/pom.xml create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/BladeMetaObjectHandler.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseEntity.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseService.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseServiceImpl.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/support/BaseEntityWrapper.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Condition.java create mode 100644 blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Query.java create mode 100644 blade-core-secure/pom.xml create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/AuthInfo.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/BladeUser.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/annotation/PreAuth.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/aspect/AuthAspect.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/auth/AuthFun.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/config/RegistryConfiguration.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/exception/SecureException.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/interceptor/SecureInterceptor.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/registry/SecureRegistry.java create mode 100644 blade-core-secure/src/main/java/org/springblade/core/secure/utils/SecureUtil.java create mode 100644 blade-core-secure/src/main/resources/META-INF/spring-devtools.properties create mode 100644 blade-core-secure/src/main/resources/META-INF/spring.factories create mode 100644 blade-core-swagger/pom.xml create mode 100644 blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerAutoConfiguration.java create mode 100644 blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerProperties.java create mode 100644 blade-core-swagger/src/main/resources/META-INF/spring-configuration-metadata.json create mode 100644 blade-core-swagger/src/main/resources/META-INF/spring.factories create mode 100644 blade-core-tool/pom.xml create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/api/IResultCode.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/api/R.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/api/ResultCode.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/config/JacksonConfiguration.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/config/MessageConfiguration.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/config/ToolConfiguration.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/constant/BladeConstant.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/constant/RoleConstant.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/constant/SystemConstant.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/BetweenFormater.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/ConcurrentDateFormat.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateBetween.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateException.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateField.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DatePattern.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateTime.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUnit.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/Month.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/Season.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/SystemClock.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/TimeInterval.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/Week.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/AbstractDateBasic.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateBasic.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateParser.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DatePrinter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateFormat.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateParser.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDatePrinter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FormatCache.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/jackson/AbstractReadWriteJackson2HttpMessageConverter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeBeanSerializerModifier.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeJavaTimeModule.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/jackson/JsonUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/jackson/MappingApiJackson2HttpMessageConverter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/BeanProperty.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/CMap.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/CaseInsensitiveHashMap.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/FastStringWriter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/IMultiOutputStream.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/ImagePosition.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/StrFormatter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/StrSpliter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/Try.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/HTMLFilter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/SQLFilter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssFilter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssHttpServletRequestWrapper.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/AESUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/Base64Util.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/BeanUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/Charsets.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/ClassUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/CollectionUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/DateTimeUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/DigestUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/Exceptions.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/Func.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/IOUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/ImageUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/Lazy.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/NumberUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/OKHttpUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/ObjectUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/PathUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/ProtostuffUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/RandomType.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/RegexUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/ResourceUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/SpringUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringPool.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/SuffixFileFilter.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/URLUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/WebUtil.java create mode 100644 blade-core-tool/src/main/java/org/springblade/core/tool/utils/XmlUtil.java create mode 100644 blade-core-tool/src/main/resources/META-INF/spring-devtools.properties create mode 100644 blade-core-tool/src/main/resources/META-INF/spring.factories create mode 100644 pic/jx.png create mode 100644 pic/springblade-admin1.png create mode 100644 pic/springblade-admin2.png create mode 100644 pic/springblade-consul-nodes1.png create mode 100644 pic/springblade-consul-nodes2.png create mode 100644 pic/springblade-consul.png create mode 100644 pic/springblade-harbor.png create mode 100644 pic/springblade-k8s.png create mode 100644 pic/springblade-swagger1.png create mode 100644 pic/springblade-swagger2.png create mode 100644 pic/springblade-traefik-health.png create mode 100644 pic/springblade-traefik.png create mode 100644 pic/sword-dict.png create mode 100644 pic/sword-locale-cn.png create mode 100644 pic/sword-locale-us.png create mode 100644 pic/sword-log.png create mode 100644 pic/sword-menu-edit.png create mode 100644 pic/sword-menu-icon.png create mode 100644 pic/sword-menu.png create mode 100644 pic/sword-role.png create mode 100644 pic/sword-user.png create mode 100644 pom.xml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8cfd370 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# http://editorconfig.org +root = true + +# 空格替代Tab缩进在各种编辑工具下效果一致 +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.java] +indent_style = tab + +[*.{json,yml}] +indent_size = 2 + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..987273c --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# maven # +target + +logs + +# windows # +Thumbs.db + +# Mac # +.DS_Store + +# eclipse # +.settings +.project +.classpath +.log +*.class + +# idea # +.idea +*.iml + +# Package Files # +*.jar +*.war +*.ear +/target diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bed53b8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,64 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + +As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License. + +“The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. + +An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. + +A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”. + +The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. + +The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: + +a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or +b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. +3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: + +a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. +b) Accompany the object code with a copy of the GNU GPL and this license document. +4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: + +a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. +b) Accompany the Combined Work with a copy of the GNU GPL and this license document. +c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. +d) Do one of the following: +0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. +1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. +e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) +5. Combined Libraries. + +You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: + +a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. +b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. +6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4c77853 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +## 简介 +blade-tool 是如梦技术团队作品, 是一个基于 Spring Boot 2 & Spring Cloud Finchley ,封装组合大量组件,用于快速构建中大型API、RESTful API项目的核心包。 + +注意事项 +* 注册中心为 Consul +* 基于 SpringBoot2.x 版本 以及 SpringCloud Finchley 版本 + +技术选型&文档 +* Spring Boot([查看Spring Boot学习&使用指南](http://www.jianshu.com/p/1a9fd8936bd8)) +* Spring Cloud([查看Spring Cloud学习&使用指南](https://springcloud.cc/)) +* Mybatis-Plus([查看官方文档](https://baomidou.gitee.io/mybatis-plus-doc/#/quick-start)) +* JsonWebToken([查看官方文档](https://jwt.io/)) + +## 鸣谢 +* 如梦技术([DreamLu](https://www.dreamlu.net/)) +* pigx([Pig Microservice](https://www.pig4cloud.com/zh-cn/)) +* avue([avue](https://avue.top/)) +* gitee.ltd([gitee.ltd](https://gitee.ltd/)) +* 鲸宵(鲸宵) + +## 开源协议 +LGPL([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html)) + +LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。 + +但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。 + +## 用户权益 +* 允许以引入不改源码的形式用于学习、毕设、公司项目、私活等 +* 特殊情况修改代码,但仍然想闭源需经过作者同意 + +## 禁止事项 +* 直接将本项目挂淘宝等商业平台出售。 + +* 非界面代码60%以上相识度的二次开源,二次开源需先联系本人。 + +注意:若禁止条款被发现有权追讨19999的授权费。 + +## 业务系统(开源协议为Apache License)界面一览(即将开源敬请期待) +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-k8s.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-traefik.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-traefik-health.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-harbor.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-consul.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-consul-nodes1.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-consul-nodes2.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-admin1.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-admin2.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-swagger1.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/springblade-swagger2.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-menu.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-menu-edit.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-menu-icon.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-role.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-user.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-dict.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-locale-cn.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-locale-us.png "业务系统") +![业务系统](https://raw.githubusercontent.com/chillzhuang/blade-tool/master/pic/sword-log.png "业务系统") \ No newline at end of file diff --git a/blade-core-boot/pom.xml b/blade-core-boot/pom.xml new file mode 100644 index 0000000..67b5149 --- /dev/null +++ b/blade-core-boot/pom.xml @@ -0,0 +1,122 @@ + + + + org.springblade + blade-tool + 1.0.0-RC1 + + + 4.0.0 + + blade-core-boot + ${project.artifactId} + ${blade.tool.version} + jar + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + tomcat-jdbc + org.apache.tomcat + + + + + org.springframework.boot + spring-boot-starter-cache + + + org.springframework.cloud + spring-cloud-starter-config + + + + org.springblade + blade-core-launch + ${blade.tool.version} + + + org.springblade + blade-core-tool + ${blade.tool.version} + + + org.springblade + blade-core-secure + ${blade.tool.version} + + + org.springblade + blade-core-log + ${blade.tool.version} + + + org.springblade + blade-core-swagger + ${blade.tool.version} + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.swagger + swagger-models + + + + + io.swagger + swagger-models + ${swagger.models.version} + + + com.github.xiaoymin + swagger-bootstrap-ui + ${swagger.bootstrapui.version} + + + + org.springblade + blade-core-mybatis + ${blade.tool.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis.plus.version} + + + org.mybatis + mybatis-typehandlers-jsr310 + 1.0.2 + + + + net.sf.ehcache + ehcache + 2.10.5 + + + + mysql + mysql-connector-java + runtime + + + + + + diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeBootAutoConfiguration.java b/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeBootAutoConfiguration.java new file mode 100644 index 0000000..9f83284 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeBootAutoConfiguration.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.config; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.tool.constant.SystemConstant; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +@Slf4j +@Configuration +@EnableConfigurationProperties({ + BladeProperties.class +}) +@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) +@AllArgsConstructor +public class BladeBootAutoConfiguration { + + private BladeProperties bladeProperties; + + /** + * 全局变量定义 + */ + @Bean + public SystemConstant fileConst() { + SystemConstant me = SystemConstant.me(); + + //设定开发模式 + me.setDevMode((bladeProperties.getEnv().equals("dev") ? true : false)); + + //设定文件上传远程地址 + me.setDomain(bladeProperties.get("upload-domain", "http://localhost:8888")); + + //设定文件上传是否为远程模式 + me.setRemoteMode(bladeProperties.getBoolean("remote-mode", true)); + + //远程上传地址 + me.setRemotePath(bladeProperties.get("remote-path", System.getProperty("user.dir") + "/work/blade")); + + //设定文件上传头文件夹 + me.setUploadPath(bladeProperties.get("upload-path", "/upload")); + + //设定文件下载头文件夹 + me.setDownloadPath(bladeProperties.get("download-path", "/download")); + + //设定上传图片是否压缩 + me.setCompress(bladeProperties.getBoolean("compress", false)); + + //设定上传图片压缩比例 + me.setCompressScale(bladeProperties.getDouble("compress-scale", 2.00)); + + //设定上传图片缩放选择:true放大;false缩小 + me.setCompressFlag(bladeProperties.getBoolean("compress-flag", false)); + + return me; + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeWebMvcConfiguration.java b/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeWebMvcConfiguration.java new file mode 100644 index 0000000..a903150 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/config/BladeWebMvcConfiguration.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.config; + +import feign.RequestInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.boot.feign.BladeFeignRequestHeaderInterceptor; +import org.springblade.core.boot.feign.FeignHystrixConcurrencyStrategy; +import org.springblade.core.boot.resolver.TokenArgumentResolver; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +/** + * WEB配置 + */ +@Slf4j +@Configuration +@EnableCaching +@Order(Ordered.HIGHEST_PRECEDENCE) +public class BladeWebMvcConfiguration implements WebMvcConfigurer { + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new TokenArgumentResolver()); + } + + @Bean + @ConditionalOnMissingBean + public RequestInterceptor requestInterceptor() { + return new BladeFeignRequestHeaderInterceptor(); + } + + @Bean + public FeignHystrixConcurrencyStrategy feignHystrixConcurrencyStrategy() { + return new FeignHystrixConcurrencyStrategy(); + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/config/MybatisPlusConfiguration.java b/blade-core-boot/src/main/java/org/springblade/core/boot/config/MybatisPlusConfiguration.java new file mode 100644 index 0000000..1ed3dce --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/config/MybatisPlusConfiguration.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springblade.core.mp.BladeMetaObjectHandler; +import org.springblade.core.launch.constant.AppConstant; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +/** + * mybatisplus 配置 + */ +@Configuration +@MapperScan("org.springblade.**.mapper.**") +public class MybatisPlusConfiguration { + + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + @Bean + public MetaObjectHandler metaObjectHandler() { + return new BladeMetaObjectHandler(); + } + + /** + * SQL执行效率插件 + */ + @Bean + @Profile({AppConstant.DEV_CDOE, AppConstant.TEST_CODE}) + public PerformanceInterceptor performanceInterceptor() { + return new PerformanceInterceptor(); + } + +} + diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/config/RetryConfiguration.java b/blade-core-boot/src/main/java/org/springblade/core/boot/config/RetryConfiguration.java new file mode 100644 index 0000000..bd825b5 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/config/RetryConfiguration.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.retry.interceptor.RetryInterceptorBuilder; +import org.springframework.retry.interceptor.RetryOperationsInterceptor; + +/** + * 重试机制 + */ +@Slf4j +@Configuration +public class RetryConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "configServerRetryInterceptor") + public RetryOperationsInterceptor configServerRetryInterceptor() { + log.info(String.format( + "configServerRetryInterceptor: Changing backOffOptions " + + "to initial: %s, multiplier: %s, maxInterval: %s", + 1000, 1.2, 5000)); + return RetryInterceptorBuilder + .stateless() + .backOffOptions(1000, 1.2, 5000) + .maxAttempts(10) + .build(); + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/ctrl/BladeController.java b/blade-core-boot/src/main/java/org/springblade/core/boot/ctrl/BladeController.java new file mode 100644 index 0000000..e4db3c0 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/ctrl/BladeController.java @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.ctrl; + +import org.springblade.core.boot.file.BladeFile; +import org.springblade.core.boot.file.BladeFileUtil; +import org.springblade.core.secure.BladeUser; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.tool.api.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.propertyeditors.CustomDateEditor; +import org.springframework.web.bind.ServletRequestDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * Blade控制器封装类 + */ +public class BladeController { + + /** + * ============================ BINDER ================================================= + */ + + @InitBinder + protected void initBinder(ServletRequestDataBinder binder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setLenient(false); + binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); + } + + /** + * ============================ REQUEST ================================================= + */ + + @Autowired + private HttpServletRequest request; + + /** + * 获取request + */ + public HttpServletRequest getRequest() { + return this.request; + } + + /** + * 获取当前用户 + * + * @return + */ + public BladeUser getUser() { + return SecureUtil.getUser(request); + } + + /** ============================ API_RESULT ================================================= */ + + /** + * 返回ApiResult + * + * @param data + * @return R + */ + public R data(T data) { + return R.data(data); + } + + /** + * 返回ApiResult + * + * @param data + * @param message + * @return R + */ + public R data(T data, String message) { + return R.data(data, message); + } + + /** + * 返回ApiResult + * + * @param data + * @param message + * @param code + * @return R + */ + public R data(T data, String message, int code) { + return R.data(code, data, message); + } + + /** + * 返回ApiResult + * + * @param message + * @return R + */ + public R success(String message) { + return R.success(message); + } + + /** + * 返回ApiResult + * + * @param message + * @return R + */ + public R failure(String message) { + return R.failure(message); + } + + /** + * 返回ApiResult + * + * @param flag + * @return R + */ + public R status(boolean flag) { + return R.status(flag); + } + + + /**============================ FILE ================================================= */ + + /** + * 获取BladeFile封装类 + * + * @param file + * @return + */ + public BladeFile getFile(MultipartFile file) { + return BladeFileUtil.getFile(file); + } + + /** + * 获取BladeFile封装类 + * + * @param file + * @param dir + * @return + */ + public BladeFile getFile(MultipartFile file, String dir) { + return BladeFileUtil.getFile(file, dir); + } + + /** + * 获取BladeFile封装类 + * + * @param file + * @param dir + * @param path + * @param virtualPath + * @return + */ + public BladeFile getFile(MultipartFile file, String dir, String path, String virtualPath) { + return BladeFileUtil.getFile(file, dir, path, virtualPath); + } + + /** + * 获取BladeFile封装类 + * + * @param files + * @return + */ + public List getFiles(List files) { + return BladeFileUtil.getFiles(files); + } + + /** + * 获取BladeFile封装类 + * + * @param files + * @param dir + * @return + */ + public List getFiles(List files, String dir) { + return BladeFileUtil.getFiles(files, dir); + } + + /** + * 获取BladeFile封装类 + * + * @param files + * @param path + * @param virtualPath + * @return + */ + public List getFiles(List files, String dir, String path, String virtualPath) { + return BladeFileUtil.getFiles(files, dir, path, virtualPath); + } + + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/feign/BladeFeignRequestHeaderInterceptor.java b/blade-core-boot/src/main/java/org/springblade/core/boot/feign/BladeFeignRequestHeaderInterceptor.java new file mode 100644 index 0000000..b1168df --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/feign/BladeFeignRequestHeaderInterceptor.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.feign; + +import feign.RequestInterceptor; +import feign.RequestTemplate; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; + +/** + * feign 传递Request header + */ +@Slf4j +public class BladeFeignRequestHeaderInterceptor implements RequestInterceptor { + + @Override + public void apply(RequestTemplate requestTemplate) { + ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attrs != null) { + HttpServletRequest request = attrs.getRequest(); + Enumeration headerNames = request.getHeaderNames(); + if (headerNames != null) { + while (headerNames.hasMoreElements()) { + String name = headerNames.nextElement(); + String value = request.getHeader(name); + /** + * 遍历请求头里面的属性字段,将Authorization添加到新的请求头中转发到下游服务 + * */ + if ("Authorization".equals(name)) { + log.debug("添加自定义请求头key:" + name + ",value:" + value); + requestTemplate.header(name, value); + } + } + } else { + log.warn("FeignHeadConfiguration", "获取请求头失败!"); + } + } + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/feign/FeignHystrixConcurrencyStrategy.java b/blade-core-boot/src/main/java/org/springblade/core/boot/feign/FeignHystrixConcurrencyStrategy.java new file mode 100644 index 0000000..5db1400 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/feign/FeignHystrixConcurrencyStrategy.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.feign; + +import com.netflix.hystrix.HystrixThreadPoolKey; +import com.netflix.hystrix.HystrixThreadPoolProperties; +import com.netflix.hystrix.strategy.HystrixPlugins; +import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; +import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; +import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; +import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; +import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; +import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; +import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; +import com.netflix.hystrix.strategy.properties.HystrixProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 自定义Feign的隔离策略 + */ +public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { + + private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategy.class); + private HystrixConcurrencyStrategy delegate; + + public FeignHystrixConcurrencyStrategy() { + try { + this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); + if (this.delegate instanceof FeignHystrixConcurrencyStrategy) { + // Welcome to singleton hell... + return; + } + HystrixCommandExecutionHook commandExecutionHook = + HystrixPlugins.getInstance().getCommandExecutionHook(); + HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); + HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher(); + HystrixPropertiesStrategy propertiesStrategy = + HystrixPlugins.getInstance().getPropertiesStrategy(); + this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy); + HystrixPlugins.reset(); + HystrixPlugins.getInstance().registerConcurrencyStrategy(this); + HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); + HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); + HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); + HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); + } catch (Exception e) { + log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e); + } + } + + private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier, + HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) { + if (log.isDebugEnabled()) { + log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy [" + + this.delegate + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher [" + + metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]"); + log.debug("Registering Sleuth Hystrix Concurrency Strategy."); + } + } + + @Override + public Callable wrapCallable(Callable callable) { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + return new WrappedCallable<>(callable, requestAttributes); + } + + @Override + public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, + HystrixProperty corePoolSize, HystrixProperty maximumPoolSize, + HystrixProperty keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { + return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, + unit, workQueue); + } + + @Override + public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, + HystrixThreadPoolProperties threadPoolProperties) { + return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties); + } + + @Override + public BlockingQueue getBlockingQueue(int maxQueueSize) { + return this.delegate.getBlockingQueue(maxQueueSize); + } + + @Override + public HystrixRequestVariable getRequestVariable(HystrixRequestVariableLifecycle rv) { + return this.delegate.getRequestVariable(rv); + } + + static class WrappedCallable implements Callable { + private final Callable target; + private final RequestAttributes requestAttributes; + + public WrappedCallable(Callable target, RequestAttributes requestAttributes) { + this.target = target; + this.requestAttributes = requestAttributes; + } + + @Override + public T call() throws Exception { + try { + RequestContextHolder.setRequestAttributes(requestAttributes); + return target.call(); + } finally { + RequestContextHolder.resetRequestAttributes(); + } + } + } +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFile.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFile.java new file mode 100644 index 0000000..429f242 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFile.java @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + +import org.springblade.core.tool.constant.SystemConstant; +import org.springblade.core.tool.date.DateUtil; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.Date; + +public class BladeFile { + /** + * 上传文件在附件表中的id + */ + private Object fileId; + + /** + * 上传文件 + */ + private MultipartFile file; + + /** + * 上传分类文件夹 + */ + private String dir; + + /** + * 上传物理路径 + */ + private String uploadPath; + + /** + * 上传虚拟路径 + */ + private String uploadVirtualPath; + + /** + * 文件名 + */ + private String fileName; + + /** + * 真实文件名 + */ + private String originalFileName; + + public BladeFile() { + + } + + public BladeFile(MultipartFile file, String dir) { + this.dir = dir; + this.file = file; + this.fileName = file.getName(); + this.originalFileName = file.getOriginalFilename(); + this.uploadPath = BladeFileUtil.formatUrl(File.separator + SystemConstant.me().getUploadRealPath() + File.separator + dir + File.separator + DateUtil.format(new Date(), "yyyyMMdd") + File.separator + this.originalFileName); + this.uploadVirtualPath = BladeFileUtil.formatUrl(SystemConstant.me().getUploadCtxPath().replace(SystemConstant.me().getContextPath(), "") + File.separator + dir + File.separator + DateUtil.format(new Date(), "yyyyMMdd") + File.separator + this.originalFileName); + } + + public BladeFile(MultipartFile file, String dir, String uploadPath, String uploadVirtualPath) { + this(file, dir); + if (null != uploadPath){ + this.uploadPath = BladeFileUtil.formatUrl(uploadPath); + this.uploadVirtualPath = BladeFileUtil.formatUrl(uploadVirtualPath); + } + } + + /** + * 图片上传 + */ + public void transfer() { + transfer(SystemConstant.me().isCompress()); + } + + /** + * 图片上传 + * @param compress 是否压缩 + */ + public void transfer(boolean compress) { + IFileProxy fileFactory = FileProxyManager.me().getDefaultFileProxyFactory(); + this.transfer(fileFactory, compress); + } + + /** + * 图片上传 + * @param fileFactory 文件上传工厂类 + * @param compress 是否压缩 + */ + public void transfer(IFileProxy fileFactory, boolean compress) { + try { + File file = new File(uploadPath); + + if(null != fileFactory){ + String [] path = fileFactory.path(file, dir); + this.uploadPath = path[0]; + this.uploadVirtualPath = path[1]; + file = fileFactory.rename(file, path[0]); + } + + File pfile = file.getParentFile(); + if (!pfile.exists()) { + pfile.mkdirs(); + } + + this.file.transferTo(file); + + if (compress) { + fileFactory.compress(this.uploadPath); + } + + } catch (IllegalStateException | IOException e) { + e.printStackTrace(); + } + } + + public MultipartFile getFile() { + return file; + } + + public void setFile(MultipartFile file) { + this.file = file; + } + + public String getUploadPath() { + return uploadPath; + } + + public void setUploadPath(String uploadPath) { + this.uploadPath = uploadPath; + } + + public String getUploadVirtualPath() { + return uploadVirtualPath; + } + + public void setUploadVirtualPath(String uploadVirtualPath) { + this.uploadVirtualPath = uploadVirtualPath; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getOriginalFileName() { + return originalFileName; + } + + public void setOriginalFileName(String originalFileName) { + this.originalFileName = originalFileName; + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileProxyFactory.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileProxyFactory.java new file mode 100644 index 0000000..2f5be0f --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileProxyFactory.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + +import org.springblade.core.tool.constant.SystemConstant; +import org.springblade.core.tool.date.DateUtil; +import org.springblade.core.tool.utils.ImageUtil; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.util.Date; + +public class BladeFileProxyFactory implements IFileProxy { + + @Override + public File rename(File f, String path) { + File dest = new File(path); + f.renameTo(dest); + return dest; + } + + @Override + public String [] path(File f, String dir) { + //避免网络延迟导致时间不同步 + long time = System.nanoTime(); + + StringBuilder uploadPath = new StringBuilder() + .append(getFileDir(dir, SystemConstant.me().getUploadRealPath())) + .append(time) + .append(getFileExt(f.getName())); + + StringBuilder virtualPath = new StringBuilder() + .append(getFileDir(dir, SystemConstant.me().getUploadCtxPath())) + .append(time) + .append(getFileExt(f.getName())); + + return new String [] {BladeFileUtil.formatUrl(uploadPath.toString()), BladeFileUtil.formatUrl(virtualPath.toString())}; + } + + /** + * 获取文件后缀 + */ + public static String getFileExt(String fileName) { + if (fileName.indexOf(".") == -1) + return ".jpg"; + else + return fileName.substring(fileName.lastIndexOf('.'), fileName.length()); + } + + /** + * 获取文件保存地址 + * @param saveDir + * @return + */ + public static String getFileDir(String dir, String saveDir) { + StringBuilder newFileDir = new StringBuilder(); + newFileDir.append(saveDir) + .append(File.separator).append(dir).append(File.separator).append(DateUtil.format(new Date(), "yyyyMMdd")) + .append(File.separator); + return newFileDir.toString(); + } + + + /** + * 图片压缩 + * @param path 文件地址 + * @return + */ + public void compress(String path) { + try { + ImageUtil.zoomScale(ImageUtil.readImage(path), new FileOutputStream(new File(path)), null, SystemConstant.me().getCompressScale(), SystemConstant.me().isCompressFlag()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileUtil.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileUtil.java new file mode 100644 index 0000000..e1aa2f2 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/BladeFileUtil.java @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + +import org.springblade.core.tool.utils.StringUtil; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; + +public class BladeFileUtil { + + // 定义允许上传的文件扩展名 + private static HashMap extMap = new HashMap(); + // 图片扩展名 + private static String[] fileTypes = new String[] { "gif", "jpg", "jpeg", "png", "bmp" }; + + static { + extMap.put("image", ".gif,.jpg,.jpeg,.png,.bmp,.JPG,.JPEG,.PNG"); + extMap.put("flash", ".swf,.flv"); + extMap.put("media", ".swf,.flv,.mp3,.mp4,.wav,.wma,.wmv,.mid,.avi,.mpg,.asf,.rm,.rmvb"); + extMap.put("file", ".doc,.docx,.xls,.xlsx,.ppt,.htm,.html,.txt,.zip,.rar,.gz,.bz2"); + extMap.put("allfile", ".gif,.jpg,.jpeg,.png,.bmp,.swf,.flv,.mp3,.mp4,.wav,.wma,.wmv,.mid,.avi,.mpg,.asf,.rm,.rmvb,.doc,.docx,.xls,.xlsx,.ppt,.htm,.html,.txt,.zip,.rar,.gz,.bz2"); + } + + /** + * 获取文件后缀 + * + * @param @param fileName + * @param @return 设定文件 + * @return String 返回类型 + */ + public static String getFileExt(String fileName) { + return fileName.substring(fileName.lastIndexOf('.'), fileName.length()); + } + + /** + * 测试文件后缀 只让指定后缀的文件上传,像jsp,war,sh等危险的后缀禁止 + * + * @return + */ + public static boolean testExt(String dir, String fileName) { + String fileExt = getFileExt(fileName); + + String ext = extMap.get(dir); + if (StringUtil.isBlank(ext) || ext.indexOf(fileExt) == -1) { + return false; + } + return true; + } + + /** + * 文件管理排序 + */ + public enum FileSort { + size, type, name; + + // 文本排序转换成枚举 + public static FileSort of(String sort) { + try { + return FileSort.valueOf(sort); + } catch (Exception e) { + return FileSort.name; + } + } + } + + public static class NameComparator implements Comparator { + public int compare(Object a, Object b) { + Hashtable hashA = (Hashtable) a; + Hashtable hashB = (Hashtable) b; + if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { + return -1; + } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { + return 1; + } else { + return ((String) hashA.get("filename")).compareTo((String) hashB.get("filename")); + } + } + } + + public static class SizeComparator implements Comparator { + public int compare(Object a, Object b) { + Hashtable hashA = (Hashtable) a; + Hashtable hashB = (Hashtable) b; + if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { + return -1; + } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { + return 1; + } else { + if (((Long) hashA.get("filesize")) > ((Long) hashB.get("filesize"))) { + return 1; + } else if (((Long) hashA.get("filesize")) < ((Long) hashB.get("filesize"))) { + return -1; + } else { + return 0; + } + } + } + } + + public static class TypeComparator implements Comparator { + public int compare(Object a, Object b) { + Hashtable hashA = (Hashtable) a; + Hashtable hashB = (Hashtable) b; + if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { + return -1; + } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { + return 1; + } else { + return ((String) hashA.get("filetype")).compareTo((String) hashB.get("filetype")); + } + } + } + + public static String formatUrl(String url) { + return url.replaceAll("\\\\", "/"); + } + + + /********************************BladeFile封装********************************************************/ + + /** + * 获取BladeFile封装类 + * @param file + * @return + */ + public static BladeFile getFile(MultipartFile file){ + return getFile(file, "image", null, null); + } + + /** + * 获取BladeFile封装类 + * @param file + * @param dir + * @return + */ + public static BladeFile getFile(MultipartFile file, String dir){ + return getFile(file, dir, null, null); + } + + /** + * 获取BladeFile封装类 + * @param file + * @param dir + * @param path + * @param virtualPath + * @return + */ + public static BladeFile getFile(MultipartFile file, String dir, String path, String virtualPath){ + return new BladeFile(file, dir, path, virtualPath); + } + + /** + * 获取BladeFile封装类 + * @param files + * @return + */ + public static List getFiles(List files){ + return getFiles(files, "image", null, null); + } + + /** + * 获取BladeFile封装类 + * @param files + * @param dir + * @return + */ + public static List getFiles(List files, String dir){ + return getFiles(files, dir, null, null); + } + + /** + * 获取BladeFile封装类 + * @param files + * @param path + * @param virtualPath + * @return + */ + public static List getFiles(List files, String dir, String path, String virtualPath){ + List list = new ArrayList<>(); + for (MultipartFile file : files){ + list.add(new BladeFile(file, dir, path, virtualPath)); + } + return list; + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileMaker.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileMaker.java new file mode 100644 index 0000000..81726ee --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileMaker.java @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + + +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.StringPool; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; + +public class FileMaker { + private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; + + private File file; + + private String fileName; + + private HttpServletRequest request; + + private HttpServletResponse response; + + public static FileMaker init(HttpServletRequest request, HttpServletResponse response, File file) { + return new FileMaker(request, response, file); + } + + public static FileMaker init(HttpServletRequest request, HttpServletResponse response, File file, String fileName) { + return new FileMaker(request, response, file, fileName); + } + + private FileMaker(HttpServletRequest request, HttpServletResponse response, File file) { + if (file == null) { + throw new IllegalArgumentException("file can not be null."); + } + this.file = file; + this.request = request; + this.response = response; + this.fileName = file.getName(); + } + + private FileMaker(HttpServletRequest request, HttpServletResponse response, File file, String fileName) { + if (file == null) { + throw new IllegalArgumentException("file can not be null."); + } + this.file = file; + this.request = request; + this.response = response; + this.fileName = fileName; + } + + public void start() { + if (file == null || !file.isFile()) { + throw new RuntimeException(); + } + + // --------- + response.setHeader("Accept-Ranges", "bytes"); + response.setHeader("Content-disposition", "attachment; filename=" + encodeFileName(fileName)); + response.setContentType(DEFAULT_CONTENT_TYPE); + + // --------- + if (StringUtil.isBlank(request.getHeader("Range"))) + normalStart(); + else + rangeStart(); + } + + private String encodeFileName(String fileName) { + try { + return new String(fileName.getBytes(StringPool.GBK), StringPool.ISO_8859_1); + } catch (UnsupportedEncodingException e) { + return fileName; + } + } + + private void normalStart() { + response.setHeader("Content-Length", String.valueOf(file.length())); + InputStream inputStream = null; + OutputStream outputStream = null; + try { + inputStream = new BufferedInputStream(new FileInputStream(file)); + outputStream = response.getOutputStream(); + byte[] buffer = new byte[1024]; + for (int len = -1; (len = inputStream.read(buffer)) != -1;) { + outputStream.write(buffer, 0, len); + } + outputStream.flush(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + catch (Exception e) { + throw new RuntimeException(e); + } + finally { + if (inputStream != null) + try {inputStream.close();} catch (IOException e) {} + if (outputStream != null) + try {outputStream.close();} catch (IOException e) {} + } + } + + private void rangeStart() { + Long[] range = {null, null}; + processRange(range); + + String contentLength = String.valueOf(range[1].longValue() - range[0].longValue() + 1); + response.setHeader("Content-Length", contentLength); + response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // status = 206 + + // Content-Range: bytes 0-499/10000 + StringBuilder contentRange = new StringBuilder("bytes ").append(String.valueOf(range[0])).append("-").append(String.valueOf(range[1])).append("/").append(String.valueOf(file.length())); + response.setHeader("Content-Range", contentRange.toString()); + + InputStream inputStream = null; + OutputStream outputStream = null; + try { + long start = range[0]; + long end = range[1]; + inputStream = new BufferedInputStream(new FileInputStream(file)); + if (inputStream.skip(start) != start) + throw new RuntimeException("File skip error"); + outputStream = response.getOutputStream(); + byte[] buffer = new byte[1024]; + long position = start; + for (int len; position <= end && (len = inputStream.read(buffer)) != -1;) { + if (position + len <= end) { + outputStream.write(buffer, 0, len); + position += len; + } + else { + for (int i=0; i= fileLength) + range[i] = fileLength - 1; + } + } + + // Range format like: 9500- + if (range[0] != null && range[1] == null) { + range[1] = fileLength - 1; + } + // Range format like: -500 + else if (range[0] == null && range[1] != null) { + range[0] = fileLength - range[1]; + range[1] = fileLength - 1; + } + + // check final range + if (range[0] == null || range[1] == null || range[0].longValue() > range[1].longValue()) + throw new RuntimeException("Range error"); + } +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileProxyManager.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileProxyManager.java new file mode 100644 index 0000000..a284684 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/FileProxyManager.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + +import java.io.File; + +public class FileProxyManager { + private IFileProxy defaultFileProxyFactory = new BladeFileProxyFactory(); + + private static FileProxyManager me = new FileProxyManager(); + + public static FileProxyManager me() { + return me; + } + + public IFileProxy getDefaultFileProxyFactory() { + return defaultFileProxyFactory; + } + + public void setDefaultFileProxyFactory(IFileProxy defaultFileProxyFactory) { + this.defaultFileProxyFactory = defaultFileProxyFactory; + } + + public String[] path(File file, String dir) { + return defaultFileProxyFactory.path(file, dir); + } + + public File rename(File file, String path) { + return defaultFileProxyFactory.rename(file, path); + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/file/IFileProxy.java b/blade-core-boot/src/main/java/org/springblade/core/boot/file/IFileProxy.java new file mode 100644 index 0000000..2162cbb --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/file/IFileProxy.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.file; + +import java.io.File; + +public interface IFileProxy { + + /** + * 返回路径[物理路径][虚拟路径] + * @param file + * @param dir + * @return + */ + String [] path(File file, String dir); + + /** + * 文件重命名策略 + * @param file + * @param path + * @return + */ + File rename(File file, String path); + + /** + * 图片压缩 + */ + void compress(String path); + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/logger/RequestLogAspect.java b/blade-core-boot/src/main/java/org/springblade/core/boot/logger/RequestLogAspect.java new file mode 100644 index 0000000..aec6faa --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/logger/RequestLogAspect.java @@ -0,0 +1,132 @@ +package org.springblade.core.boot.logger; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springblade.core.tool.jackson.JsonUtil; +import org.springblade.core.tool.utils.BeanUtil; +import org.springblade.core.tool.utils.ClassUtil; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.MethodParameter; +import org.springframework.core.io.InputStreamSource; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * Spring boot 控制器 请求日志,方便代码调试 + * + * @author L.cm + */ +@Slf4j +@Aspect +@Configuration +@Profile({"dev", "test"}) +public class RequestLogAspect { + + /** + * AOP 环切 控制器 R 返回值 + * @param point JoinPoint + * @throws Throwable 异常 + * @return Object + */ + @Around( + "execution(!static org.springblade.core.tool.api.R<*> *(..)) && " + + "(@within(org.springframework.stereotype.Controller) || " + + "@within(org.springframework.web.bind.annotation.RestController))" + ) + public Object aroundApi(ProceedingJoinPoint point) throws Throwable { + MethodSignature ms = (MethodSignature) point.getSignature(); + Method method = ms.getMethod(); + Object[] args = point.getArgs(); + // 请求参数处理 + final Map paraMap = new HashMap<>(16); + for (int i = 0; i < args.length; i++) { + // 读取方法参数 + MethodParameter methodParam = ClassUtil.getMethodParameter(method, i); + // PathVariable 参数跳过 + PathVariable pathVariable = methodParam.getParameterAnnotation(PathVariable.class); + if (pathVariable != null) { + continue; + } + RequestBody requestBody = methodParam.getParameterAnnotation(RequestBody.class); + Object object = args[i]; + // 如果是body的json则是对象 + if (requestBody != null && object != null) { + paraMap.putAll(BeanUtil.toMap(object)); + } else { + // 参数名 + RequestParam requestParam = methodParam.getParameterAnnotation(RequestParam.class); + String paraName; + if (requestParam != null && StringUtil.isNotBlank(requestParam.value())) { + paraName = requestParam.value(); + } else { + paraName = methodParam.getParameterName(); + } + paraMap.put(paraName, object); + } + } + HttpServletRequest request = WebUtil.getRequest(); + String requestURI = request.getRequestURI(); + String requestMethod = request.getMethod(); + // 处理 参数 + List needRemoveKeys = new ArrayList<>(paraMap.size()); + paraMap.forEach((key, value) -> { + if (value instanceof HttpServletRequest) { + needRemoveKeys.add(key); + paraMap.putAll(((HttpServletRequest) value).getParameterMap()); + } else if (value instanceof HttpServletResponse) { + needRemoveKeys.add(key); + } else if (value instanceof InputStream) { + needRemoveKeys.add(key); + } else if (value instanceof MultipartFile) { + String fileName = ((MultipartFile) value).getOriginalFilename(); + paraMap.put(key, fileName); + } else if (value instanceof InputStreamSource) { + needRemoveKeys.add(key); + } else if (value instanceof WebRequest) { + needRemoveKeys.add(key); + paraMap.putAll(((WebRequest) value).getParameterMap()); + } + }); + needRemoveKeys.forEach(paraMap::remove); + // 打印请求 + if (paraMap.isEmpty()) { + log.info("===> {}: {}", requestMethod, requestURI); + } else { + log.info("===> {}: {} Parameters: {}", requestMethod, requestURI, JsonUtil.toJson(paraMap)); + } + // 打印请求头 + Enumeration headers = request.getHeaderNames(); + while (headers.hasMoreElements()) { + String headerName = headers.nextElement(); + String headerValue = request.getHeader(headerName); + log.info("===headers=== {} : {}", headerName, headerValue); + } + // 打印执行时间 + long startNs = System.nanoTime(); + try { + Object result = point.proceed(); + log.info("===Result=== {}", JsonUtil.toJson(result)); + return result; + } finally { + long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); + log.info("<=== {}: {} ({} ms)", request.getMethod(), requestURI, tookMs); + } + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/BaseNode.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/BaseNode.java new file mode 100644 index 0000000..bf2b221 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/BaseNode.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.node; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 节点基类 + * + * @author zhuangqian + */ +@Data +public class BaseNode implements INode { + + protected Integer id;//主键ID + protected Integer parentId;//父节点ID + protected List children = new ArrayList<>();//子孙节点 + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNode.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNode.java new file mode 100644 index 0000000..4c802b4 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNode.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.node; + +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * 森林节点类 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class ForestNode extends BaseNode { + + private Object content;//节点内容 + + public ForestNode(Integer id, Integer parentId, Object content) { + this.id = id; + this.parentId = parentId; + this.content = content; + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeManager.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeManager.java new file mode 100644 index 0000000..49a9517 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeManager.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.node; + +import java.util.ArrayList; +import java.util.List; + +/** + * 森林管理类 + * + * @author zhuangqian + */ +public class ForestNodeManager { + + private List list;// 森林的所有节点 + + public ForestNodeManager(List items) { + list = items; + } + + /** + * 根据节点ID获取一个节点 + * + * @param id 节点ID + * @return 对应的节点对象 + */ + public INode getTreeNodeAT(int id) { + for (INode forestNode : list) { + if (forestNode.getId() == id) + return forestNode; + } + return null; + } + + /** + * 获取树的根节点(一个森林对应多颗树) + * + * @return 树的根节点集合 + */ + public List getRoot() { + List roots = new ArrayList<>(); + for (INode forestNode : list) { + if (forestNode.getParentId() == 0) + roots.add(forestNode); + } + return roots; + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeMerger.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeMerger.java new file mode 100644 index 0000000..c0c6230 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/ForestNodeMerger.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.node; + +import java.util.List; + +/** + * 森林节点归并类 + * + * @author zhuangqian + */ +public class ForestNodeMerger { + + /** + * 将节点数组归并为一个森林(多棵树)(填充节点的children域) + * 时间复杂度为O(n^2) + * + * @param items 节点域 + * @return 多棵树的根节点集合 + */ + public static List merge(List items) { + ForestNodeManager forestNodeManager = new ForestNodeManager(items); + for (INode forestNode : items) { + if (forestNode.getParentId() != 0) { + INode node = forestNodeManager.getTreeNodeAT(forestNode.getParentId()); + node.getChildren().add(forestNode); + } + } + return forestNodeManager.getRoot(); + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/INode.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/INode.java new file mode 100644 index 0000000..14fd32e --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/INode.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.node; + +import java.util.List; + +/** + * Created by Blade. + * + * @author zhuangqian + */ +public interface INode { + + Integer getId(); + + Integer getParentId(); + + List getChildren(); + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/node/NodeTest.java b/blade-core-boot/src/main/java/org/springblade/core/boot/node/NodeTest.java new file mode 100644 index 0000000..fd8b904 --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/node/NodeTest.java @@ -0,0 +1,34 @@ +package org.springblade.core.boot.node; + +import org.springblade.core.tool.jackson.JsonUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Blade. + * + * @author zhuangqian + */ +public class NodeTest { + + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add(new ForestNode(1, 0, "1")); + list.add(new ForestNode(2, 0, "2")); + list.add(new ForestNode(3, 1, "3")); + list.add(new ForestNode(4, 2, "4")); + list.add(new ForestNode(5, 3, "5")); + list.add(new ForestNode(6, 4, "6")); + list.add(new ForestNode(7, 3, "7")); + list.add(new ForestNode(8, 5, "8")); + list.add(new ForestNode(9, 6, "9")); + list.add(new ForestNode(10, 9, "10")); + List tns = ForestNodeMerger.merge(list); + tns.forEach(node -> { + ForestNode n = (ForestNode) node; + System.out.println(JsonUtil.toJson(n)); + }); + } + +} diff --git a/blade-core-boot/src/main/java/org/springblade/core/boot/resolver/TokenArgumentResolver.java b/blade-core-boot/src/main/java/org/springblade/core/boot/resolver/TokenArgumentResolver.java new file mode 100644 index 0000000..49535ec --- /dev/null +++ b/blade-core-boot/src/main/java/org/springblade/core/boot/resolver/TokenArgumentResolver.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.boot.resolver; + +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.secure.BladeUser; +import org.springblade.core.secure.utils.SecureUtil; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import javax.servlet.http.HttpServletRequest; + +/** + * Token转化BladeUser + */ +@Slf4j +public class TokenArgumentResolver implements HandlerMethodArgumentResolver { + + /** + * 1. 入参筛选 + * + * @param methodParameter 参数集合 + * @return 格式化后的参数 + */ + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.getParameterType().equals(BladeUser.class); + } + + /** + * @param methodParameter 入参集合 + * @param modelAndViewContainer model 和 view + * @param nativeWebRequest web相关 + * @param webDataBinderFactory 入参解析 + * @return 包装对象 + * @throws Exception exception + */ + @Override + public Object resolveArgument(MethodParameter methodParameter, + ModelAndViewContainer modelAndViewContainer, + NativeWebRequest nativeWebRequest, + WebDataBinderFactory webDataBinderFactory) { + HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class); + return SecureUtil.getUser(request); + } + +} diff --git a/blade-core-boot/src/main/resources/META-INF/spring-devtools.properties b/blade-core-boot/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..785b4fb --- /dev/null +++ b/blade-core-boot/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.blade-core-boot=/blade-core-boot[\\w-]+\.jar diff --git a/blade-core-boot/src/main/resources/META-INF/spring.factories b/blade-core-boot/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..6051062 --- /dev/null +++ b/blade-core-boot/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.boot.config.MybatisPlusConfiguration,\ + org.springblade.core.boot.logger.RequestLogAspect,\ + org.springblade.core.boot.config.RetryConfiguration,\ + org.springblade.core.boot.config.BladeWebMvcConfiguration,\ + org.springblade.core.boot.config.BladeBootAutoConfiguration diff --git a/blade-core-boot/src/main/resources/banner.txt b/blade-core-boot/src/main/resources/banner.txt new file mode 100644 index 0000000..cbd0280 --- /dev/null +++ b/blade-core-boot/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +${AnsiColor.BRIGHT_CYAN} _____ _ ${AnsiColor.BLUE} ______ _ _ +${AnsiColor.BRIGHT_CYAN}/ ___| (_) ${AnsiColor.BLUE} | ___ \| | | | +${AnsiColor.BRIGHT_CYAN}\ `--. _ __ _ __ _ _ __ __ _ ${AnsiColor.BLUE} | |_/ /| | __ _ __| | ___ +${AnsiColor.BRIGHT_CYAN} `--. \| '_ \ | '__|| || '_ \ / _` | ${AnsiColor.BLUE} | ___ \| | / _` | / _` | / _ \ +${AnsiColor.BRIGHT_CYAN}/\__/ /| |_) || | | || | | || (_| | ${AnsiColor.BLUE} | |_/ /| || (_| || (_| || __/ +${AnsiColor.BRIGHT_CYAN}\____/ | .__/ |_| |_||_| |_| \__, | ${AnsiColor.BLUE} \____/ |_| \__,_| \__,_| \___| +${AnsiColor.BRIGHT_CYAN} | | __/ | +${AnsiColor.BRIGHT_CYAN} |_| |___/ + +${AnsiColor.BLUE}:: SpringBlade :: ${spring.application.name}:${AnsiColor.RED}${blade.env}${AnsiColor.BLUE} :: Running SpringBoot ${spring-boot.version} :: ${AnsiColor.BRIGHT_BLACK} diff --git a/blade-core-boot/src/main/resources/bootstrap.yml b/blade-core-boot/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5f3e55a --- /dev/null +++ b/blade-core-boot/src/main/resources/bootstrap.yml @@ -0,0 +1,87 @@ +#服务器配置 +server: + undertow: + # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 + io-threads: 4 + # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 + worker-threads: 20 + # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 + buffer-size: 1024 + # 是否分配的直接内存 + direct-buffers: true + +#spring配置 +spring: + cloud: + config: + label: master + profile: ${blade.env} + fail-fast: true + discovery: + enabled: true + service-id: blade-config-server + cache: + ehcache: + config: classpath:config/ehcache.xml + http: + encoding: + charset: UTF-8 + force: true + servlet: + multipart: + max-file-size: 256MB + max-request-size: 1024MB + mvc: + throw-exception-if-no-handler-found: true + resources: + add-mappings: false + datasource: + driver-class-name: com.mysql.jdbc.Driver + devtools: + restart: + log-condition-evaluation-delta: false + + +#配置日志地址 +logging: + config: classpath:log/logback_${blade.env}.xml + +# mybatis +mybatis-plus: + mapper-locations: classpath:org/springblade/**/mapper/*Mapper.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: org.springblade.**.model + #typeEnumsPackage: org.springblade.dashboard.entity.enums + global-config: + #刷新mapper 调试神器 + refresh: ${blade.dev-mode} + # 关闭MP3.0自带的banner + banner: false + db-config: + #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; + id-type: 0 + #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" + field-strategy: 2 + #驼峰下划线转换 + column-underline: true + # 逻辑删除配置 + # 逻辑删除全局值(1表示已删除,这也是Mybatis Plus的默认配置) + logic-delete-value: 1 + # 逻辑未删除全局值(0表示未删除,这也是Mybatis Plus的默认配置) + logic-not-delete-value: 0 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + +#swagger公共信息 +swagger: + title: SpringBlade 接口文档系统 + description: SpringBlade 接口文档系统 + version: 1.0.0 + license: Powered By SpringBlade + licenseUrl: https://springblade.org + terms-of-service-url: https://springblade.org + contact: + name: smallchill + email: smallchill@163.com + url: https://gitee.com/smallc diff --git a/blade-core-boot/src/main/resources/config/ehcache.xml b/blade-core-boot/src/main/resources/config/ehcache.xml new file mode 100644 index 0000000..1623029 --- /dev/null +++ b/blade-core-boot/src/main/resources/config/ehcache.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/blade-core-boot/src/main/resources/log/logback_dev.xml b/blade-core-boot/src/main/resources/log/logback_dev.xml new file mode 100644 index 0000000..4faf6ed --- /dev/null +++ b/blade-core-boot/src/main/resources/log/logback_dev.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blade-core-boot/src/main/resources/log/logback_prod.xml b/blade-core-boot/src/main/resources/log/logback_prod.xml new file mode 100644 index 0000000..eb8dc78 --- /dev/null +++ b/blade-core-boot/src/main/resources/log/logback_prod.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf8 + + + + + + + + target/blade/log/info-%d{yyyy-MM-dd}.log + + 365 + + + %n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{50}] %n%-5level: %msg%n + + + + 500MB + + + + INFO + ACCEPT + DENY + + + + + + + + target/blade/log/error-%d{yyyy-MM-dd}.log + + 365 + + + %n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{50}] %n%-5level: %msg%n + + + + 500MB + + + + ERROR + ACCEPT + DENY + + + + + + + + + + + + + + diff --git a/blade-core-boot/src/main/resources/log/logback_test.xml b/blade-core-boot/src/main/resources/log/logback_test.xml new file mode 100644 index 0000000..eb8dc78 --- /dev/null +++ b/blade-core-boot/src/main/resources/log/logback_test.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf8 + + + + + + + + target/blade/log/info-%d{yyyy-MM-dd}.log + + 365 + + + %n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{50}] %n%-5level: %msg%n + + + + 500MB + + + + INFO + ACCEPT + DENY + + + + + + + + target/blade/log/error-%d{yyyy-MM-dd}.log + + 365 + + + %n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{50}] %n%-5level: %msg%n + + + + 500MB + + + + ERROR + ACCEPT + DENY + + + + + + + + + + + + + + diff --git a/blade-core-boot/src/main/resources/static/favicon.ico b/blade-core-boot/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5e2aec953da8a73002971c1a60fa9c5f33a9c3b7 GIT binary patch literal 67646 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 I4ai9S8+?=QG5`Po literal 0 HcmV?d00001 diff --git a/blade-core-launch/pom.xml b/blade-core-launch/pom.xml new file mode 100644 index 0000000..b0c2956 --- /dev/null +++ b/blade-core-launch/pom.xml @@ -0,0 +1,36 @@ + + + + blade-tool + org.springblade + 1.0.0-RC1 + + + 4.0.0 + + blade-core-launch + ${project.artifactId} + ${blade.tool.version} + jar + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-undertow + + + + diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java b/blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java new file mode 100644 index 0000000..8f28ddf --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch; + +import org.springblade.core.launch.constant.AppConstant; +import org.springblade.core.launch.service.LauncherService; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.*; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.function.Function; + +/** + * 项目启动器,搞定环境变量问题 + */ +public class BladeApplication { + + /** + * Create an application context + * + * @param appName application name + * @param source The sources + * @param args args the command line arguments + * @return an application context created from the current state + * @run java -jar app.jar --spring.profiles.active=prod --server.port=2333 + */ + public static ConfigurableApplicationContext run(String appName, Class source, String... args) { + SpringApplicationBuilder builder = createSpringApplicationBuilder(appName, source, args); + return builder.run(args); + } + + private static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, String... args) { + Assert.hasText(appName, "[appName]服务名不能为空"); + // 读取环境变量,使用spring boot的规则 + ConfigurableEnvironment environment = new StandardEnvironment(); + MutablePropertySources propertySources = environment.getPropertySources(); + propertySources.addFirst(new SimpleCommandLinePropertySource(args)); + propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties())); + propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment())); + // 获取配置的环境变量 + String[] activeProfiles = environment.getActiveProfiles(); + // 判断环境:dev、test、prod + List profiles = Arrays.asList(activeProfiles); + // 预设的环境 + List presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CDOE, AppConstant.TEST_CODE, AppConstant.PROD_CODE)); + // 交集 + presetProfiles.retainAll(profiles); + // 当前使用 + List activeProfileList = new ArrayList<>(profiles); + Function joinFun = StringUtils::arrayToCommaDelimitedString; + SpringApplicationBuilder builder = new SpringApplicationBuilder(source); + String profile; + if (activeProfileList.isEmpty()) { + // 默认dev开发 + profile = AppConstant.DEV_CDOE; + activeProfileList.add(profile); + builder.profiles(profile); + } else if (activeProfileList.size() == 1) { + profile = activeProfileList.get(0); + } else { + // 同时存在dev、test、prod环境时 + throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]"); + } + String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0]; + String activePros = joinFun.apply(activeProfileList.toArray()); + System.out.println(String.format("----启动中,读取到的环境变量:[%s],jar地址:[%s]----", activePros, startJarPath)); + Properties props = System.getProperties(); + props.setProperty("spring.application.name", appName); + props.setProperty("spring.profiles.active", profile); + props.setProperty("info.version", AppConstant.APPLICATION_VERSION); + props.setProperty("info.desc", appName); + props.setProperty("blade.env", profile); + props.setProperty("blade.name", appName); + props.setProperty("blade.is-local", String.valueOf(isLocalDev())); + props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true"); + props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION); + // 加载自定义组件 + ServiceLoader loader = ServiceLoader.load(LauncherService.class); + loader.forEach(launcherService -> launcherService.launcher(builder, appName, profile)); + return builder; + } + + /** + * 判断是否为本地开发环境 + * + * @return boolean + */ + private static boolean isLocalDev() { + String osName = System.getProperty("os.name"); + return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equals(osName.toUpperCase())); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/BladeLineRunner.java b/blade-core-launch/src/main/java/org/springblade/core/launch/BladeLineRunner.java new file mode 100644 index 0000000..a0b9fda --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/BladeLineRunner.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * 系统启动完毕后执行 + */ +@Component +public class BladeLineRunner implements CommandLineRunner { + + @Override + public void run(String... args) { + + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/StartEventListener.java b/blade-core-launch/src/main/java/org/springblade/core/launch/StartEventListener.java new file mode 100644 index 0000000..939f5fd --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/StartEventListener.java @@ -0,0 +1,29 @@ +package org.springblade.core.launch; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.scheduling.annotation.Async; +import org.springframework.util.StringUtils; + +/** + * 项目启动事件通知 + */ +@Slf4j +@Configuration +public class StartEventListener { + + @Async + @Order + @EventListener(WebServerInitializedEvent.class) + public void afterStart(WebServerInitializedEvent event) { + Environment environment = event.getApplicationContext().getEnvironment(); + String appName = environment.getProperty("spring.application.name").toUpperCase(); + int localPort = event.getWebServer().getPort(); + String profile = StringUtils.arrayToCommaDelimitedString(environment.getActiveProfiles()); + log.info("---[{}]---启动完成,当前使用的端口:[{}],环境变量:[{}]---", appName, localPort, profile); + } +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeConsulServiceRegistryConfiguration.java b/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeConsulServiceRegistryConfiguration.java new file mode 100644 index 0000000..7b86567 --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeConsulServiceRegistryConfiguration.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.config; + +import com.ecwid.consul.v1.ConsulClient; +import org.springblade.core.launch.consul.BladeConsulServiceRegistry; +import org.springblade.core.launch.server.ServerInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.cloud.consul.ConditionalOnConsulEnabled; +import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; +import org.springframework.cloud.consul.discovery.HeartbeatProperties; +import org.springframework.cloud.consul.discovery.TtlScheduler; +import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry; +import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Consul自定义注册规则 + */ +@Configuration +@ConditionalOnConsulEnabled +@AutoConfigureBefore(ConsulServiceRegistryAutoConfiguration.class) +public class BladeConsulServiceRegistryConfiguration { + + @Autowired(required = false) + private TtlScheduler ttlScheduler; + + @Autowired + private ServerInfo serverInfo; + + @Bean + public ConsulServiceRegistry consulServiceRegistry(ConsulClient consulClient, ConsulDiscoveryProperties properties, + HeartbeatProperties heartbeatProperties) { + return new BladeConsulServiceRegistry(consulClient, properties, ttlScheduler, heartbeatProperties, serverInfo); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeLaunchConfiguration.java b/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeLaunchConfiguration.java new file mode 100644 index 0000000..c019f0c --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/config/BladeLaunchConfiguration.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.config; + +import lombok.AllArgsConstructor; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.launch.server.ServerInfo; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; + + +@Configuration +@AllArgsConstructor +@Order(Ordered.HIGHEST_PRECEDENCE) +@EnableConfigurationProperties({ + BladeProperties.class +}) +public class BladeLaunchConfiguration { + + private ServerProperties serverProperties; + private InetUtils inetUtils; + + + /** + * 服务器信息 + */ + @Bean + public ServerInfo serverInfo() { + return new ServerInfo(serverProperties, inetUtils); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/constant/AppConstant.java b/blade-core-launch/src/main/java/org/springblade/core/launch/constant/AppConstant.java new file mode 100644 index 0000000..c4b2b86 --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/constant/AppConstant.java @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.constant; + +/** + * 系统常量 + */ +public interface AppConstant { + + /** + * 应用版本 + */ + String APPLICATION_VERSION = "1.0.0"; + + /** + * consul dev 地址 + */ + String CONSUL_DEV_HOST = "http://localhost"; + + /** + * consul prod 地址 + */ + String CONSUL_PROD_HOST = "http://192.168.186.129"; + + /** + * consul端口 + */ + String CONSUL_PORT = "8500"; + + /** + * consul端口 + */ + String CONSUL_CONFIG_FORMAT = "yaml"; + + /** + * consul端口 + */ + String CONSUL_WATCH_DELAY = "1000"; + + /** + * consul端口 + */ + String CONSUL_WATCH_ENABLED = "true"; + + /** + * 基础包 + */ + String BASE_PACKAGES = "org.springblade"; + + /** + * zookeeper id + */ + String ZOOKEEPER_ID = "zk"; + + /** + * zookeeper connect string + */ + String ZOOKEEPER_CONNECT_STRING = "127.0.0.1:2181"; + + /** + * zookeeper address + */ + String ZOOKEEPER_ADDRESS = "zookeeper://" + ZOOKEEPER_CONNECT_STRING; + + /** + * zookeeper root + */ + String ZOOKEEPER_ROOT = "/blade-services"; + + /** + * 应用名前缀 + */ + String APPLICATION_NAME_FREFIX = "blade-"; + /** + * 网关模块名称 + */ + String APPLICATION_GATEWAY_NAME = APPLICATION_NAME_FREFIX + "gateway"; + /** + * 授权模块名称 + */ + String APPLICATION_AUTH_NAME = APPLICATION_NAME_FREFIX + "auth"; + /** + * 监控模块名称 + */ + String APPLICATION_ADMIN_NAME = APPLICATION_NAME_FREFIX + "admin"; + /** + * 配置中心模块名称 + */ + String APPLICATION_CONFIG_NAME = APPLICATION_NAME_FREFIX + "config-server"; + /** + * TX模块名称 + */ + String APPLICATION_TX_MANAGER = "tx-manager"; + /** + * 首页模块名称 + */ + String APPLICATION_DESK_NAME = APPLICATION_NAME_FREFIX + "desk"; + /** + * 系统模块名称 + */ + String APPLICATION_SYSTEM_NAME = APPLICATION_NAME_FREFIX + "system"; + /** + * 用户模块名称 + */ + String APPLICATION_USER_NAME = APPLICATION_NAME_FREFIX + "user"; + /** + * 日志模块名称 + */ + String APPLICATION_LOG_NAME = APPLICATION_NAME_FREFIX + "log"; + /** + * 测试模块名称 + */ + String APPLICATION_TEST_NAME = APPLICATION_NAME_FREFIX + "test"; + + /** + * 开发环境 + */ + String DEV_CDOE = "dev"; + /** + * 生产环境 + */ + String PROD_CODE = "prod"; + /** + * 测试环境 + */ + String TEST_CODE = "test"; + + /** + * 代码部署于 linux 上,工作默认为 mac 和 Windows + */ + String OS_NAME_LINUX = "LINUX"; + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/consul/BladeConsulServiceRegistry.java b/blade-core-launch/src/main/java/org/springblade/core/launch/consul/BladeConsulServiceRegistry.java new file mode 100644 index 0000000..b5d0492 --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/consul/BladeConsulServiceRegistry.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.consul; + +import com.ecwid.consul.v1.ConsulClient; +import org.springblade.core.launch.server.ServerInfo; +import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; +import org.springframework.cloud.consul.discovery.HeartbeatProperties; +import org.springframework.cloud.consul.discovery.TtlScheduler; +import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; +import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry; + +/** + * Consul自定义注册规则 + */ +public class BladeConsulServiceRegistry extends ConsulServiceRegistry { + + private ServerInfo serverInfo; + + public BladeConsulServiceRegistry(ConsulClient client, ConsulDiscoveryProperties properties, TtlScheduler ttlScheduler, HeartbeatProperties heartbeatProperties, ServerInfo serverInfo) { + super(client, properties, ttlScheduler, heartbeatProperties); + this.serverInfo = serverInfo; + } + + @Override + public void register(ConsulRegistration reg) { + reg.getService().setId(reg.getService().getName() + "-" + serverInfo.getIP() + "-" + serverInfo.getPort()); + super.register(reg); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/consul/ConsulLauncherService.java b/blade-core-launch/src/main/java/org/springblade/core/launch/consul/ConsulLauncherService.java new file mode 100644 index 0000000..d0e7daf --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/consul/ConsulLauncherService.java @@ -0,0 +1,24 @@ +package org.springblade.core.launch.consul; + +import org.springblade.core.launch.constant.AppConstant; +import org.springblade.core.launch.service.LauncherService; +import org.springframework.boot.builder.SpringApplicationBuilder; + +import java.util.Properties; + +/** + * consul启动拓展 + */ +public class ConsulLauncherService implements LauncherService { + + @Override + public void launcher(SpringApplicationBuilder builder, String appName, String profile) { + Properties props = System.getProperties(); + props.setProperty("spring.cloud.consul.host", profile.equals(AppConstant.DEV_CDOE) ? AppConstant.CONSUL_DEV_HOST : AppConstant.CONSUL_PROD_HOST); + props.setProperty("spring.cloud.consul.port", AppConstant.CONSUL_PORT); + props.setProperty("spring.cloud.consul.config.format", AppConstant.CONSUL_CONFIG_FORMAT); + props.setProperty("spring.cloud.consul.watch.delay", AppConstant.CONSUL_WATCH_DELAY); + props.setProperty("spring.cloud.consul.watch.enabled", AppConstant.CONSUL_WATCH_ENABLED); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladeProperties.java b/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladeProperties.java new file mode 100644 index 0000000..f176944 --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladeProperties.java @@ -0,0 +1,210 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.props; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.lang.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * 配置文件 + */ +@ConfigurationProperties("blade") +public class BladeProperties { + + /** + * 开发环境 + */ + @Getter + @Setter + private String env; + + /** + * 服务名 + */ + @Getter + @Setter + private String name; + + /** + * 判断是否为 本地开发环境 + */ + @Getter + @Setter + private Boolean isLocal = Boolean.FALSE; + + /** + * 装载自定义配置blade.prop.xxx + */ + @Getter + private final Map prop = new HashMap<>(); + + /** + * 获取配置 + * + * @param key key + * @return value + */ + @Nullable + public String get(String key) { + return get(key, null); + } + + /** + * 获取配置 + * + * @param key key + * @param defaultValue 默认值 + * @return value + */ + @Nullable + public String get(String key, @Nullable String defaultValue) { + String value = prop.get(key); + if (value == null) { + return defaultValue; + } + return value; + } + + /** + * 获取配置 + * + * @param key key + * @return int value + */ + @Nullable + public Integer getInt(String key) { + return getInt(key, null); + } + + /** + * 获取配置 + * + * @param key key + * @param defaultValue 默认值 + * @return int value + */ + @Nullable + public Integer getInt(String key, @Nullable Integer defaultValue) { + String value = prop.get(key); + if (value != null) { + return Integer.valueOf(value.trim()); + } + return defaultValue; + } + + /** + * 获取配置 + * + * @param key key + * @return long value + */ + @Nullable + public Long getLong(String key) { + return getLong(key, null); + } + + /** + * 获取配置 + * + * @param key key + * @param defaultValue 默认值 + * @return long value + */ + @Nullable + public Long getLong(String key, @Nullable Long defaultValue) { + String value = prop.get(key); + if (value != null) { + return Long.valueOf(value.trim()); + } + return defaultValue; + } + + /** + * 获取配置 + * + * @param key key + * @return Boolean value + */ + @Nullable + public Boolean getBoolean(String key) { + return getBoolean(key, null); + } + + /** + * 获取配置 + * + * @param key key + * @param defaultValue 默认值 + * @return Boolean value + */ + @Nullable + public Boolean getBoolean(String key, @Nullable Boolean defaultValue) { + String value = prop.get(key); + if (value != null) { + value = value.toLowerCase().trim(); + if ("true".equals(value)) { + return Boolean.TRUE; + } else if ("false".equals(value)) { + return Boolean.FALSE; + } + throw new RuntimeException("The value can not parse to Boolean : " + value); + } + return defaultValue; + } + + /** + * 获取配置 + * + * @param key key + * @return double value + */ + @Nullable + public Double getDouble(String key) { + return getDouble(key, null); + } + + /** + * 获取配置 + * + * @param key key + * @param defaultValue 默认值 + * @return double value + */ + @Nullable + public Double getDouble(String key, @Nullable Double defaultValue) { + String value = prop.get(key); + if (value != null) { + return Double.parseDouble(value.trim()); + } + return defaultValue; + } + + /** + * 判断是否存在key + * + * @param key prop key + * @return boolean + */ + public boolean containsKey(String key) { + return prop.containsKey(key); + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/server/ServerInfo.java b/blade-core-launch/src/main/java/org/springblade/core/launch/server/ServerInfo.java new file mode 100644 index 0000000..d936385 --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/server/ServerInfo.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.server; + +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.cloud.commons.util.InetUtils; + +/** + * 服务器信息 + */ +public class ServerInfo { + + private ServerProperties serverProperties; + private InetUtils inetUtils; + private String hostName; + private String ip; + private Integer prot; + private String ipWithPort; + + public ServerInfo(ServerProperties serverProperties, InetUtils inetUtils) { + this.serverProperties = serverProperties; + this.inetUtils = inetUtils; + this.hostName = getHostInfo().getHostname(); + this.ip = getHostInfo().getIpAddress(); + this.prot = serverProperties.getPort(); + this.ipWithPort = String.format("%s:%d", ip, prot); + } + + public InetUtils.HostInfo getHostInfo() { + return inetUtils.findFirstNonLoopbackHostInfo(); + } + + public String getIP() { + return this.ip; + } + + public Integer getPort() { + return this.prot; + } + + public String getHostName() { + return this.hostName; + } + + public String getIPWithPort() { + return this.ipWithPort; + } + +} diff --git a/blade-core-launch/src/main/java/org/springblade/core/launch/service/LauncherService.java b/blade-core-launch/src/main/java/org/springblade/core/launch/service/LauncherService.java new file mode 100644 index 0000000..9b24b1e --- /dev/null +++ b/blade-core-launch/src/main/java/org/springblade/core/launch/service/LauncherService.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.launch.service; + +import org.springframework.boot.builder.SpringApplicationBuilder; + +/** + * launcher 扩展 用于一些组件发现 + */ +public interface LauncherService { + + /** + * 启动时 处理 SpringApplicationBuilder + * @param builder SpringApplicationBuilder + * @param appName SpringApplicationAppName + * @param profile SpringApplicationProfile + */ + void launcher(SpringApplicationBuilder builder, String appName, String profile); + +} diff --git a/blade-core-launch/src/main/resources/META-INF/services/org.springblade.core.launch.service.LauncherService b/blade-core-launch/src/main/resources/META-INF/services/org.springblade.core.launch.service.LauncherService new file mode 100644 index 0000000..adb5545 --- /dev/null +++ b/blade-core-launch/src/main/resources/META-INF/services/org.springblade.core.launch.service.LauncherService @@ -0,0 +1 @@ +org.springblade.core.launch.consul.ConsulLauncherService diff --git a/blade-core-launch/src/main/resources/META-INF/spring-configuration-metadata.json b/blade-core-launch/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 0000000..d30dadb --- /dev/null +++ b/blade-core-launch/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,37 @@ +{ + "hints": [], + "groups": [ + { + "sourceType": "org.springblade.core.launch.props.BladeProperties", + "name": "blade", + "type": "org.springblade.core.launch.props.BladeProperties" + } + ], + "properties": [ + { + "sourceType": "org.springblade.core.launch.props.BladeProperties", + "name": "blade.env", + "description": "开发环境", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.launch.props.BladeProperties", + "defaultValue": false, + "name": "blade.is-local", + "description": "判断是否为 本地开发环境", + "type": "java.lang.Boolean" + }, + { + "sourceType": "org.springblade.core.launch.props.BladeProperties", + "name": "blade.name", + "description": "服务名", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.launch.props.BladeProperties", + "name": "blade.prop", + "description": "装载自定义配置blade.prop.xxx", + "type": "java.util.Map" + } + ] +} \ No newline at end of file diff --git a/blade-core-launch/src/main/resources/META-INF/spring-devtools.properties b/blade-core-launch/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..83627c5 --- /dev/null +++ b/blade-core-launch/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.blade-core-launch=/blade-core-launch[\\w-]+\.jar diff --git a/blade-core-launch/src/main/resources/META-INF/spring.factories b/blade-core-launch/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a7c7070 --- /dev/null +++ b/blade-core-launch/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.launch.config.BladeLaunchConfiguration,\ + org.springblade.core.launch.StartEventListener,\ + org.springblade.core.launch.config.BladeConsulServiceRegistryConfiguration diff --git a/blade-core-log/pom.xml b/blade-core-log/pom.xml new file mode 100644 index 0000000..a8f6bb9 --- /dev/null +++ b/blade-core-log/pom.xml @@ -0,0 +1,43 @@ + + + + blade-tool + org.springblade + 1.0.0-RC1 + + + 4.0.0 + + blade-core-log + ${project.artifactId} + ${blade.tool.version} + jar + + + + + org.springblade + blade-core-tool + ${blade.tool.version} + + + org.springblade + blade-core-secure + ${blade.tool.version} + + + + com.baomidou + mybatis-plus + ${mybatis.plus.version} + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/blade-core-log/src/main/java/org/springblade/core/log/annotation/ApiLog.java b/blade-core-log/src/main/java/org/springblade/core/log/annotation/ApiLog.java new file mode 100644 index 0000000..b9563d4 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/annotation/ApiLog.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.annotation; + +import java.lang.annotation.*; + +/** + * 操作日志注解 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ApiLog { + + /** + * 日志描述 + * + * @return {String} + */ + String value() default "日志记录"; +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/aspect/ApiLogAspect.java b/blade-core-log/src/main/java/org/springblade/core/log/aspect/ApiLogAspect.java new file mode 100644 index 0000000..b55b9e1 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/aspect/ApiLogAspect.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.aspect; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springblade.core.log.annotation.ApiLog; +import org.springblade.core.log.publisher.ApiLogPublisher; + +/** + * 操作日志使用spring event异步入库 + */ +@Slf4j +@Aspect +public class ApiLogAspect { + + @Around("@annotation(apiLog)") + public Object around(ProceedingJoinPoint point, ApiLog apiLog) throws Throwable { + //获取类名 + String className = point.getTarget().getClass().getName(); + //获取方法 + String methodName = point.getSignature().getName(); + // 发送异步日志事件 + long beginTime = System.currentTimeMillis(); + //执行方法 + Object result = point.proceed(); + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + //记录日志 + ApiLogPublisher.publishEvent(methodName, className, apiLog, time); + return result; + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/config/BladeErrorMvcAutoConfiguration.java b/blade-core-log/src/main/java/org/springblade/core/log/config/BladeErrorMvcAutoConfiguration.java new file mode 100644 index 0000000..918b1bd --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/config/BladeErrorMvcAutoConfiguration.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.config; + + +import lombok.AllArgsConstructor; +import org.springblade.core.log.error.BladeErrorAttributes; +import org.springblade.core.log.error.BladeErrorController; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; +import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.DispatcherServlet; + +import javax.servlet.Servlet; + +/** + * 统一异常处理 + */ +@Configuration +@AllArgsConstructor +@ConditionalOnWebApplication +@AutoConfigureBefore(ErrorMvcAutoConfiguration.class) +@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) +public class BladeErrorMvcAutoConfiguration { + + private final ServerProperties serverProperties; + + @Bean + @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) + public DefaultErrorAttributes errorAttributes() { + return new BladeErrorAttributes(); + } + + @Bean + @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) + public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) { + return new BladeErrorController(errorAttributes, serverProperties.getError()); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/config/BladeLogToolAutoConfiguration.java b/blade-core-log/src/main/java/org/springblade/core/log/config/BladeLogToolAutoConfiguration.java new file mode 100644 index 0000000..095ce5a --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/config/BladeLogToolAutoConfiguration.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.config; + +import lombok.AllArgsConstructor; +import org.springblade.core.log.aspect.ApiLogAspect; +import org.springblade.core.log.event.ApiLogListener; +import org.springblade.core.log.event.BladeLogListener; +import org.springblade.core.log.event.ErrorLogListener; +import org.springblade.core.log.logger.BladeLogger; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.log.feign.ILogClient; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 日志工具自动配置 + */ +@Configuration +@AllArgsConstructor +@ConditionalOnWebApplication +public class BladeLogToolAutoConfiguration { + + private final ILogClient logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + @Bean + public ApiLogAspect apiLogAspect() { + return new ApiLogAspect(); + } + + @Bean + public BladeLogger bladeLogger() { + return new BladeLogger(); + } + + @Bean + public ApiLogListener apiLogListener() { + return new ApiLogListener(logService, serverInfo, bladeProperties); + } + + @Bean + public ErrorLogListener errorEventListener() { + return new ErrorLogListener(logService, serverInfo, bladeProperties); + } + + @Bean + public BladeLogListener bladeEventListener() { + return new BladeLogListener(logService, serverInfo, bladeProperties); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/constant/EventConstant.java b/blade-core-log/src/main/java/org/springblade/core/log/constant/EventConstant.java new file mode 100644 index 0000000..9d4fc37 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/constant/EventConstant.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.constant; + +/** + * 事件常量 + */ +public interface EventConstant { + + /** + * log + */ + String EVENT_LOG = "log"; + /** + * request + */ + String EVENT_REQUEST = "request"; + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorAttributes.java b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorAttributes.java new file mode 100644 index 0000000..cb1dcb4 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorAttributes.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.error; + +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.log.publisher.ErrorLogPublisher; +import org.springblade.core.tool.api.R; +import org.springblade.core.tool.api.ResultCode; +import org.springblade.core.tool.utils.BeanUtil; +import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.lang.Nullable; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.WebRequest; + +import java.util.Map; + +/** + * 全局异常处理 + */ +@Slf4j +public class BladeErrorAttributes extends DefaultErrorAttributes { + + @Override + public Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { + String requestUri = this.getAttr(webRequest, "javax.servlet.error.request_uri"); + Integer status = this.getAttr(webRequest, "javax.servlet.error.status_code"); + Throwable error = getError(webRequest); + R result; + if (error == null) { + log.error("URL:{} error status:{}", requestUri, status); + result = R.failure(ResultCode.FAILURE, "系统未知异常[HttpStatus]:" + status); + } else { + log.error(String.format("URL:%s error status:%d", requestUri, status), error); + result = R.failure(status, error.getMessage()); + } + //发送服务异常事件 + ErrorLogPublisher.publishEvent(error, requestUri); + return BeanUtil.toMap(result); + } + + @Nullable + private T getAttr(WebRequest webRequest, String name) { + return (T) webRequest.getAttribute(name, RequestAttributes.SCOPE_REQUEST); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorController.java b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorController.java new file mode 100644 index 0000000..d3b4c74 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeErrorController.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.error; + +import org.springblade.core.tool.jackson.JsonUtil; +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * 更改html请求异常为ajax + */ +public class BladeErrorController extends BasicErrorController { + + public BladeErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) { + super(errorAttributes, errorProperties); + } + + @Override + public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { + Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); + HttpStatus status = getStatus(request); + response.setStatus(status.value()); + MappingJackson2JsonView view = new MappingJackson2JsonView(); + view.setObjectMapper(JsonUtil.getInstance()); + view.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + return new ModelAndView(view, body); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/error/BladeRestExceptionTranslator.java b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeRestExceptionTranslator.java new file mode 100644 index 0000000..24dca6e --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/error/BladeRestExceptionTranslator.java @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.error; + +import lombok.extern.slf4j.Slf4j; +import org.hibernate.validator.internal.engine.path.PathImpl; +import org.springblade.core.log.exception.ServiceException; +import org.springblade.core.log.publisher.ErrorLogPublisher; +import org.springblade.core.secure.exception.SecureException; +import org.springblade.core.tool.api.R; +import org.springblade.core.tool.api.ResultCode; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.URLUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.NoHandlerFoundException; + +import javax.servlet.Servlet; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.util.Set; + +/** + * 全局异常处理,处理可预见的异常 + */ +@Slf4j +@Configuration +@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@RestControllerAdvice +public class BladeRestExceptionTranslator { + + @ExceptionHandler(MissingServletRequestParameterException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(MissingServletRequestParameterException e) { + log.warn("缺少请求参数", e.getMessage()); + String message = String.format("缺少必要的请求参数: %s", e.getParameterName()); + return R.failure(ResultCode.PARAM_MISS, message); + } + + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(MethodArgumentTypeMismatchException e) { + log.warn("请求参数格式错误", e.getMessage()); + String message = String.format("请求参数格式错误: %s", e.getName()); + return R.failure(ResultCode.PARAM_TYPE_ERROR, message); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(MethodArgumentNotValidException e) { + log.warn("参数验证失败", e.getMessage()); + return handleError(e.getBindingResult()); + } + + @ExceptionHandler(BindException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(BindException e) { + log.warn("参数绑定失败", e.getMessage()); + return handleError(e.getBindingResult()); + } + + private R handleError(BindingResult result) { + FieldError error = result.getFieldError(); + String message = String.format("%s:%s", error.getField(), error.getDefaultMessage()); + return R.failure(ResultCode.PARAM_BIND_ERROR, message); + } + + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(ConstraintViolationException e) { + log.warn("参数验证失败", e.getMessage()); + Set> violations = e.getConstraintViolations(); + ConstraintViolation violation = violations.iterator().next(); + String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName(); + String message = String.format("%s:%s", path, violation.getMessage()); + return R.failure(ResultCode.PARAM_VALID_ERROR, message); + } + + @ExceptionHandler(NoHandlerFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public R handleError(NoHandlerFoundException e) { + log.error("404没找到请求:{}", e.getMessage()); + return R.failure(ResultCode.NOT_FOUND, e.getMessage()); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(HttpMessageNotReadableException e) { + log.error("消息不能读取:{}", e.getMessage()); + return R.failure(ResultCode.MSG_NOT_READABLE, e.getMessage()); + } + + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) + public R handleError(HttpRequestMethodNotSupportedException e) { + log.error("不支持当前请求方法:{}", e.getMessage()); + return R.failure(ResultCode.METHOD_NOT_SUPPORTED, e.getMessage()); + } + + @ExceptionHandler(HttpMediaTypeNotSupportedException.class) + @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) + public R handleError(HttpMediaTypeNotSupportedException e) { + log.error("不支持当前媒体类型:{}", e.getMessage()); + return R.failure(ResultCode.MEDIA_TYPE_NOT_SUPPORTED, e.getMessage()); + } + + @ExceptionHandler(ServiceException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleError(ServiceException e) { + log.error("业务异常", e); + return R.failure(e.getResultCode(), e.getMessage()); + } + + @ExceptionHandler(SecureException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R handleError(SecureException e) { + log.error("认证异常", e); + return R.failure(e.getResultCode(), e.getMessage()); + } + + @ExceptionHandler(Throwable.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public R handleError(Throwable e) { + log.error("服务器异常", e); + //发送服务异常事件 + ErrorLogPublisher.publishEvent(e, URLUtil.getPath(WebUtil.getRequest().getRequestURI())); + return R.failure(ResultCode.INTERNAL_SERVER_ERROR, (Func.isEmpty(e.getMessage()) ? ResultCode.INTERNAL_SERVER_ERROR.getMessage() : e.getMessage())); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogEvent.java b/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogEvent.java new file mode 100644 index 0000000..1254bd4 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogEvent.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.event; + +import org.springframework.context.ApplicationEvent; + +import java.util.Map; + +/** + * 系统日志事件 + */ +public class ApiLogEvent extends ApplicationEvent { + + public ApiLogEvent(Map source) { + super(source); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogListener.java b/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogListener.java new file mode 100644 index 0000000..46bc582 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/ApiLogListener.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.event; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.tool.utils.URLUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springblade.core.log.feign.ILogClient; +import org.springblade.core.log.model.LogApi; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.Map; + + +/** + * 异步监听日志事件 + */ +@Slf4j +@Component +@AllArgsConstructor +public class ApiLogListener { + + private final ILogClient logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + + @Async + @Order + @EventListener(ApiLogEvent.class) + public void saveApiLog(ApiLogEvent event) { + Map source = (Map) event.getSource(); + LogApi logApi = (LogApi) source.get(EventConstant.EVENT_LOG); + HttpServletRequest request = (HttpServletRequest) source.get(EventConstant.EVENT_REQUEST); + logApi.setServiceId(bladeProperties.getName()); + logApi.setServerHost(serverInfo.getHostName()); + logApi.setServerIp(serverInfo.getIPWithPort()); + logApi.setEnv(bladeProperties.getEnv()); + logApi.setRemoteIp(WebUtil.getIP(request)); + logApi.setUserAgent(request.getHeader(WebUtil.USER_AGENT_HEADER)); + logApi.setRequestUri(URLUtil.getPath(request.getRequestURI())); + logApi.setMethod(request.getMethod()); + logApi.setParams(WebUtil.getRequestParamString(request)); + logApi.setCreateBy(SecureUtil.getUser(request).getAccount()); + logApi.setCreateTime(LocalDateTime.now()); + logService.saveApiLog(logApi); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogEvent.java b/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogEvent.java new file mode 100644 index 0000000..c8bc540 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogEvent.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.event; + +import org.springframework.context.ApplicationEvent; + +import java.util.Map; + +/** + * 系统日志事件 + */ +public class BladeLogEvent extends ApplicationEvent { + + public BladeLogEvent(Map source) { + super(source); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogListener.java b/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogListener.java new file mode 100644 index 0000000..dd565a7 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/BladeLogListener.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.event; + + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.feign.ILogClient; +import org.springblade.core.log.model.LogBlade; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.tool.utils.URLUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.Map; + +/** + * 异步监听日志事件 + */ +@Slf4j +@Component +@AllArgsConstructor +public class BladeLogListener { + + private final ILogClient logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + @Async + @Order + @EventListener(BladeLogEvent.class) + public void saveBladeLog(BladeLogEvent event) { + Map source = (Map) event.getSource(); + LogBlade logBlade = (LogBlade) source.get(EventConstant.EVENT_LOG); + HttpServletRequest request = (HttpServletRequest) source.get(EventConstant.EVENT_REQUEST); + logBlade.setRequestUri(URLUtil.getPath(request.getRequestURI())); + logBlade.setUserAgent(request.getHeader(WebUtil.USER_AGENT_HEADER)); + logBlade.setMethod(request.getMethod()); + logBlade.setParams(WebUtil.getRequestParamString(request)); + logBlade.setServiceId(bladeProperties.getName()); + logBlade.setServerHost(serverInfo.getHostName()); + logBlade.setServerIp(serverInfo.getIPWithPort()); + logBlade.setEnv(bladeProperties.getEnv()); + logBlade.setCreateBy(SecureUtil.getUser(request).getAccount()); + logBlade.setCreateTime(LocalDateTime.now()); + logService.saveBladeLog(logBlade); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogEvent.java b/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogEvent.java new file mode 100644 index 0000000..9c4c7db --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogEvent.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.event; + + +import org.springframework.context.ApplicationEvent; + +import java.util.Map; + +/** + * 错误日志事件 + */ +public class ErrorLogEvent extends ApplicationEvent { + + public ErrorLogEvent(Map source) { + super(source); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogListener.java b/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogListener.java new file mode 100644 index 0000000..9b24aad --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/event/ErrorLogListener.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.event; + + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.tool.utils.WebUtil; +import org.springblade.core.log.feign.ILogClient; +import org.springblade.core.log.model.LogError; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.Map; + +/** + * 异步监听错误日志事件 + */ +@Slf4j +@Component +@AllArgsConstructor +public class ErrorLogListener { + + private final ILogClient logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + @Async + @Order + @EventListener(ErrorLogEvent.class) + public void saveErrorLog(ErrorLogEvent event) { + Map source = (Map) event.getSource(); + LogError logError = (LogError) source.get(EventConstant.EVENT_LOG); + HttpServletRequest request = (HttpServletRequest) source.get(EventConstant.EVENT_REQUEST); + logError.setUserAgent(request.getHeader(WebUtil.USER_AGENT_HEADER)); + logError.setMethod(request.getMethod()); + logError.setParams(WebUtil.getRequestParamString(request)); + logError.setServiceId(bladeProperties.getName()); + logError.setServerHost(serverInfo.getHostName()); + logError.setServerIp(serverInfo.getIPWithPort()); + logError.setEnv(bladeProperties.getEnv()); + logError.setCreateBy(SecureUtil.getUser(request).getAccount()); + logError.setCreateTime(LocalDateTime.now()); + logService.saveErrorLog(logError); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/exception/ServiceException.java b/blade-core-log/src/main/java/org/springblade/core/log/exception/ServiceException.java new file mode 100644 index 0000000..74d5008 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/exception/ServiceException.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.exception; + +import lombok.Getter; +import org.springblade.core.tool.api.IResultCode; +import org.springblade.core.tool.api.ResultCode; + + +/** + * 业务异常 + */ +public class ServiceException extends RuntimeException { + private static final long serialVersionUID = 2359767895161832954L; + + @Getter + private final IResultCode resultCode; + + public ServiceException(String message) { + super(message); + this.resultCode = ResultCode.INTERNAL_SERVER_ERROR; + } + + public ServiceException(IResultCode resultCode) { + super(resultCode.getMessage()); + this.resultCode = resultCode; + } + + public ServiceException(IResultCode resultCode, Throwable cause) { + super(cause); + this.resultCode = resultCode; + } + + /** + * 提高性能 + * @return Throwable + */ + @Override + public Throwable fillInStackTrace() { + return this; + } + + public Throwable doFillInStackTrace() { + return super.fillInStackTrace(); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/feign/ILogClient.java b/blade-core-log/src/main/java/org/springblade/core/log/feign/ILogClient.java new file mode 100644 index 0000000..59f4b8d --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/feign/ILogClient.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.feign; + +import org.springblade.core.launch.constant.AppConstant; +import org.springblade.core.log.model.LogApi; +import org.springblade.core.log.model.LogBlade; +import org.springblade.core.log.model.LogError; +import org.springblade.core.tool.api.R; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * Feign接口类 + */ +@FeignClient( + value = AppConstant.APPLICATION_LOG_NAME +) +public interface ILogClient { + + String API_PREFIX = "/log"; + + /** + * 保存错误日志 + * + * @param log + * @return + */ + @PostMapping(API_PREFIX + "/saveBladeLog") + R saveBladeLog(@RequestBody LogBlade log); + + /** + * 保存操作日志 + * + * @param log + * @return + */ + @PostMapping(API_PREFIX + "/saveApiLog") + R saveApiLog(@RequestBody LogApi log); + + /** + * 保存错误日志 + * + * @param log + * @return + */ + @PostMapping(API_PREFIX + "/saveErrorLog") + R saveErrorLog(@RequestBody LogError log); + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/logger/BladeLogger.java b/blade-core-log/src/main/java/org/springblade/core/log/logger/BladeLogger.java new file mode 100644 index 0000000..778a6c2 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/logger/BladeLogger.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.logger; + +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.log.publisher.BladeLogPublisher; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; + +/** + * 日志工具类 + */ +@Slf4j +public class BladeLogger implements InitializingBean { + + @Value("${spring.application.name}") + private String serviceId; + + public void info(String id, String data) { + BladeLogPublisher.publishEvent("info", id, data); + } + + public void debug(String id, String data) { + BladeLogPublisher.publishEvent("debug", id, data); + } + + public void warn(String id, String data) { + BladeLogPublisher.publishEvent("warn", id, data); + } + + public void error(String id, String data) { + BladeLogPublisher.publishEvent("error", id, data); + } + + @Override + public void afterPropertiesSet() throws Exception { + log.info(serviceId + ": BladeLogger init success!"); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/model/LogApi.java b/blade-core-log/src/main/java/org/springblade/core/log/model/LogApi.java new file mode 100644 index 0000000..1fdd101 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/model/LogApi.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.model; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springblade.core.tool.date.DatePattern; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 实体类 + * + * @author Blade + */ +@Data +@TableName("blade_log_api") +public class LogApi implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + /** + * 日志类型 + */ + private String type; + /** + * 日志标题 + */ + private String title; + /** + * 服务ID + */ + private String serviceId; + /** + * 服务器 ip + */ + private String serverIp; + /** + * 服务器名 + */ + private String serverHost; + /** + * 环境 + */ + private String env; + /** + * 操作IP地址 + */ + private String remoteIp; + /** + * 用户代理 + */ + private String userAgent; + /** + * 请求URI + */ + private String requestUri; + /** + * 操作方式 + */ + private String method; + /** + * 方法类 + */ + private String methodClass; + /** + * 方法名 + */ + private String methodName; + /** + * 操作提交的数据 + */ + private String params; + /** + * 执行时间 + */ + private String time; + /** + * 异常信息 + */ + private String exception; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + private LocalDateTime createTime; + + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/model/LogBlade.java b/blade-core-log/src/main/java/org/springblade/core/log/model/LogBlade.java new file mode 100644 index 0000000..cd90e45 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/model/LogBlade.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.model; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springblade.core.tool.date.DatePattern; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 实体类 + * + * @author Blade + * @since 2018-10-12 + */ +@Data +@TableName("blade_log") +public class LogBlade implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + /** + * 服务ID + */ + private String serviceId; + /** + * 服务器名 + */ + private String serverHost; + /** + * 服务器IP地址 + */ + private String serverIp; + /** + * 系统环境 + */ + private String env; + /** + * 日志级别 + */ + private String logLevel; + /** + * 日志业务id + */ + private String logId; + /** + * 日志数据 + */ + private String logData; + /** + * 操作方式 + */ + private String method; + /** + * 请求URI + */ + private String requestUri; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作提交的数据 + */ + private String params; + /** + * 创建者 + */ + private String createBy; + /** + * 创建时间 + */ + @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + private LocalDateTime createTime; + + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/model/LogError.java b/blade-core-log/src/main/java/org/springblade/core/log/model/LogError.java new file mode 100644 index 0000000..287798e --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/model/LogError.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.log.model; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springblade.core.tool.date.DatePattern; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.lang.Nullable; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 服务 异常 + */ +@Data +@TableName("blade_log_error") +public class LogError implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + /** + * 应用名 + */ + private String serviceId; + /** + * 环境 + */ + private String env; + /** + * 服务器 ip + */ + private String serverIp; + /** + * 服务器名 + */ + private String serverHost; + /** + * 用户代理 + */ + private String userAgent; + /** + * 请求url + */ + @Nullable + private String requestUri; + /** + * 操作方式 + */ + private String method; + /** + * 堆栈信息 + */ + private String stackTrace; + /** + * 异常名 + */ + private String exceptionName; + /** + * 异常消息 + */ + private String message; + /** + * 类名 + */ + private String methodClass; + /** + * 文件名 + */ + private String fileName; + /** + * 方法名 + */ + private String methodName; + /** + * 操作提交的数据 + */ + private String params; + /** + * 代码行数 + */ + private Integer lineNumber; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + private LocalDateTime createTime; +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/publisher/ApiLogPublisher.java b/blade-core-log/src/main/java/org/springblade/core/log/publisher/ApiLogPublisher.java new file mode 100644 index 0000000..2c4b690 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/publisher/ApiLogPublisher.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.publisher; + +import org.springblade.core.log.annotation.ApiLog; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.event.ApiLogEvent; +import org.springblade.core.tool.constant.BladeConstant; +import org.springblade.core.tool.utils.SpringUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springblade.core.log.model.LogApi; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +/** + * API日志信息事件发送 + */ +public class ApiLogPublisher { + + public static void publishEvent(String methodName, String methodClass, ApiLog apiLog, long time) { + HttpServletRequest request = WebUtil.getRequest(); + LogApi logApi = new LogApi(); + logApi.setType(BladeConstant.LOG_NORMAL_TYPE); + logApi.setTitle(apiLog.value()); + logApi.setTime(String.valueOf(time)); + logApi.setMethodClass(methodClass); + logApi.setMethodName(methodName); + Map event = new HashMap<>(); + event.put(EventConstant.EVENT_LOG, logApi); + event.put(EventConstant.EVENT_REQUEST, request); + SpringUtil.publishEvent(new ApiLogEvent(event)); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/publisher/BladeLogPublisher.java b/blade-core-log/src/main/java/org/springblade/core/log/publisher/BladeLogPublisher.java new file mode 100644 index 0000000..918800b --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/publisher/BladeLogPublisher.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.publisher; + +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.event.BladeLogEvent; +import org.springblade.core.tool.utils.SpringUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springblade.core.log.model.LogBlade; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +/** + * BLADE日志信息事件发送 + */ +public class BladeLogPublisher { + + public static void publishEvent(String level, String id, String data) { + HttpServletRequest request = WebUtil.getRequest(); + LogBlade logBlade = new LogBlade(); + logBlade.setLogLevel(level); + logBlade.setLogId(id); + logBlade.setLogData(data); + Map event = new HashMap<>(); + event.put(EventConstant.EVENT_LOG, logBlade); + event.put(EventConstant.EVENT_REQUEST, request); + SpringUtil.publishEvent(new BladeLogEvent(event)); + } + +} diff --git a/blade-core-log/src/main/java/org/springblade/core/log/publisher/ErrorLogPublisher.java b/blade-core-log/src/main/java/org/springblade/core/log/publisher/ErrorLogPublisher.java new file mode 100644 index 0000000..4748509 --- /dev/null +++ b/blade-core-log/src/main/java/org/springblade/core/log/publisher/ErrorLogPublisher.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springblade.core.log.publisher; + +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.event.ErrorLogEvent; +import org.springblade.core.tool.utils.*; +import org.springblade.core.log.model.LogError; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +/** + * 异常信息事件发送 + */ +public class ErrorLogPublisher { + + public static void publishEvent(Throwable error, String requestUri) { + HttpServletRequest request = WebUtil.getRequest(); + LogError logError = new LogError(); + logError.setRequestUri(requestUri); + if (Func.isNotEmpty(error)) { + logError.setStackTrace(Exceptions.getStackTraceAsString(error)); + logError.setExceptionName(error.getClass().getName()); + logError.setMessage(error.getMessage()); + StackTraceElement[] elements = error.getStackTrace(); + if (Func.isNotEmpty(elements)) { + StackTraceElement element = elements[0]; + logError.setMethodName(element.getMethodName()); + logError.setMethodClass(element.getClassName()); + logError.setFileName(element.getFileName()); + logError.setLineNumber(element.getLineNumber()); + } + } + Map event = new HashMap<>(); + event.put(EventConstant.EVENT_LOG, logError); + event.put(EventConstant.EVENT_REQUEST, request); + SpringUtil.publishEvent(new ErrorLogEvent(event)); + } + +} diff --git a/blade-core-log/src/main/resources/META-INF/spring-devtools.properties b/blade-core-log/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..dff854a --- /dev/null +++ b/blade-core-log/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.blade-core-log=/blade-core-log[\\w-]+\.jar diff --git a/blade-core-log/src/main/resources/META-INF/spring.factories b/blade-core-log/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..3097701 --- /dev/null +++ b/blade-core-log/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.log.config.BladeLogToolAutoConfiguration,\ + org.springblade.core.log.config.BladeErrorMvcAutoConfiguration,\ + org.springblade.core.log.error.BladeRestExceptionTranslator diff --git a/blade-core-mybatis/pom.xml b/blade-core-mybatis/pom.xml new file mode 100644 index 0000000..7b518f6 --- /dev/null +++ b/blade-core-mybatis/pom.xml @@ -0,0 +1,33 @@ + + + + blade-tool + org.springblade + 1.0.0-RC1 + + + 4.0.0 + + blade-core-mybatis + ${project.artifactId} + ${blade.tool.version} + jar + + + + + com.baomidou + mybatis-plus + ${mybatis.plus.version} + + + + org.springblade + blade-core-secure + ${blade.tool.version} + + + + diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/BladeMetaObjectHandler.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/BladeMetaObjectHandler.java new file mode 100644 index 0000000..43cc93a --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/BladeMetaObjectHandler.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; + +/** + * mybatisplus自定义填充 + */ +@Slf4j +public class BladeMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + + } + + @Override + public void updateFill(MetaObject metaObject) { + + } + +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseEntity.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseEntity.java new file mode 100644 index 0000000..0fc282c --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseEntity.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.base; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springblade.core.tool.date.DatePattern; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class BaseEntity implements Serializable { + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + @ApiModelProperty(value = "主键id") + private Integer id; + + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private Integer createUser; + + /** + * 创建时间 + */ + @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private Integer updateUser; + + /** + * 更新时间 + */ + @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) + @ApiModelProperty(value = "更新时间") + private LocalDateTime updateTime; + + /** + * 状态[1:正常] + */ + @ApiModelProperty(value = "业务状态") + private Integer status; + + /** + * 状态[0:未删除,1:删除] + */ + @ApiModelProperty(value = "是否已删除") + private Integer isDeleted; +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseService.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseService.java new file mode 100644 index 0000000..5210240 --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseService.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.base; + +import com.baomidou.mybatisplus.extension.service.IService; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +public interface BaseService extends IService { + + /** + * 逻辑删除 + * @param ids id集合(逗号分隔) + * @return + */ + boolean deleteLogic(@NotEmpty List ids); + +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseServiceImpl.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseServiceImpl.java new file mode 100644 index 0000000..0e4ed6c --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/base/BaseServiceImpl.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.base; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springblade.core.secure.BladeUser; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.tool.constant.BladeConstant; +import org.springblade.core.tool.utils.BeanUtil; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotEmpty; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 业务封装基础类 + * + * @param mapper + * @param model + */ +@Validated +public class BaseServiceImpl, T extends BaseEntity> extends ServiceImpl implements BaseService { + + private Class modelClass; + + @SuppressWarnings("unchecked") + public BaseServiceImpl() { + Type type = this.getClass().getGenericSuperclass(); + this.modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1]; + } + + @Override + public boolean save(T entity) { + BladeUser user = SecureUtil.getUser(); + LocalDateTime now = LocalDateTime.now(); + entity.setCreateUser(user.getUserId()); + entity.setCreateTime(now); + entity.setUpdateUser(user.getUserId()); + entity.setUpdateTime(now); + entity.setStatus(BladeConstant.DB_STATUS_NORMAL); + entity.setIsDeleted(BladeConstant.DB_NOT_DELETED); + return super.save(entity); + } + + @Override + public boolean updateById(T entity) { + BladeUser user = SecureUtil.getUser(); + entity.setUpdateUser(user.getUserId()); + entity.setUpdateTime(LocalDateTime.now()); + return super.updateById(entity); + } + + @Override + public boolean deleteLogic(@NotEmpty List ids) { + BladeUser user = SecureUtil.getUser(); + T entity = BeanUtil.newInstance(modelClass); + entity.setUpdateUser(user.getUserId()); + entity.setUpdateTime(LocalDateTime.now()); + entity.setIsDeleted(BladeConstant.DB_IS_DELETED); + UpdateWrapper uw = new UpdateWrapper<>(); + uw.in(BladeConstant.DB_PRIMARY_KEY, ids); + return super.update(entity, uw); + } + +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/BaseEntityWrapper.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/BaseEntityWrapper.java new file mode 100644 index 0000000..d63a4ce --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/BaseEntityWrapper.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.support; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 视图包装基类 + */ +public abstract class BaseEntityWrapper { + + public abstract V entityVO(E entity); + + public IPage pageVO(IPage pages) { + List records = pages.getRecords().stream().map(this::entityVO).collect(Collectors.toList()); + IPage pageVo = new Page<>(pages.getCurrent(), pages.getSize(), pages.getTotal()); + pageVo.setRecords(records); + return pageVo; + } + +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Condition.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Condition.java new file mode 100644 index 0000000..5bb184e --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Condition.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.support; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.BeanUtil; + +import java.util.Map; + +/** + * 分页工具 + */ +public class Condition { + + /** + * 转化成mybatis plus中的Page + * + * @param query + * @return + */ + public static IPage getPage(Query query) { + Page page = new Page<>(Func.toInt(query.getCurrent(), 1), Func.toInt(query.getSize(), 10)); + page.setAsc(Func.toStrArray(query.getAscs())); + page.setDesc(Func.toStrArray(query.getDescs())); + return page; + } + + /** + * 获取mybatis plus中的QueryWrapper + * + * @param entity + * @param + * @return + */ + public static QueryWrapper getQueryWrapper(T entity) { + return new QueryWrapper<>(entity); + } + + /** + * 获取mybatis plus中的QueryWrapper + * + * @param query + * @param clazz + * @param + * @return + */ + public static QueryWrapper getQueryWrapper(Map query, Class clazz) { + QueryWrapper qw = new QueryWrapper<>(); + qw.setEntity(BeanUtil.newInstance(clazz)); + if (Func.isNotEmpty(query)) { + query.forEach((k, v) -> { + if (Func.isNotEmpty(v)) qw.like(k, v); + }); + } + return qw; + } + +} diff --git a/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Query.java b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Query.java new file mode 100644 index 0000000..f265e3f --- /dev/null +++ b/blade-core-mybatis/src/main/java/org/springblade/core/mp/support/Query.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.mp.support; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 分页工具 + */ +@Data +@ApiModel(description = "查询条件") +public class Query { + + /** + * 当前页 + */ + @ApiModelProperty(value = "当前页") + private Integer current; + + /** + * 每页的数量 + */ + @ApiModelProperty(value = "每页的数量") + private Integer size; + + /** + * 排序的字段名 + */ + @ApiModelProperty(value = "升序字段") + private String ascs; + + /** + * 排序方式 + */ + @ApiModelProperty(value = "降序字段") + private String descs; + +} diff --git a/blade-core-secure/pom.xml b/blade-core-secure/pom.xml new file mode 100644 index 0000000..bde8e60 --- /dev/null +++ b/blade-core-secure/pom.xml @@ -0,0 +1,33 @@ + + + + blade-tool + org.springblade + 1.0.0-RC1 + + + 4.0.0 + + blade-core-secure + ${project.artifactId} + ${blade.tool.version} + jar + + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + org.springblade + blade-core-tool + ${blade.tool.version} + + + + diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/AuthInfo.java b/blade-core-secure/src/main/java/org/springblade/core/secure/AuthInfo.java new file mode 100644 index 0000000..0df84f8 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/AuthInfo.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AuthInfo + */ +@Data +@ApiModel(description = "认证信息") +public class AuthInfo { + @ApiModelProperty(value = "令牌") + private String accessToken; + @ApiModelProperty(value = "令牌类型") + private String tokenType; + @ApiModelProperty(value = "角色名") + private String authority; + @ApiModelProperty(value = "用户名") + private String userName; + @ApiModelProperty(value = "账号名") + private String account; + @ApiModelProperty(value = "过期时间") + private long expiresIn; + @ApiModelProperty(value = "许可证") + private String license = "made by blade"; +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/BladeUser.java b/blade-core-secure/src/main/java/org/springblade/core/secure/BladeUser.java new file mode 100644 index 0000000..421bea2 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/BladeUser.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户实体 + */ +@Data +public class BladeUser implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + private Integer userId; + /** + * 昵称 + */ + private String userName; + /** + * 账号 + */ + private String account; + /** + * 角色id + */ + private String roleId; + /** + * 角色名 + */ + private String roleName; + + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/annotation/PreAuth.java b/blade-core-secure/src/main/java/org/springblade/core/secure/annotation/PreAuth.java new file mode 100644 index 0000000..baa1567 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/annotation/PreAuth.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.annotation; + +import java.lang.annotation.*; + +/** + * 权限注解 用于检查权限 规定访问权限 + * + * @example @PreAuth("#userVO.id<10") + * @example @PreAuth("hasRole(#test, #test1)") + * @example @PreAuth("hasPermission(#test) and @PreAuth.hasPermission(#test)") + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +public @interface PreAuth { + + /** + * Spring el + * 文档地址:https://docs.spring.io/spring/docs/4.3.16.RELEASE/spring-framework-reference/htmlsingle/#expressions-operators-logical + */ + String value(); + +} + diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/aspect/AuthAspect.java b/blade-core-secure/src/main/java/org/springblade/core/secure/aspect/AuthAspect.java new file mode 100644 index 0000000..4ba4c1d --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/aspect/AuthAspect.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.aspect; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springblade.core.secure.annotation.PreAuth; +import org.springblade.core.secure.auth.AuthFun; +import org.springblade.core.secure.exception.SecureException; +import org.springblade.core.tool.api.ResultCode; +import org.springblade.core.tool.utils.ClassUtil; +import org.springblade.core.tool.utils.StringUtil; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.expression.BeanFactoryResolver; +import org.springframework.core.MethodParameter; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +import java.lang.reflect.Method; + +/** + * AOP 鉴权 + */ +@Aspect +public class AuthAspect implements ApplicationContextAware { + + /** + * 表达式处理 + */ + private static final ExpressionParser SPEL_PARSER = new SpelExpressionParser(); + + /** + * 切 方法 和 类上的 @PreAuth 注解 + * @param point 切点 + * @return Object + * @throws Throwable 没有权限的异常 + */ + @Around( + "@annotation(org.springblade.core.secure.annotation.PreAuth) || " + + "@within(org.springblade.core.secure.annotation.PreAuth)" + ) + public Object preAuth(ProceedingJoinPoint point) throws Throwable { + if (handleAuth(point)) { + return point.proceed(); + } + throw new SecureException(ResultCode.UN_AUTHORIZED); + } + + /** + * 处理权限 + * + * @param point 切点 + */ + private boolean handleAuth(ProceedingJoinPoint point) { + MethodSignature ms = (MethodSignature) point.getSignature(); + Method method = ms.getMethod(); + // 读取权限注解,优先方法上,没有则读取类 + PreAuth preAuth = ClassUtil.getAnnotation(method, PreAuth.class); + // 判断表达式 + String condition = preAuth.value(); + if (StringUtil.isNotBlank(condition)) { + Expression expression = SPEL_PARSER.parseExpression(condition); + // 方法参数值 + Object[] args = point.getArgs(); + StandardEvaluationContext context = getEvaluationContext(method, args); + return expression.getValue(context, Boolean.class); + } + return false; + } + + /** + * 获取方法上的参数 + * + * @param method 方法 + * @param args 变量 + * @return {SimpleEvaluationContext} + */ + private StandardEvaluationContext getEvaluationContext(Method method, Object[] args) { + // 初始化Sp el表达式上下文,并设置 AuthFun + StandardEvaluationContext context = new StandardEvaluationContext(new AuthFun()); + // 设置表达式支持spring bean + context.setBeanResolver(new BeanFactoryResolver(applicationContext)); + for (int i = 0; i < args.length; i++) { + // 读取方法参数 + MethodParameter methodParam = ClassUtil.getMethodParameter(method, i); + // 设置方法 参数名和值 为sp el变量 + context.setVariable(methodParam.getParameterName(), args[i]); + } + return context; + } + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/auth/AuthFun.java b/blade-core-secure/src/main/java/org/springblade/core/secure/auth/AuthFun.java new file mode 100644 index 0000000..6a597f4 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/auth/AuthFun.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.auth; + +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.tool.constant.RoleConstant; +import org.springblade.core.tool.utils.CollectionUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.StringUtil; + +/** + * 权限判断 + */ +public class AuthFun { + + /** + * 放行所有请求 + * + * @return {boolean} + */ + public boolean permitAll() { + return true; + } + + /** + * 只有超管角色才可访问 + * + * @return {boolean} + */ + public boolean denyAll() { + return hasRole(RoleConstant.ADMIN); + } + + /** + * 判断是否有该角色权限 + * + * @param role 单角色 + * @return {boolean} + */ + public boolean hasRole(String role) { + return hasAnyRole(role); + } + + /** + * 判断是否有该角色权限 + * + * @param role 角色集合 + * @return {boolean} + */ + public boolean hasAnyRole(String... role) { + String userRole = SecureUtil.getUser().getRoleName(); + if (StringUtil.isBlank(userRole)) { + return false; + } + String[] roles = Func.toStrArray(userRole); + if (CollectionUtil.contains(roles, role)) { + return true; + } + return false; + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/config/RegistryConfiguration.java b/blade-core-secure/src/main/java/org/springblade/core/secure/config/RegistryConfiguration.java new file mode 100644 index 0000000..1b98956 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/config/RegistryConfiguration.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.config; + + +import org.springblade.core.secure.registry.SecureRegistry; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * secure模块api放行默认配置 + */ +@Configuration +@AutoConfigureBefore(SecureConfiguration.class) +public class RegistryConfiguration { + + @Bean + @ConditionalOnMissingBean(SecureRegistry.class) + public SecureRegistry secureRegistry() { + return new SecureRegistry(); + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java b/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java new file mode 100644 index 0000000..3bc59e6 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.config; + + +import lombok.AllArgsConstructor; +import org.springblade.core.secure.aspect.AuthAspect; +import org.springblade.core.secure.interceptor.SecureInterceptor; +import org.springblade.core.secure.registry.SecureRegistry; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Order +@Configuration +@AllArgsConstructor +public class SecureConfiguration implements WebMvcConfigurer { + + private final SecureRegistry secureRegistry; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + if (secureRegistry.isEnable()) { + registry.addInterceptor(new SecureInterceptor()) + .excludePathPatterns(secureRegistry.getExcludePatterns()) + .excludePathPatterns(secureRegistry.getDefaultExcludePatterns()); + } + } + + @Bean + public AuthAspect authAspect() { + return new AuthAspect(); + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/exception/SecureException.java b/blade-core-secure/src/main/java/org/springblade/core/secure/exception/SecureException.java new file mode 100644 index 0000000..898cf86 --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/exception/SecureException.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.exception; + +import lombok.Getter; +import org.springblade.core.tool.api.IResultCode; +import org.springblade.core.tool.api.ResultCode; + +/** + * Secure异常 + */ +public class SecureException extends RuntimeException { + private static final long serialVersionUID = 2359767895161832954L; + + @Getter + private final IResultCode resultCode; + + public SecureException(String message) { + super(message); + this.resultCode = ResultCode.INTERNAL_SERVER_ERROR; + } + + public SecureException(IResultCode resultCode) { + super(resultCode.getMessage()); + this.resultCode = resultCode; + } + + public SecureException(IResultCode resultCode, Throwable cause) { + super(cause); + this.resultCode = resultCode; + } + + @Override + public Throwable fillInStackTrace() { + return this; + } +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/interceptor/SecureInterceptor.java b/blade-core-secure/src/main/java/org/springblade/core/secure/interceptor/SecureInterceptor.java new file mode 100644 index 0000000..0d8318f --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/interceptor/SecureInterceptor.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.interceptor; + +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.secure.utils.SecureUtil; +import org.springblade.core.tool.api.R; +import org.springblade.core.tool.api.ResultCode; +import org.springblade.core.tool.jackson.JsonUtil; +import org.springblade.core.tool.utils.StringPool; +import org.springblade.core.tool.utils.WebUtil; +import org.springframework.http.MediaType; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Objects; + +/** + * jwt拦截器校验 + */ +@Slf4j +public class SecureInterceptor extends HandlerInterceptorAdapter { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if (null != SecureUtil.getUser().getUserId()) { + return true; + } else { + log.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(), WebUtil.getIP(request), JsonUtil.toJson(request.getParameterMap())); + R result = R.failure(ResultCode.UN_AUTHORIZED); + response.setCharacterEncoding(StringPool.UTF_8); + response.setHeader("Content-type", MediaType.APPLICATION_JSON_UTF8_VALUE); + response.setStatus(HttpServletResponse.SC_OK); + try { + response.getWriter().write(Objects.requireNonNull(JsonUtil.toJson(result))); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + return false; + } + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/registry/SecureRegistry.java b/blade-core-secure/src/main/java/org/springblade/core/secure/registry/SecureRegistry.java new file mode 100644 index 0000000..b15ce1c --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/registry/SecureRegistry.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.registry; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * secure api放行配置 + */ +@Data +public class SecureRegistry { + + private boolean enable = true; + + private final List defaultExcludePatterns = new ArrayList<>(); + + private final List excludePatterns = new ArrayList<>(); + + public SecureRegistry() { + this.defaultExcludePatterns.add("/actuator/health/**"); + this.defaultExcludePatterns.add("/v2/api-docs/**"); + this.defaultExcludePatterns.add("/v2/api-docs-ext/**"); + this.defaultExcludePatterns.add("/auth/**"); + this.defaultExcludePatterns.add("/token/**"); + this.defaultExcludePatterns.add("/log/**"); + this.defaultExcludePatterns.add("/user/userInfo"); + this.defaultExcludePatterns.add("/error/**"); + } + + /** + * 设置放行api + */ + public SecureRegistry excludePathPatterns(String... patterns) { + return excludePathPatterns(Arrays.asList(patterns)); + } + + /** + * 设置放行api + */ + public SecureRegistry excludePathPatterns(List patterns) { + this.excludePatterns.addAll(patterns); + return this; + } + +} diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/utils/SecureUtil.java b/blade-core-secure/src/main/java/org/springblade/core/secure/utils/SecureUtil.java new file mode 100644 index 0000000..81d258b --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/utils/SecureUtil.java @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.secure.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springblade.core.secure.BladeUser; +import org.springblade.core.tool.date.DateField; +import org.springblade.core.tool.date.DateTime; +import org.springblade.core.tool.date.DateUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.WebUtil; + +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import javax.xml.bind.DatatypeConverter; +import java.security.Key; +import java.util.Date; +import java.util.Map; + +/** + * Secure工具类 + */ +public class SecureUtil { + + public final static String header = "Authorization"; + public final static String bearer = "bearer"; + public final static String account = "account"; + public final static String userId = "userId"; + public final static String roleId = "roleId"; + public final static String userName = "userName"; + public final static String roleName = "roleName"; + private static String base64Security = DatatypeConverter.printBase64Binary("SpringBlade".getBytes()); + + /** + * 获取用户信息 + * + * @return + */ + public static BladeUser getUser() { + return getUser(WebUtil.getRequest()); + } + + /** + * 获取用户信息 + * + * @return + */ + public static BladeUser getUser(HttpServletRequest request) { + Claims claims = getClaims(request); + if (claims == null) { + return new BladeUser(); + } + Integer userId = Func.toInt(claims.get(SecureUtil.userId)); + String roleId = Func.toStr(claims.get(SecureUtil.roleId)); + String account = Func.toStr(claims.get(SecureUtil.account)); + String roleName = Func.toStr(claims.get(SecureUtil.roleName)); + BladeUser bladeUser = new BladeUser(); + bladeUser.setAccount(account); + bladeUser.setUserId(userId); + bladeUser.setRoleId(roleId); + bladeUser.setRoleName(roleName); + return bladeUser; + } + + /** + * 获取Claims + * + * @return + */ + public static Claims getClaims(HttpServletRequest request) { + String auth = request.getHeader(SecureUtil.header); + if ((auth != null) && (auth.length() > 7)) { + String HeadStr = auth.substring(0, 6).toLowerCase(); + if (HeadStr.compareTo(SecureUtil.bearer) == 0) { + auth = auth.substring(7); + return SecureUtil.parseJWT(auth); + } + } + return null; + } + + /** + * 获取请求头 + * + * @return + */ + public static String getHeader() { + return getHeader(WebUtil.getRequest()); + } + + /** + * 获取请求头 + * + * @param request + * @return + */ + public static String getHeader(HttpServletRequest request) { + return request.getHeader(header); + } + + /** + * 解析jsonWebToken + * + * @param jsonWebToken + * @return + */ + public static Claims parseJWT(String jsonWebToken) { + try { + Claims claims = Jwts.parser() + .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security)) + .parseClaimsJws(jsonWebToken).getBody(); + return claims; + } catch (Exception ex) { + return null; + } + } + + /** + * 创建jwt + * + * @param user 用户 + * @param audience audience + * @param issuer issuer + * @param isExpire isExpire + * @return + */ + public static String createJWT(Map user, String audience, String issuer, boolean isExpire) { + SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + + long nowMillis = System.currentTimeMillis(); + Date now = new Date(nowMillis); + + //生成签名密钥 + byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security); + Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); + + //添加构成JWT的类 + JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JsonWebToken") + .setIssuer(issuer) + .setAudience(audience) + .signWith(signatureAlgorithm, signingKey); + + //设置JWT参数 + user.forEach(builder::claim); + + //添加Token过期时间 + if (isExpire) { + long expMillis = nowMillis + getExpire(); + Date exp = new Date(expMillis); + builder.setExpiration(exp).setNotBefore(now); + } + + //生成JWT + return builder.compact(); + } + + /** + * 获取过期时间(次日凌晨3点) + * + * @return + */ + public static long getExpire() { + DateTime dateTime = DateUtil.endOfDay(new Date()); + DateTime offset = DateUtil.offset(dateTime, DateField.HOUR, 3); + + return offset.getTime() - System.currentTimeMillis(); + } +} diff --git a/blade-core-secure/src/main/resources/META-INF/spring-devtools.properties b/blade-core-secure/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..9773f18 --- /dev/null +++ b/blade-core-secure/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.blade-core-secure=/blade-core-secure[\\w-]+\.jar diff --git a/blade-core-secure/src/main/resources/META-INF/spring.factories b/blade-core-secure/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..4cf6dfd --- /dev/null +++ b/blade-core-secure/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.secure.config.RegistryConfiguration,\ + org.springblade.core.secure.config.SecureConfiguration diff --git a/blade-core-swagger/pom.xml b/blade-core-swagger/pom.xml new file mode 100644 index 0000000..9e3d5b0 --- /dev/null +++ b/blade-core-swagger/pom.xml @@ -0,0 +1,49 @@ + + + + blade-tool + org.springblade + 1.0.0-RC1 + + + 4.0.0 + + blade-core-swagger + ${project.artifactId} + ${blade.tool.version} + jar + + + + + org.springblade + blade-core-tool + ${blade.tool.version} + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.swagger + swagger-models + + + + + io.swagger + swagger-models + ${swagger.models.version} + + + com.github.xiaoymin + swagger-bootstrap-ui + ${swagger.bootstrapui.version} + + + + diff --git a/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerAutoConfiguration.java b/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerAutoConfiguration.java new file mode 100644 index 0000000..f92a732 --- /dev/null +++ b/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerAutoConfiguration.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2018-2028, lengleng (wangiegie@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.swagger; + + +import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * swagger配置 + */ +@Configuration +@EnableSwagger2 +@EnableSwaggerBootstrapUI +@Profile({"dev", "test"}) +public class SwaggerAutoConfiguration { + + private static final String DEFAULT_EXCLUDE_PATH = "/error"; + private static final String BASE_PATH = "/**"; + + @Bean + @ConditionalOnMissingBean + public SwaggerProperties swaggerProperties() { + return new SwaggerProperties(); + } + + @Bean + public Docket api(SwaggerProperties swaggerProperties) { + // base-path处理 + if (swaggerProperties.getBasePath().size() == 0) { + swaggerProperties.getBasePath().add(BASE_PATH); + } + //noinspection unchecked + List> basePath = new ArrayList(); + swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path))); + + // exclude-path处理 + if (swaggerProperties.getExcludePath().size() == 0) { + swaggerProperties.getExcludePath().add(DEFAULT_EXCLUDE_PATH); + } + List> excludePath = new ArrayList<>(); + swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); + + //noinspection Guava + return new Docket(DocumentationType.SWAGGER_2) + .host(swaggerProperties.getHost()) + .apiInfo(apiInfo(swaggerProperties)).select() + .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) + .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)), Predicates.or(basePath))) + .build() + .securitySchemes(Collections.singletonList(securitySchema())) + .securityContexts(Collections.singletonList(securityContext())) + .pathMapping("/" ); + } + + /** + * 配置默认的全局鉴权策略的开关,通过正则表达式进行匹配;默认匹配所有URL + * + * @return + */ + private SecurityContext securityContext() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) + .build(); + } + + /** + * 默认的全局鉴权策略 + * + * @return + */ + private List defaultAuth() { + ArrayList authorizationScopeList = new ArrayList<>(); + swaggerProperties().getAuthorization().getAuthorizationScopeList().forEach(authorizationScope -> authorizationScopeList.add(new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription()))); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[authorizationScopeList.size()]; + return Collections.singletonList(SecurityReference.builder() + .reference(swaggerProperties().getAuthorization().getName()) + .scopes(authorizationScopeList.toArray(authorizationScopes)) + .build()); + } + + + private OAuth securitySchema() { + ArrayList authorizationScopeList = new ArrayList<>(); + swaggerProperties().getAuthorization().getAuthorizationScopeList().forEach(authorizationScope -> authorizationScopeList.add(new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription()))); + ArrayList grantTypes = new ArrayList<>(); + swaggerProperties().getAuthorization().getTokenUrlList().forEach(tokenUrl -> grantTypes.add(new ResourceOwnerPasswordCredentialsGrant(tokenUrl))); + return new OAuth(swaggerProperties().getAuthorization().getName(), authorizationScopeList, grantTypes); + } + + private ApiInfo apiInfo(SwaggerProperties swaggerProperties) { + return new ApiInfoBuilder() + .title(swaggerProperties.getTitle()) + .description(swaggerProperties.getDescription()) + .license(swaggerProperties.getLicense()) + .licenseUrl(swaggerProperties.getLicenseUrl()) + .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()) + .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail())) + .version(swaggerProperties.getVersion()) + .build(); + } + +} diff --git a/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerProperties.java b/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerProperties.java new file mode 100644 index 0000000..3b546b0 --- /dev/null +++ b/blade-core-swagger/src/main/java/org/springblade/core/swagger/SwaggerProperties.java @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2018-2028, lengleng (wangiegie@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.swagger; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; + +import java.util.ArrayList; +import java.util.List; + +/** + * SwaggerProperties + */ +@Data +@RefreshScope +@ConfigurationProperties("swagger") +public class SwaggerProperties { + /** + * swagger会解析的包路径 + **/ + private String basePackage = "org.springblade"; + /** + * swagger会解析的url规则 + **/ + private List basePath = new ArrayList<>(); + /** + * 在basePath基础上需要排除的url规则 + **/ + private List excludePath = new ArrayList<>(); + /** + * 标题 + **/ + private String title = "SpringBlade 接口文档系统"; + /** + * 描述 + **/ + private String description = "SpringBlade 接口文档系统"; + /** + * 版本 + **/ + private String version = "1.0.0"; + /** + * 许可证 + **/ + private String license = ""; + /** + * 许可证URL + **/ + private String licenseUrl = ""; + /** + * 服务条款URL + **/ + private String termsOfServiceUrl = ""; + + /** + * host信息 + **/ + private String host = ""; + /** + * 联系人信息 + */ + private Contact contact = new Contact(); + /** + * 全局统一鉴权配置 + **/ + private Authorization authorization = new Authorization(); + + @Data + @NoArgsConstructor + public static class Contact { + + /** + * 联系人 + **/ + private String name = "chillzhuang"; + /** + * 联系人url + **/ + private String url = ""; + /** + * 联系人email + **/ + private String email = "smallchill@163.com"; + + } + + @Data + @NoArgsConstructor + public static class Authorization { + + /** + * 鉴权策略ID,需要和SecurityReferences ID保持一致 + */ + private String name = ""; + + /** + * 需要开启鉴权URL的正则 + */ + private String authRegex = "^.*$"; + + /** + * 鉴权作用域列表 + */ + private List authorizationScopeList = new ArrayList<>(); + + private List tokenUrlList = new ArrayList<>(); + } + + @Data + @NoArgsConstructor + public static class AuthorizationScope { + + /** + * 作用域名称 + */ + private String scope = ""; + + /** + * 作用域描述 + */ + private String description = ""; + + } +} diff --git a/blade-core-swagger/src/main/resources/META-INF/spring-configuration-metadata.json b/blade-core-swagger/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 0000000..5bbb770 --- /dev/null +++ b/blade-core-swagger/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,136 @@ +{ + "hints": [], + "groups": [ + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "name": "swagger", + "type": "org.springblade.core.swagger.SwaggerProperties" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "name": "swagger.authorization", + "type": "org.springblade.core.swagger.SwaggerProperties$Authorization" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "name": "swagger.contact", + "type": "org.springblade.core.swagger.SwaggerProperties$Contact" + } + ], + "properties": [ + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Authorization", + "defaultValue": "^.*$", + "name": "swagger.authorization.auth-regex", + "description": "需要开启鉴权URL的正则", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Authorization", + "name": "swagger.authorization.authorization-scope-list", + "description": "鉴权作用域列表", + "type": "java.util.List" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Authorization", + "defaultValue": "", + "name": "swagger.authorization.name", + "description": "鉴权策略ID,需要和SecurityReferences ID保持一致", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Authorization", + "name": "swagger.authorization.token-url-list", + "type": "java.util.List" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "org.springblade", + "name": "swagger.base-package", + "description": "swagger会解析的包路径", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "name": "swagger.base-path", + "description": "swagger会解析的url规则", + "type": "java.util.List" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Contact", + "defaultValue": "smallchill@163.com", + "name": "swagger.contact.email", + "description": "联系人email", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Contact", + "defaultValue": "chillzhuang", + "name": "swagger.contact.name", + "description": "联系人", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties$Contact", + "defaultValue": "", + "name": "swagger.contact.url", + "description": "联系人url", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "SpringBlade 接口文档系统", + "name": "swagger.description", + "description": "描述", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "name": "swagger.exclude-path", + "description": "在basePath基础上需要排除的url规则", + "type": "java.util.List" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "", + "name": "swagger.host", + "description": "host信息", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "", + "name": "swagger.license", + "description": "许可证", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "", + "name": "swagger.license-url", + "description": "许可证URL", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "", + "name": "swagger.terms-of-service-url", + "description": "服务条款URL", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "SpringBlade 接口文档系统", + "name": "swagger.title", + "description": "标题", + "type": "java.lang.String" + }, + { + "sourceType": "org.springblade.core.swagger.SwaggerProperties", + "defaultValue": "1.0.0", + "name": "swagger.version", + "description": "版本", + "type": "java.lang.String" + } + ] +} diff --git a/blade-core-swagger/src/main/resources/META-INF/spring.factories b/blade-core-swagger/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..7af0f77 --- /dev/null +++ b/blade-core-swagger/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.swagger.SwaggerAutoConfiguration diff --git a/blade-core-tool/pom.xml b/blade-core-tool/pom.xml new file mode 100644 index 0000000..f122d4e --- /dev/null +++ b/blade-core-tool/pom.xml @@ -0,0 +1,77 @@ + + + + + org.springblade + blade-tool + 1.0.0-RC1 + + + 4.0.0 + + blade-core-tool + ${project.artifactId} + ${blade.tool.version} + jar + + + + + org.springblade + blade-core-launch + ${blade.tool.version} + + + + org.springframework.cloud + spring-cloud-commons + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + com.google.guava + guava + 26.0-jre + + + + com.squareup.okhttp3 + okhttp + 3.11.0 + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.swagger + swagger-models + + + + + io.swagger + swagger-models + ${swagger.models.version} + + + + io.protostuff + protostuff-core + ${protostuff.version} + + + io.protostuff + protostuff-runtime + ${protostuff.version} + + + + diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/api/IResultCode.java b/blade-core-tool/src/main/java/org/springblade/core/tool/api/IResultCode.java new file mode 100644 index 0000000..4317929 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/api/IResultCode.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.api; + +import java.io.Serializable; + +/** + * 业务代码接口 + */ +public interface IResultCode extends Serializable { + + String getMessage(); + + int getCode(); + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/api/R.java b/blade-core-tool/src/main/java/org/springblade/core/tool/api/R.java new file mode 100644 index 0000000..b19d01a --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/api/R.java @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.api; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import org.springblade.core.tool.constant.BladeConstant; +import org.springblade.core.tool.utils.ObjectUtil; +import org.springframework.lang.Nullable; + +import javax.servlet.http.HttpServletResponse; +import java.io.Serializable; +import java.util.Optional; + +/** + * 统一API响应结果封装 + */ +@Getter +@Setter +@ToString +@ApiModel(description = "返回信息") +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class R implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "状态码", required = true) + private int code; + @ApiModelProperty(value = "是否成功", required = true) + private boolean success; + @ApiModelProperty(value = "承载数据") + private T data; + @ApiModelProperty(value = "返回消息", required = true) + private String msg; + + private R(IResultCode resultCode) { + this(resultCode, null, resultCode.getMessage()); + } + + private R(IResultCode resultCode, String msg) { + this(resultCode, null, msg); + } + + private R(IResultCode resultCode, T data) { + this(resultCode, data, resultCode.getMessage()); + } + + private R(IResultCode resultCode, T data, String msg) { + this(resultCode.getCode(), data, msg); + } + + private R(int code, T data, String msg) { + this.code = code; + this.data = data; + this.msg = msg; + this.success = ResultCode.SUCCESS.code == code; + } + + /** + * 判断返回是否为成功 + * + * @param result Result + * @return 是否成功 + */ + public static boolean isSuccess(@Nullable R result) { + return Optional.ofNullable(result) + .map(x -> ObjectUtil.nullSafeEquals(ResultCode.SUCCESS.code, x.code)) + .orElse(Boolean.FALSE); + } + + /** + * 判断返回是否为成功 + * + * @param result Result + * @return 是否成功 + */ + public static boolean isNotSuccess(@Nullable R result) { + return !R.isSuccess(result); + } + + /** + * 返回R + * @param data 数据 + */ + public static R data(T data) { + return data(data, BladeConstant.DEFAULT_SUCCESS_MESSAGE); + } + + /** + * 返回R + * @param data 数据 + * @param msg 消息 + */ + public static R data(T data, String msg) { + return data(HttpServletResponse.SC_OK, data, msg); + } + + /** + * 返回R + * @param code 状态码 + * @param data 数据 + * @param msg 消息 + */ + public static R data(int code, T data, String msg) { + return new R<>(code, data, data == null ? BladeConstant.DEFAULT_NULL_MESSAGE : msg); + } + + /** + * 返回R + * @param msg 消息 + */ + public static R success(String msg) { + return new R<>(ResultCode.SUCCESS, msg); + } + + /** + * 返回R + * @param resultCode 业务代码 + */ + public static R success(IResultCode resultCode) { + return new R<>(resultCode); + } + + /** + * 返回R + * @param resultCode 业务代码 + */ + public static R success(IResultCode resultCode, String msg) { + return new R<>(resultCode, msg); + } + + /** + * 返回R + * @param msg 消息 + */ + public static R failure(String msg) { + return new R<>(ResultCode.FAILURE, msg); + } + + + /** + * 返回R + * @param code 状态码 + * @param msg 消息 + */ + public static R failure(int code, String msg) { + return new R<>(code, null, msg); + } + + /** + * 返回R + * @param resultCode 业务代码 + */ + public static R failure(IResultCode resultCode) { + return new R<>(resultCode); + } + + /** + * 返回R + * @param resultCode 业务代码 + */ + public static R failure(IResultCode resultCode, String msg) { + return new R<>(resultCode, msg); + } + + /** + * 返回R + * @param flag 成功状态 + */ + public static R status(boolean flag) { + return flag ? success(BladeConstant.DEFAULT_SUCCESS_MESSAGE) : failure(BladeConstant.DEFAULT_FAILURE_MESSAGE); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/api/ResultCode.java b/blade-core-tool/src/main/java/org/springblade/core/tool/api/ResultCode.java new file mode 100644 index 0000000..4841052 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/api/ResultCode.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.api; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import javax.servlet.http.HttpServletResponse; + +/** + * 业务代码枚举 + */ +@Getter +@AllArgsConstructor +public enum ResultCode implements IResultCode { + + /** + * 操作成功 + */ + SUCCESS(HttpServletResponse.SC_OK, "操作成功"), + + /** + * 业务异常 + */ + FAILURE(HttpServletResponse.SC_BAD_REQUEST, "业务异常"), + + /** + * 请求未授权 + */ + UN_AUTHORIZED(HttpServletResponse.SC_UNAUTHORIZED, "请求未授权"), + + /** + * 404 没找到请求 + */ + NOT_FOUND(HttpServletResponse.SC_NOT_FOUND, "404 没找到请求"), + + /** + * 消息不能读取 + */ + MSG_NOT_READABLE(HttpServletResponse.SC_BAD_REQUEST, "消息不能读取"), + + /** + * 不支持当前请求方法 + */ + METHOD_NOT_SUPPORTED(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "不支持当前请求方法"), + + /** + * 不支持当前媒体类型 + */ + MEDIA_TYPE_NOT_SUPPORTED(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "不支持当前媒体类型"), + + /** + * 请求被拒绝 + */ + REQ_REJECT(HttpServletResponse.SC_FORBIDDEN, "请求被拒绝"), + + /** + * 服务器异常 + */ + INTERNAL_SERVER_ERROR(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器异常"), + + /** + * 缺少必要的请求参数 + */ + PARAM_MISS(HttpServletResponse.SC_BAD_REQUEST, "缺少必要的请求参数"), + + /** + * 请求参数类型错误 + */ + PARAM_TYPE_ERROR(HttpServletResponse.SC_BAD_REQUEST, "请求参数类型错误"), + + /** + * 请求参数绑定错误 + */ + PARAM_BIND_ERROR(HttpServletResponse.SC_BAD_REQUEST, "请求参数绑定错误"), + + /** + * 参数校验失败 + */ + PARAM_VALID_ERROR(HttpServletResponse.SC_BAD_REQUEST, "参数校验失败"), + ; + + /** + * code编码 + */ + final int code; + /** + * 中文信息描述 + */ + final String message; + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/config/JacksonConfiguration.java b/blade-core-tool/src/main/java/org/springblade/core/tool/config/JacksonConfiguration.java new file mode 100644 index 0000000..1fec89b --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/config/JacksonConfiguration.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.config; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.springblade.core.tool.date.DatePattern; +import org.springblade.core.tool.jackson.BladeJavaTimeModule; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.util.Locale; +import java.util.TimeZone; + +@Configuration +@ConditionalOnClass(ObjectMapper.class) +@AutoConfigureBefore(JacksonAutoConfiguration.class) +public class JacksonConfiguration { + + @Primary + @Bean + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN); + //创建ObjectMapper + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + //设置地点为中国 + objectMapper.setLocale(Locale.CHINA); + //去掉默认的时间戳格式 + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + //设置为中国上海时区 + objectMapper.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault())); + //序列化时,日期的统一格式 + objectMapper.setDateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN, Locale.CHINA)); + //序列化处理 + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); + objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true); + objectMapper.findAndRegisterModules(); + //失败处理 + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //单引号处理 + objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + //反序列化时,属性不存在的兼容处理 + objectMapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + //日期格式化 + objectMapper.registerModule(new BladeJavaTimeModule()); + objectMapper.findAndRegisterModules(); + return objectMapper; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/config/MessageConfiguration.java b/blade-core-tool/src/main/java/org/springblade/core/tool/config/MessageConfiguration.java new file mode 100644 index 0000000..9a397c6 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/config/MessageConfiguration.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.config; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.AllArgsConstructor; +import org.springblade.core.tool.jackson.MappingApiJackson2HttpMessageConverter; +import org.springblade.core.tool.support.xss.XssFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.converter.*; +import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.servlet.DispatcherType; +import java.nio.charset.StandardCharsets; +import java.util.List; + +@Configuration +@AllArgsConstructor +@Order(Ordered.HIGHEST_PRECEDENCE) +public class MessageConfiguration implements WebMvcConfigurer { + + private final ObjectMapper objectMapper; + + /** + * 使用 JACKSON 作为JSON MessageConverter + */ + @Override + public void configureMessageConverters(List> converters) { + converters.removeIf(x -> x instanceof StringHttpMessageConverter || x instanceof AbstractJackson2HttpMessageConverter); + converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new ResourceHttpMessageConverter()); + converters.add(new ResourceRegionHttpMessageConverter()); + converters.add(new MappingApiJackson2HttpMessageConverter(objectMapper)); + } + + /** + * 防XSS注入 + */ + @Bean + public FilterRegistrationBean xssFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns("/*"); + registration.setName("xssFilter"); + registration.setOrder(Ordered.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/config/ToolConfiguration.java b/blade-core-tool/src/main/java/org/springblade/core/tool/config/ToolConfiguration.java new file mode 100644 index 0000000..da6103c --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/config/ToolConfiguration.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.config; + + +import org.springblade.core.tool.utils.SpringUtil; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + + +@Configuration +@Order(Ordered.HIGHEST_PRECEDENCE) +public class ToolConfiguration implements WebMvcConfigurer { + + /** + * Spring上下文缓存 + */ + @Bean + public SpringUtil springUtils() { + return new SpringUtil(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/constant/BladeConstant.java b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/BladeConstant.java new file mode 100644 index 0000000..8fdcc80 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/BladeConstant.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.constant; + +/** + * 系统常量 + */ +public interface BladeConstant { + + /** + * 编码 + */ + String UTF_8 = "UTF-8"; + + /** + * JSON 资源 + */ + String CONTENT_TYPE = "application/json; charset=utf-8"; + + /** + * 角色前缀 + */ + String SECURITY_ROLE_PREFIX = "ROLE_"; + + /** + * 主键字段名 + */ + String DB_PRIMARY_KEY = "id"; + + /** + * 业务状态[1:正常] + */ + int DB_STATUS_NORMAL = 1; + + + /** + * 删除状态[0:正常,1:删除] + */ + int DB_NOT_DELETED = 0; + int DB_IS_DELETED = 1; + + /** + * 用户锁定状态 + */ + int DB_ADMIN_NON_LOCKED = 0; + int DB_ADMIN_LOCKED = 1; + + /** + * 日志默认状态 + */ + String LOG_NORMAL_TYPE = "1"; + + /** + * 默认为空消息 + */ + String DEFAULT_NULL_MESSAGE = "暂无承载数据"; + /** + * 默认成功消息 + */ + String DEFAULT_SUCCESS_MESSAGE = "操作成功"; + /** + * 默认失败消息 + */ + String DEFAULT_FAILURE_MESSAGE = "操作失败"; + /** + * 默认未授权消息 + */ + String DEFAULT_UNAUTHORIZED_MESSAGE = "签名认证失败"; + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/constant/RoleConstant.java b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/RoleConstant.java new file mode 100644 index 0000000..a80620f --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/RoleConstant.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.constant; + +/** + * 系统默认角色 + */ +public class RoleConstant { + + public static final String ADMIN = "admin"; + + public static final String HAS_ROLE_ADMIN = "hasRole('" + ADMIN + "')"; + + public static final String USER = "user"; + + public static final String HAS_ROLE_USER = "hasRole('" + USER + "')"; + + public static final String TEST = "test"; + + public static final String HAS_ROLE_TEST = "hasRole('" + TEST + "')"; + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/constant/SystemConstant.java b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/SystemConstant.java new file mode 100644 index 0000000..f01118f --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/constant/SystemConstant.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.constant; + + +import lombok.Data; + +/** + * Blade系统配置类 + */ +@Data +public class SystemConstant { + + /** + * 开发模式 + */ + private boolean devMode = false; + + /** + * 远程上传模式 + */ + private boolean remoteMode = false; + + /** + * 外网地址 + */ + private String domain = "http://localhost:8888"; + + /** + * 上传下载路径(物理路径) + */ + private String remotePath = System.getProperty("user.dir") + "/target/blade"; + + /** + * 上传路径(相对路径) + */ + private String uploadPath = "/upload"; + + /** + * 下载路径 + */ + private String downloadPath = "/download"; + + /** + * 图片压缩 + */ + private boolean compress = false; + + /** + * 图片压缩比例 + */ + private Double compressScale = 2.00; + + /** + * 图片缩放选择:true放大;false缩小 + */ + private boolean compressFlag = false; + + /** + * 项目物理路径 + */ + private String realPath = System.getProperty("user.dir"); + + /** + * 项目相对路径 + */ + private String contextPath = "/"; + + private static final SystemConstant me = new SystemConstant(); + + private SystemConstant() { + + } + + public static SystemConstant me() { + return me; + } + + public String getUploadRealPath() { + return (remoteMode ? remotePath : realPath) + uploadPath; + } + + public String getUploadCtxPath() { + return contextPath + uploadPath; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/BetweenFormater.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/BetweenFormater.java new file mode 100644 index 0000000..c3b32da --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/BetweenFormater.java @@ -0,0 +1,157 @@ +package org.springblade.core.tool.date; + +/** + * 时长格式化器 + * @author Looly + * + */ +public class BetweenFormater { + + /** 时长毫秒数 */ + private long betweenMs; + /** 格式化级别 */ + private Level level; + /** 格式化级别的最大个数 */ + private int levelMaxCount; + + /** + * 构造 + * @param betweenMs 日期间隔 + * @param level 级别,按照天、小时、分、秒、毫秒分为5个等级,根据传入等级,格式化到相应级别 + */ + public BetweenFormater(long betweenMs, Level level) { + this(betweenMs, level, 0); + } + + /** + * 构造 + * @param betweenMs 日期间隔 + * @param level 级别,按照天、小时、分、秒、毫秒分为5个等级,根据传入等级,格式化到相应级别 + * @param levelMaxCount 格式化级别的最大个数,假如级别个数为1,但是级别到秒,那只显示一个级别 + */ + public BetweenFormater(long betweenMs, Level level, int levelMaxCount) { + this.betweenMs = betweenMs; + this.level = level; + this.levelMaxCount = levelMaxCount; + } + + /** + * 格式化日期间隔输出
+ * + * @return 格式化后的字符串 + */ + public String format(){ + if(betweenMs == 0){ + return "0"; + } + + long day = betweenMs / DateUnit.DAY.getMillis(); + long hour = betweenMs / DateUnit.HOUR.getMillis() - day * 24; + long minute = betweenMs / DateUnit.MINUTE.getMillis() - day * 24 * 60 - hour * 60; + long second = betweenMs / DateUnit.SECOND.getMillis() - ((day * 24 + hour) * 60 + minute) * 60; + long millisecond = betweenMs - (((day * 24 + hour) * 60 + minute) * 60 + second) * 1000; + + StringBuilder sb = new StringBuilder(); + final int level = this.level.value; + int levelCount = 0; + + if(isLevelCountValid(levelCount) && 0 != day && level > 0){ + sb.append(day).append("天"); + levelCount++; + } + if(isLevelCountValid(levelCount) && 0 != hour && level > 1){ + sb.append(hour).append("小时"); + levelCount++; + } + if(isLevelCountValid(levelCount) && 0 != minute && level > 2){ + sb.append(minute).append("分"); + levelCount++; + } + if(isLevelCountValid(levelCount) && 0 != second && level > 3){ + sb.append(second).append("秒"); + levelCount++; + } + if(isLevelCountValid(levelCount) && 0 != millisecond && level > 4){ + sb.append(millisecond).append("毫秒"); + levelCount++; + } + + return sb.toString(); + } + + /** + * 获得 时长毫秒数 + * @return 时长毫秒数 + */ + public long getBetweenMs() { + return betweenMs; + } + + /** + * 设置 时长毫秒数 + * @param betweenMs 时长毫秒数 + */ + public void setBetweenMs(long betweenMs) { + this.betweenMs = betweenMs; + } + + /** + * 获得 格式化级别 + * @return 格式化级别 + */ + public Level getLevel() { + return level; + } + + /** + * 设置格式化级别 + * @param level 格式化级别 + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * 格式化等级枚举
+ * @author Looly + */ + public static enum Level { + + /** 天 */ + DAY(1), + /** 小时 */ + HOUR(2), + /** 分钟 */ + MINUTE(3), + /** 秒 */ + SECOND(4), + /** 毫秒 */ + MILLSECOND(5); + + private int value; + + private Level(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + } + + @Override + public String toString() { + return format(); + } + + /** + * 等级数量是否有效
+ * 有效的定义是:levelMaxCount大于0(被设置),当前等级数量没有超过这个最大值 + * + * @param levelCount 登记数量 + * @return 是否有效 + */ + private boolean isLevelCountValid(int levelCount){ + return this.levelMaxCount <= 0 || levelCount < this.levelMaxCount; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/ConcurrentDateFormat.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/ConcurrentDateFormat.java new file mode 100644 index 0000000..be576c1 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/ConcurrentDateFormat.java @@ -0,0 +1,70 @@ +package org.springblade.core.tool.date; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Queue; +import java.util.TimeZone; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * 参考tomcat8中的并发DateFormat + *

+ * {@link SimpleDateFormat}的线程安全包装器。 + * 不使用ThreadLocal,创建足够的SimpleDateFormat对象来满足并发性要求。 + * + * @author L.cm + */ +public class ConcurrentDateFormat { + private final String format; + private final Locale locale; + private final TimeZone timezone; + private final Queue queue = new ConcurrentLinkedQueue<>(); + + private ConcurrentDateFormat(String format, Locale locale, TimeZone timezone) { + this.format = format; + this.locale = locale; + this.timezone = timezone; + SimpleDateFormat initial = createInstance(); + queue.add(initial); + } + + public static ConcurrentDateFormat of(String format) { + return new ConcurrentDateFormat(format, Locale.getDefault(), TimeZone.getDefault()); + } + + public static ConcurrentDateFormat of(String format, TimeZone timezone) { + return new ConcurrentDateFormat(format, Locale.getDefault(), timezone); + } + + public static ConcurrentDateFormat of(String format, Locale locale, TimeZone timezone) { + return new ConcurrentDateFormat(format, locale, timezone); + } + + public String format(Date date) { + SimpleDateFormat sdf = queue.poll(); + if (sdf == null) { + sdf = createInstance(); + } + String result = sdf.format(date); + queue.add(sdf); + return result; + } + + public Date parse(String source) throws ParseException { + SimpleDateFormat sdf = queue.poll(); + if (sdf == null) { + sdf = createInstance(); + } + Date result = sdf.parse(source); + queue.add(sdf); + return result; + } + + private SimpleDateFormat createInstance() { + SimpleDateFormat sdf = new SimpleDateFormat(format, locale); + sdf.setTimeZone(timezone); + return sdf; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateBetween.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateBetween.java new file mode 100644 index 0000000..d86a2f8 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateBetween.java @@ -0,0 +1,153 @@ +package org.springblade.core.tool.date; + +import java.util.Calendar; +import java.util.Date; + +/** + * 日期间隔 + * + * @author Looly + * + */ +public class DateBetween { + + /** 开始日期 */ + private Date begin; + /** 结束日期 */ + private Date end; + + /** + * 创建
+ * 在前的日期做为起始时间,在后的做为结束时间,间隔只保留绝对值正数 + * + * @param begin 起始时间 + * @param end 结束时间 + * @return {@link DateBetween} + * @since 3.2.3 + */ + public static DateBetween create(Date begin, Date end) { + return new DateBetween(begin, end); + } + + /** + * 创建
+ * 在前的日期做为起始时间,在后的做为结束时间,间隔只保留绝对值正数 + * + * @param begin 起始时间 + * @param end 结束时间 + * @param isAbs 日期间隔是否只保留绝对值正数 + * @return {@link DateBetween} + * @since 3.2.3 + */ + public static DateBetween create(Date begin, Date end, boolean isAbs) { + return new DateBetween(begin, end, isAbs); + } + + /** + * 构造
+ * 在前的日期做为起始时间,在后的做为结束时间,间隔只保留绝对值正数 + * + * @param begin 起始时间 + * @param end 结束时间 + */ + public DateBetween(Date begin, Date end) { + this(begin, end, true); + } + + /** + * 构造
+ * 在前的日期做为起始时间,在后的做为结束时间 + * + * @param begin 起始时间 + * @param end 结束时间 + * @param isAbs 日期间隔是否只保留绝对值正数 + * @since 3.1.1 + */ + public DateBetween(Date begin, Date end, boolean isAbs) { + if (isAbs && begin.after(end)) { + // 间隔只为正数的情况下,如果开始日期晚于结束日期,置换之 + this.begin = end; + this.end = begin; + } else { + this.begin = begin; + this.end = end; + } + } + + /** + * 判断两个日期相差的时长
+ * 返回 给定单位的时长差 + * + * @param unit 相差的单位:相差 天{@link DateUnit#DAY}、小时{@link DateUnit#HOUR} 等 + * @return 时长差 + */ + public long between(DateUnit unit) { + long diff = end.getTime() - begin.getTime(); + return diff / unit.getMillis(); + } + + /** + * 计算两个日期相差月数
+ * 在非重置情况下,如果起始日期的天小于结束日期的天,月数要少算1(不足1个月) + * + * @param isReset 是否重置时间为起始时间(重置天时分秒) + * @return 相差月数 + * @since 3.0.8 + */ + public long betweenMonth(boolean isReset) { + final Calendar beginCal = DateUtil.calendar(begin); + final Calendar endCal = DateUtil.calendar(end); + + final int betweenYear = endCal.get(Calendar.YEAR) - beginCal.get(Calendar.YEAR); + final int betweenMonthOfYear = endCal.get(Calendar.MONTH) - beginCal.get(Calendar.MONTH); + + int result = betweenYear * 12 + betweenMonthOfYear; + if (false == isReset) { + endCal.set(Calendar.YEAR, beginCal.get(Calendar.YEAR)); + endCal.set(Calendar.MONTH, beginCal.get(Calendar.MONTH)); + long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis(); + if (between < 0) { + return result - 1; + } + } + return result; + } + + /** + * 计算两个日期相差年数
+ * 在非重置情况下,如果起始日期的月小于结束日期的月,年数要少算1(不足1年) + * + * @param isReset 是否重置时间为起始时间(重置月天时分秒) + * @return 相差年数 + * @since 3.0.8 + */ + public long betweenYear(boolean isReset) { + final Calendar beginCal = DateUtil.calendar(begin); + final Calendar endCal = DateUtil.calendar(end); + + int result = endCal.get(Calendar.YEAR) - beginCal.get(Calendar.YEAR); + if (false == isReset) { + endCal.set(Calendar.YEAR, beginCal.get(Calendar.YEAR)); + long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis(); + if (between < 0) { + return result - 1; + } + } + return result; + } + + /** + * 格式化输出时间差
+ * + * @param level 级别 + * @return 字符串 + */ + public String toString(BetweenFormater.Level level) { + return DateUtil.formatBetween(between(DateUnit.MS), level); + } + + @Override + public String toString() { + return toString(BetweenFormater.Level.MILLSECOND); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateException.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateException.java new file mode 100644 index 0000000..05faf83 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateException.java @@ -0,0 +1,31 @@ +package org.springblade.core.tool.date; + +import org.springblade.core.tool.utils.StringUtil; + +/** + * 工具类异常 + * @author xiaoleilu + */ +public class DateException extends RuntimeException{ + private static final long serialVersionUID = 8247610319171014183L; + + public DateException(Throwable e) { + super(StringUtil.format("{}: {}", e.getClass().getSimpleName(), e.getMessage()), e); + } + + public DateException(String message) { + super(message); + } + + public DateException(String messageTemplate, Object... params) { + super(StringUtil.format(messageTemplate, params)); + } + + public DateException(String message, Throwable throwable) { + super(message, throwable); + } + + public DateException(Throwable throwable, String messageTemplate, Object... params) { + super(StringUtil.format(messageTemplate, params), throwable); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateField.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateField.java new file mode 100644 index 0000000..f53f982 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateField.java @@ -0,0 +1,130 @@ +package org.springblade.core.tool.date; + +import java.util.Calendar; + +/** + * 日期各个部分的枚举
+ * 与Calendar相应值对应 + * + * @author Looly + * + */ +public enum DateField { + + /** + * 年 + * @see Calendar#YEAR + */ + YEAR(Calendar.YEAR), + /** + * 月 + * @see Calendar#MONTH + */ + MONTH(Calendar.MONTH), + /** + * 一年中第几周 + * @see Calendar#WEEK_OF_YEAR + */ + WEEK_OF_YEAR(Calendar.WEEK_OF_YEAR), + /** + * 一月中第几周 + * @see Calendar#WEEK_OF_MONTH + */ + WEEK_OF_MONTH(Calendar.WEEK_OF_MONTH), + /** + * 一月中的第几天 + * @see Calendar#DAY_OF_MONTH + */ + DAY_OF_MONTH(Calendar.DAY_OF_MONTH), + /** + *一年中的第几天 + * @see Calendar#DAY_OF_YEAR + */ + DAY_OF_YEAR(Calendar.DAY_OF_YEAR), + /** + *周几,1表示周日,2表示周一 + * @see Calendar#DAY_OF_WEEK + */ + DAY_OF_WEEK(Calendar.DAY_OF_WEEK), + /** + * 天所在的周是这个月的第几周 + * @see Calendar#DAY_OF_WEEK_IN_MONTH + */ + DAY_OF_WEEK_IN_MONTH(Calendar.DAY_OF_WEEK_IN_MONTH), + /** + * 上午或者下午 + * @see Calendar#AM_PM + */ + AM_PM(Calendar.AM_PM), + /** + * 小时,用于12小时制 + * @see Calendar#HOUR + */ + HOUR(Calendar.HOUR), + /** + * 小时,用于24小时制 + * @see Calendar#HOUR + */ + HOUR_OF_DAY(Calendar.HOUR_OF_DAY), + /** + * 分钟 + * @see Calendar#MINUTE + */ + MINUTE(Calendar.MINUTE), + /** + * 秒 + * @see Calendar#SECOND + */ + SECOND(Calendar.SECOND), + /** + * 毫秒 + * @see Calendar#MILLISECOND + */ + MILLISECOND(Calendar.MILLISECOND); + + // --------------------------------------------------------------- + private int value; + + private DateField(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + /** + * 将 {@link Calendar}相关值转换为DatePart枚举对象
+ * + * @param calendarPartIntValue Calendar中关于Week的int值 + * @return {@link DateField} + */ + public static DateField of(int calendarPartIntValue) { + switch (calendarPartIntValue) { + case Calendar.YEAR: + return YEAR; + case Calendar.MONTH: + return MONTH; + case Calendar.WEEK_OF_YEAR: + return WEEK_OF_YEAR; + case Calendar.WEEK_OF_MONTH: + return WEEK_OF_MONTH; + case Calendar.DAY_OF_MONTH: + return DAY_OF_MONTH; + case Calendar.DAY_OF_YEAR: + return DAY_OF_YEAR; + case Calendar.DAY_OF_WEEK: + return DAY_OF_WEEK; + case Calendar.DAY_OF_WEEK_IN_MONTH: + return DAY_OF_WEEK_IN_MONTH; + case Calendar.MINUTE: + return MINUTE; + case Calendar.SECOND: + return SECOND; + case Calendar.MILLISECOND: + return MILLISECOND; + default: + return null; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DatePattern.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DatePattern.java new file mode 100644 index 0000000..24d1b76 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DatePattern.java @@ -0,0 +1,71 @@ +package org.springblade.core.tool.date; + + +import org.springblade.core.tool.date.format.FastDateFormat; + +/** + * 日期格式化类,提供常用的日期格式化对象 + * + * @author Looly + * + */ +public class DatePattern { + + //-------------------------------------------------------------------------------------------------------------------------------- Normal + /** 标准日期格式:yyyy-MM-dd */ + public final static String NORM_DATE_PATTERN = "yyyy-MM-dd"; + /** 标准日期格式 {@link FastDateFormat}:yyyy-MM-dd */ + public final static FastDateFormat NORM_DATE_FORMAT = FastDateFormat.getInstance(NORM_DATE_PATTERN); + + /** 标准时间格式:HH:mm:ss */ + public final static String NORM_TIME_PATTERN = "HH:mm:ss"; + /** 标准时间格式 {@link FastDateFormat}:HH:mm:ss */ + public final static FastDateFormat NORM_TIME_FORMAT = FastDateFormat.getInstance(NORM_TIME_PATTERN); + + /** 标准日期时间格式,精确到分:yyyy-MM-dd HH:mm */ + public final static String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm"; + /** 标准日期时间格式,精确到分 {@link FastDateFormat}:yyyy-MM-dd HH:mm */ + public final static FastDateFormat NORM_DATETIME_MINUTE_FORMAT = FastDateFormat.getInstance(NORM_DATETIME_MINUTE_PATTERN); + + /** 标准日期时间格式,精确到秒:yyyy-MM-dd HH:mm:ss */ + public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + /** 标准日期时间格式,精确到秒 {@link FastDateFormat}:yyyy-MM-dd HH:mm:ss */ + public final static FastDateFormat NORM_DATETIME_FORMAT = FastDateFormat.getInstance(NORM_DATETIME_PATTERN); + + /** 标准日期时间格式,精确到毫秒:yyyy-MM-dd HH:mm:ss.SSS */ + public final static String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; + /** 标准日期时间格式,精确到毫秒 {@link FastDateFormat}:yyyy-MM-dd HH:mm:ss.SSS */ + public final static FastDateFormat NORM_DATETIME_MS_FORMAT = FastDateFormat.getInstance(NORM_DATETIME_MS_PATTERN); + + //-------------------------------------------------------------------------------------------------------------------------------- Pure + /** 标准日期格式:yyyyMMdd */ + public final static String PURE_DATE_PATTERN = "yyyyMMdd"; + /** 标准日期格式 {@link FastDateFormat}:yyyyMMdd */ + public final static FastDateFormat PURE_DATE_FORMAT = FastDateFormat.getInstance(PURE_DATE_PATTERN); + + /** 标准日期格式:HHmmss */ + public final static String PURE_TIME_PATTERN = "HHmmss"; + /** 标准日期格式 {@link FastDateFormat}:HHmmss */ + public final static FastDateFormat PURE_TIME_FORMAT = FastDateFormat.getInstance(PURE_TIME_PATTERN); + + /** 标准日期格式:yyyyMMddHHmmss */ + public final static String PURE_DATETIME_PATTERN = "yyyyMMddHHmmss"; + /** 标准日期格式 {@link FastDateFormat}:yyyyMMddHHmmss */ + public final static FastDateFormat PURE_DATETIME_FORMAT = FastDateFormat.getInstance(PURE_DATETIME_PATTERN); + + /** 标准日期格式:yyyyMMddHHmmssSSS */ + public final static String PURE_DATETIME_MS_PATTERN = "yyyyMMddHHmmssSSS"; + /** 标准日期格式 {@link FastDateFormat}:yyyyMMddHHmmssSSS */ + public final static FastDateFormat PURE_DATETIME_MS_FORMAT = FastDateFormat.getInstance(PURE_DATETIME_MS_PATTERN); + + //-------------------------------------------------------------------------------------------------------------------------------- Others + /** HTTP头中日期时间格式:EEE, dd MMM yyyy HH:mm:ss z */ + public final static String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z"; + /** HTTP头中日期时间格式 {@link FastDateFormat}:EEE, dd MMM yyyy HH:mm:ss z */ + public final static FastDateFormat HTTP_DATETIME_FORMAT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN); + + /** HTTP头中日期时间格式:EEE MMM dd HH:mm:ss zzz yyyy */ + public final static String JDK_DATETIME_PATTERN = "EEE MMM dd HH:mm:ss zzz yyyy"; + /** HTTP头中日期时间格式 {@link FastDateFormat}:EEE MMM dd HH:mm:ss zzz yyyy */ + public final static FastDateFormat JDK_DATETIME_FORMAT = FastDateFormat.getInstance(JDK_DATETIME_PATTERN); +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateTime.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateTime.java new file mode 100644 index 0000000..0190362 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateTime.java @@ -0,0 +1,753 @@ +package org.springblade.core.tool.date; + +import org.springblade.core.tool.date.format.DateParser; +import org.springblade.core.tool.date.format.DatePrinter; +import org.springblade.core.tool.date.format.FastDateFormat; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.StringUtil; +import org.springframework.util.Assert; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + + +/** + * 包装java.util.Date + * + * @author xiaoleilu + * + */ +public class DateTime extends Date { + private static final long serialVersionUID = -5395712593979185936L; + + /** 是否可变对象 */ + private boolean mutable = true; + /** 一周的第一天,默认是周一, 在设置或获得 WEEK_OF_MONTH 或 WEEK_OF_YEAR 字段时,Calendar 必须确定一个月或一年的第一个星期,以此作为参考点。 */ + private Week firstDayOfWeek = Week.MONDAY; + + /** + * 转换JDK date为 DateTime + * + * @param date JDK Date + * @return DateTime + */ + public static DateTime of(Date date) { + if(date instanceof DateTime) { + return (DateTime)date; + } + return new DateTime(date); + } + + /** + * 转换 {@link Calendar} 为 DateTime + * + * @param calendar {@link Calendar} + * @return DateTime + */ + public static DateTime of(Calendar calendar) { + return new DateTime(calendar); + } + + /** + * 构造 + * + * @see DatePattern + * @param dateStr Date字符串 + * @param format 格式 + * @return {@link DateTime} + */ + public static DateTime of(String dateStr, String format) { + return new DateTime(dateStr, format); + } + + /** + * 现在的时间 + * + * @return 现在的时间 + */ + public static DateTime now() { + return new DateTime(); + } + + // -------------------------------------------------------------------- Constructor start + /** + * 当前时间 + */ + public DateTime() { + super(); + } + + /** + * 给定日期的构造 + * + * @param date 日期 + */ + public DateTime(Date date) { + this(date.getTime()); + } + + /** + * 给定日期的构造 + * + * @param calendar {@link Calendar} + */ + public DateTime(Calendar calendar) { + this(calendar.getTime()); + } + + /** + * 给定日期毫秒数的构造 + * + * @param timeMillis 日期毫秒数 + */ + public DateTime(long timeMillis) { + super(timeMillis); + } + + /** + * 构造 + * + * @see DatePattern + * @param dateStr Date字符串 + * @param format 格式 + */ + public DateTime(String dateStr, String format) { + this(dateStr, new SimpleDateFormat(format)); + } + + /** + * 构造 + * + * @see DatePattern + * @param dateStr Date字符串 + * @param dateFormat 格式化器 {@link SimpleDateFormat} + */ + public DateTime(String dateStr, DateFormat dateFormat) { + this(parse(dateStr, dateFormat)); + } + + /** + * 构造 + * + * @see DatePattern + * @param dateStr Date字符串 + * @param dateParser 格式化器 {@link DateParser},可以使用 {@link FastDateFormat} + */ + public DateTime(String dateStr, DateParser dateParser) { + this(parse(dateStr, dateParser)); + } + + // -------------------------------------------------------------------- Constructor end + + // -------------------------------------------------------------------- offset start + /** + * 调整日期和时间
+ * 如果此对象为可变对象,返回自身,否则返回新对象,设置是否可变对象见{@link #setMutable(boolean)} + * + * @param datePart 调整的部分 {@link DateField} + * @param offset 偏移量,正数为向后偏移,负数为向前偏移 + * @return 如果此对象为可变对象,返回自身,否则返回新对象 + */ + public DateTime offset(DateField datePart, int offset) { + final Calendar cal = toCalendar(); + cal.add(datePart.getValue(), offset); + + DateTime dt = mutable ? this : Func.clone(this); + return dt.setTimeInternal(cal.getTimeInMillis()); + } + + /** + * 调整日期和时间
+ * 返回调整后的新{@link DateTime},不影响原对象 + * + * @param datePart 调整的部分 {@link DateField} + * @param offset 偏移量,正数为向后偏移,负数为向前偏移 + * @return 如果此对象为可变对象,返回自身,否则返回新对象 + * @since 3.0.9 + */ + public DateTime offsetNew(DateField datePart, int offset) { + final Calendar cal = toCalendar(); + cal.add(datePart.getValue(), offset); + + DateTime dt = Func.clone(this); + return dt.setTimeInternal(cal.getTimeInMillis()); + } + // -------------------------------------------------------------------- offset end + + // -------------------------------------------------------------------- Part of Date start + /** + * 获得日期的某个部分
+ * 例如获得年的部分,则使用 getField(DatePart.YEAR) + * + * @param field 表示日期的哪个部分的枚举 {@link DateField} + * @return 某个部分的值 + */ + public int getField(DateField field) { + return getField(field.getValue()); + } + + /** + * 获得日期的某个部分
+ * 例如获得年的部分,则使用 getField(Calendar.YEAR) + * + * @param field 表示日期的哪个部分的int值 {@link Calendar} + * @return 某个部分的值 + */ + public int getField(int field) { + return toCalendar().get(field); + } + + /** + * 设置日期的某个部分
+ * 如果此对象为可变对象,返回自身,否则返回新对象,设置是否可变对象见{@link #setMutable(boolean)} + * + * @param field 表示日期的哪个部分的枚举 {@link DateField} + * @param value 值 + * @return {@link DateTime} + */ + public DateTime setField(DateField field, int value) { + return setField(field.getValue(), value); + } + + /** + * 设置日期的某个部分
+ * 如果此对象为可变对象,返回自身,否则返回新对象,设置是否可变对象见{@link #setMutable(boolean)} + * + * @param field 表示日期的哪个部分的int值 {@link Calendar} + * @param value 值 + * @return {@link DateTime} + */ + public DateTime setField(int field, int value) { + Calendar calendar = toCalendar(); + calendar.set(field, value); + + DateTime dt = this; + if (false == mutable) { + dt = Func.clone(this); + } + return dt.setTimeInternal(calendar.getTimeInMillis()); + } + + @Override + public void setTime(long time) { + if (mutable) { + super.setTime(time); + } else { + throw new DateException("This is not a mutable object !"); + } + } + + /** + * 获得年的部分 + * + * @return 年的部分 + */ + public int year() { + return getField(DateField.YEAR); + } + + /** + * 获得当前日期所属季度
+ * 1:第一季度
+ * 2:第二季度
+ * 3:第三季度
+ * 4:第四季度
+ * + * @return 第几个季度 + */ + public int season() { + return monthStartFromOne() / 4 + 1; + } + + /** + * 获得当前日期所属季度
+ * + * @return 第几个季度 {@link Season} + */ + public Season seasonEnum() { + return Season.of(season()); + } + + /** + * 获得月份,从0开始计数 + * + * @return 月份 + */ + public int month() { + return getField(DateField.MONTH); + } + + /** + * 获得月份,从1开始计数
+ * 由于{@link Calendar} 中的月份按照0开始计数,导致某些需求容易误解,因此如果想用1表示一月,2表示二月则调用此方法 + * + * @return 月份 + */ + public int monthStartFromOne() { + return month() + 1; + } + + /** + * 获得月份 + * + * @return {@link Month} + */ + public Month monthEnum() { + return Month.of(month()); + } + + /** + * 获得指定日期是所在年份的第几周
+ * 此方法返回值与一周的第一天有关,比如:
+ * 2016年1月3日为周日,如果一周的第一天为周日,那这天是第二周(返回2)
+ * 如果一周的第一天为周一,那这天是第一周(返回1) + * + * @return 周 + * @see #setFirstDayOfWeek(Week) + */ + public int weekOfYear() { + return getField(DateField.WEEK_OF_YEAR); + } + + /** + * 获得指定日期是所在月份的第几周
+ * 此方法返回值与一周的第一天有关,比如:
+ * 2016年1月3日为周日,如果一周的第一天为周日,那这天是第二周(返回2)
+ * 如果一周的第一天为周一,那这天是第一周(返回1) + * + * @return 周 + * @see #setFirstDayOfWeek(Week) + */ + public int weekOfMonth() { + return getField(DateField.WEEK_OF_MONTH); + } + + /** + * 获得指定日期是这个日期所在月份的第几天
+ * + * @return 天 + */ + public int dayOfMonth() { + return getField(DateField.DAY_OF_MONTH); + } + + /** + * 获得指定日期是星期几,1表示周日,2表示周一 + * + * @return 星期几 + */ + public int dayOfWeek() { + return getField(DateField.DAY_OF_WEEK); + } + + /** + * 获得天所在的周是这个月的第几周 + * + * @return 天 + */ + public int dayOfWeekInMonth() { + return getField(DateField.DAY_OF_WEEK_IN_MONTH); + } + + /** + * 获得指定日期是星期几 + * + * @return {@link Week} + */ + public Week dayOfWeekEnum() { + return Week.of(dayOfWeek()); + } + + /** + * 获得指定日期的小时数部分
+ * + * @param is24HourClock 是否24小时制 + * @return 小时数 + */ + public int hour(boolean is24HourClock) { + return getField(is24HourClock ? DateField.HOUR_OF_DAY : DateField.HOUR); + } + + /** + * 获得指定日期的分钟数部分
+ * 例如:10:04:15.250 =》 4 + * + * @return 分钟数 + */ + public int minute() { + return getField(DateField.MINUTE); + } + + /** + * 获得指定日期的秒数部分
+ * + * @return 秒数 + */ + public int second() { + return getField(DateField.SECOND); + } + + /** + * 获得指定日期的毫秒数部分
+ * + * @return 毫秒数 + */ + public int millsecond() { + return getField(DateField.MILLISECOND); + } + + /** + * 是否为上午 + * + * @return 是否为上午 + */ + public boolean isAM() { + return Calendar.AM == getField(DateField.AM_PM); + } + + /** + * 是否为下午 + * + * @return 是否为下午 + */ + public boolean isPM() { + return Calendar.PM == getField(DateField.AM_PM); + } + // -------------------------------------------------------------------- Part of Date end + + /** + * 是否闰年 + * + * @see DateUtil#isLeapYear(int) + * @return 是否闰年 + */ + public boolean isLeapYear() { + return DateUtil.isLeapYear(year()); + } + + /** + * 转换为Calendar,默认{@link TimeZone},默认 {@link Locale} + * + * @return {@link Calendar} + */ + public Calendar toCalendar() { + final Calendar cal = Calendar.getInstance(); + cal.setFirstDayOfWeek(firstDayOfWeek.getValue()); + cal.setTime(this); + return cal; + } + + /** + * 转换为Calendar + * + * @param locale 地域 {@link Locale} + * @return {@link Calendar} + */ + public Calendar toCalendar(Locale locale) { + final Calendar cal = Calendar.getInstance(locale); + cal.setFirstDayOfWeek(firstDayOfWeek.getValue()); + cal.setTime(this); + return cal; + } + + /** + * 转换为Calendar + * + * @param zone 时区 {@link TimeZone} + * @return {@link Calendar} + */ + public Calendar toCalendar(TimeZone zone) { + return toCalendar(zone, Locale.getDefault(Locale.Category.FORMAT)); + } + + /** + * 转换为Calendar + * + * @param zone 时区 {@link TimeZone} + * @param locale 地域 {@link Locale} + * @return {@link Calendar} + */ + public Calendar toCalendar(TimeZone zone, Locale locale) { + final Calendar cal = Calendar.getInstance(zone, locale); + cal.setFirstDayOfWeek(firstDayOfWeek.getValue()); + cal.setTime(this); + return cal; + } + + /** + * 转换为 {@link Date}
+ * 考虑到很多框架(例如Hibernate)的兼容性,提供此方法返回JDK原生的Date对象 + * + * @return {@link Date} + * @since 3.2.2 + */ + public Date toJdkDate() { + return new Date(this.getTime()); + } + + /** + * 转为{@link Timestamp} + * + * @return {@link Timestamp} + */ + public Timestamp toTimestamp() { + return new Timestamp(this.getTime()); + } + + /** + * 转为 {@link java.sql.Date} + * + * @return {@link java.sql.Date} + */ + public java.sql.Date toSqlDate() { + return new java.sql.Date(getTime()); + } + + /** + * 计算相差时长 + * + * @param date 对比的日期 + * @return {@link DateBetween} + */ + public DateBetween between(Date date) { + return new DateBetween(this, date); + } + + /** + * 计算相差时长 + * + * @param date 对比的日期 + * @param unit 单位 {@link DateUnit} + * @return 相差时长 + */ + public long between(Date date, DateUnit unit) { + return new DateBetween(this, date).between(unit); + } + + /** + * 计算相差时长 + * + * @param date 对比的日期 + * @param unit 单位 {@link DateUnit} + * @param formatLevel 格式化级别 + * @return 相差时长 + */ + public String between(Date date, DateUnit unit, BetweenFormater.Level formatLevel) { + return new DateBetween(this, date).toString(formatLevel); + } + + /** + * 当前日期是否在日期指定范围内
+ * 起始日期和结束日期可以互换 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @return 是否在范围内 + * @since 3.0.8 + */ + public boolean isIn(Date beginDate, Date endDate) { + long beginMills = beginDate.getTime(); + long endMills = endDate.getTime(); + long thisMills = this.getTime(); + + return thisMills >= Math.min(beginMills, endMills) && thisMills <= Math.max(beginMills, endMills); + } + + /** + * 是否在给定日期之前或与给定日期相等 + * + * @param date 日期 + * @return 是否在给定日期之前或与给定日期相等 + * @since 3.0.9 + */ + public boolean isBeforeOrEquals(Date date) { + if (null == date) { + throw new NullPointerException("Date to compare is null !"); + } + return compareTo(date) <= 0; + } + + /** + * 是否在给定日期之后或与给定日期相等 + * + * @param date 日期 + * @return 是否在给定日期之后或与给定日期相等 + * @since 3.0.9 + */ + public boolean isAfterOrEquals(Date date) { + if (null == date) { + throw new NullPointerException("Date to compare is null !"); + } + return compareTo(date) >= 0; + } + + /** + * 对象是否可变
+ * 如果为不可变对象,以下方法将返回新方法: + *

+ * 如果为不可变对象,{@link DateTime#setTime(long)}将抛出异常 + * + * @return 对象是否可变 + */ + public boolean isMutable() { + return mutable; + } + + /** + * 设置对象是否可变 如果为不可变对象,以下方法将返回新方法: + * + * 如果为不可变对象,{@link DateTime#setTime(long)}将抛出异常 + * + * @param mutable 是否可变 + * @return this + */ + public DateTime setMutable(boolean mutable) { + this.mutable = mutable; + return this; + } + + /** + * 获得一周的第一天,默认为周一 + * + * @return 一周的第一天 + */ + public Week getFirstDayOfWeek() { + return firstDayOfWeek; + } + + /** + * 设置一周的第一天
+ * JDK的Calendar中默认一周的第一天是周日,Hutool中将此默认值设置为周一
+ * 设置一周的第一天主要影响{@link #weekOfMonth()}和{@link #weekOfYear()} 两个方法 + * + * @param firstDayOfWeek 一周的第一天 + * @return this + * @see #weekOfMonth() + * @see #weekOfYear() + */ + public DateTime setFirstDayOfWeek(Week firstDayOfWeek) { + this.firstDayOfWeek = firstDayOfWeek; + return this; + } + + // -------------------------------------------------------------------- toString start + /** + * 转为"yyyy-MM-dd yyyy-MM-dd HH:mm:ss " 格式字符串 + * + * @return "yyyy-MM-dd yyyy-MM-dd HH:mm:ss " 格式字符串 + */ + @Override + public String toString() { + return toString(DatePattern.NORM_DATETIME_FORMAT); + } + + /** + * 转为"yyyy-MM-dd " 格式字符串 + * + * @return "yyyy-MM-dd " 格式字符串 + * @since 4.0.0 + */ + public String toDateStr() { + return toString(DatePattern.NORM_DATE_PATTERN); + } + + /** + * 转为字符串 + * + * @param format 日期格式,常用格式见: {@link DatePattern} + * @return String + */ + public String toString(String format) { + return toString(FastDateFormat.getInstance(format)); + } + + /** + * 转为字符串 + * + * @param format {@link DatePrinter} 或 {@link FastDateFormat} + * @return String + */ + public String toString(DatePrinter format) { + return format.format(this); + } + + /** + * 转为字符串 + * + * @param format {@link SimpleDateFormat} + * @return String + */ + public String toString(DateFormat format) { + return format.format(this); + } + + /** + * @return 输出精确到毫秒的标准日期形式 + */ + public String toMsStr() { + return toString(DatePattern.NORM_DATETIME_MS_FORMAT); + } + // -------------------------------------------------------------------- toString end + + /** + * 转换字符串为Date + * + * @param dateStr 日期字符串 + * @param dateFormat {@link SimpleDateFormat} + * @return {@link Date} + */ + private static Date parse(String dateStr, DateFormat dateFormat) { + try { + return dateFormat.parse(dateStr); + } catch (Exception e) { + String pattern; + if (dateFormat instanceof SimpleDateFormat) { + pattern = ((SimpleDateFormat) dateFormat).toPattern(); + } else { + pattern = dateFormat.toString(); + } + throw new DateException(StringUtil.format("Parse [{}] with format [{}] error!", dateStr, pattern), e); + } + } + + /** + * 转换字符串为Date + * + * @param dateStr 日期字符串 + * @param parser {@link FastDateFormat} + * @return {@link Date} + */ + private static Date parse(String dateStr, DateParser parser) { + Assert.notNull(parser, "Parser or DateFromat must be not null !"); + //Assert.notBlank(dateStr, "Date String must be not blank !"); + try { + return parser.parse(dateStr); + } catch (Exception e) { + throw new DateException("Parse [{}] with format [{}] error!", dateStr, parser.getPattern(), e); + } + } + + /** + * 设置日期时间 + * + * @param time 日期时间毫秒 + * @return this + */ + private DateTime setTimeInternal(long time) { + super.setTime(time); + return this; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUnit.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUnit.java new file mode 100644 index 0000000..1fd507e --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUnit.java @@ -0,0 +1,33 @@ +package org.springblade.core.tool.date; + +/** + * 日期时间单位,每个单位都是以毫秒为基数 + * @author Looly + * + */ +public enum DateUnit { + /** 一毫秒 */ + MS(1), + /** 一秒的毫秒数 */ + SECOND(1000), + /**一分钟的毫秒数 */ + MINUTE(SECOND.getMillis() * 60), + /**一小时的毫秒数 */ + HOUR(MINUTE.getMillis() * 60), + /**一天的毫秒数 */ + DAY(HOUR.getMillis() * 24), + /**一周的毫秒数 */ + WEEK(DAY.getMillis() * 7); + + private long millis; + DateUnit(long millis){ + this.millis = millis; + } + + /** + * @return 单位对应的毫秒数 + */ + public long getMillis(){ + return this.millis; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUtil.java new file mode 100644 index 0000000..b37d6c4 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/DateUtil.java @@ -0,0 +1,1471 @@ +package org.springblade.core.tool.date; + +import org.springblade.core.tool.date.format.DateParser; +import org.springblade.core.tool.date.format.DatePrinter; +import org.springblade.core.tool.date.format.FastDateFormat; +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.Exceptions; +import org.springblade.core.tool.utils.StringPool; +import org.springblade.core.tool.utils.StringUtil; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 时间工具类 + * + * @author xiaoleilu + */ +public class DateUtil { + + /** + * 转换为{@link DateTime}对象 + * + * @return 当前时间 + */ + public static DateTime date() { + return new DateTime(); + } + + /** + * {@link Date}类型时间转为{@link DateTime} + * + * @param date Long类型Date(Unix时间戳) + * @return 时间对象 + * @since 3.0.7 + */ + public static DateTime date(Date date) { + if (date instanceof DateTime) { + return (DateTime) date; + } + return new DateTime(date); + } + + /** + * Long类型时间转为{@link DateTime}
+ * 同时支持10位秒级别时间戳和13位毫秒级别时间戳 + * + * @param date Long类型Date(Unix时间戳) + * @return 时间对象 + */ + public static DateTime date(long date) { + return new DateTime(date); + } + + /** + * {@link Calendar}类型时间转为{@link DateTime} + * + * @param calendar {@link Calendar} + * @return 时间对象 + */ + public static DateTime date(Calendar calendar) { + return new DateTime(calendar); + } + + /** + * 转换为Calendar对象 + * + * @param date 日期对象 + * @return Calendar对象 + */ + public static Calendar calendar(Date date) { + return calendar(date.getTime()); + } + + /** + * 转换为Calendar对象 + * + * @param millis 时间戳 + * @return Calendar对象 + */ + public static Calendar calendar(long millis) { + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(millis); + return cal; + } + + /** + * 当前时间,格式 yyyy-MM-dd HH:mm:ss + * + * @return 当前时间的标准形式字符串 + */ + public static String now() { + return formatDateTime(new DateTime()); + } + + /** + * 当前时间long + * + * @param isNano 是否为高精度时间 + * @return 时间 + */ + public static long current(boolean isNano) { + return isNano ? System.nanoTime() : System.currentTimeMillis(); + } + + /** + * 当前时间秒数 + * + * @return 当前时间秒数 + * @since 4.0.0 + */ + public static long currentSeconds() { + return System.currentTimeMillis() / 1000; + } + + /** + * 当前日期,格式 yyyy-MM-dd + * + * @return 当前日期的标准形式字符串 + */ + public static String today() { + return formatDate(new DateTime()); + } + + // -------------------------------------------------------------- Part of Date start + /** + * 获得年的部分 + * + * @param date 日期 + * @return 年的部分 + */ + public static int year(Date date) { + return DateTime.of(date).year(); + } + + /** + * 获得指定日期所属季节 + * + * @param date 日期 + * @return 第几个季节 + */ + public static int season(Date date) { + return DateTime.of(date).season(); + } + + /** + * 获得月份,从0开始计数 + * + * @param date 日期 + * @return 月份,从0开始计数 + */ + public static int month(Date date) { + return DateTime.of(date).month(); + } + + /** + * 获得月份 + * + * @param date 日期 + * @return {@link Month} + */ + public static Month monthEnum(Date date) { + return DateTime.of(date).monthEnum(); + } + + /** + * 获得指定日期是所在年份的第几周
+ * + * @param date 日期 + * @return 周 + */ + public static int weekOfYear(Date date) { + return DateTime.of(date).weekOfYear(); + } + + /** + * 获得指定日期是所在月份的第几周
+ * + * @param date 日期 + * @return 周 + */ + public static int weekOfMonth(Date date) { + return DateTime.of(date).weekOfMonth(); + } + + /** + * 获得指定日期是这个日期所在月份的第几天
+ * + * @param date 日期 + * @return 天 + */ + public static int dayOfMonth(Date date) { + return DateTime.of(date).dayOfMonth(); + } + + /** + * 获得指定日期是星期几,1表示周日,2表示周一 + * + * @param date 日期 + * @return 天 + */ + public static int dayOfWeek(Date date) { + return DateTime.of(date).dayOfWeek(); + } + + /** + * 获得指定日期是星期几 + * + * @param date 日期 + * @return {@link Week} + */ + public static Week dayOfWeekEnum(Date date) { + return DateTime.of(date).dayOfWeekEnum(); + } + + /** + * 获得指定日期的小时数部分
+ * + * @param date 日期 + * @param is24HourClock 是否24小时制 + * @return 小时数 + */ + public static int hour(Date date, boolean is24HourClock) { + return DateTime.of(date).hour(is24HourClock); + } + + /** + * 获得指定日期的分钟数部分
+ * 例如:10:04:15.250 =》 4 + * + * @param date 日期 + * @return 分钟数 + */ + public static int minute(Date date) { + return DateTime.of(date).minute(); + } + + /** + * 获得指定日期的秒数部分
+ * + * @param date 日期 + * @return 秒数 + */ + public static int second(Date date) { + return DateTime.of(date).second(); + } + + /** + * 获得指定日期的毫秒数部分
+ * + * @param date 日期 + * @return 毫秒数 + */ + public static int millsecond(Date date) { + return DateTime.of(date).millsecond(); + } + + /** + * 是否为上午 + * + * @param date 日期 + * @return 是否为上午 + */ + public static boolean isAM(Date date) { + return DateTime.of(date).isAM(); + } + + /** + * 是否为下午 + * + * @param date 日期 + * @return 是否为下午 + */ + public static boolean isPM(Date date) { + return DateTime.of(date).isPM(); + } + + /** + * @return 今年 + */ + public static int thisYear() { + return year(date()); + } + + /** + * @return 当前月份 + */ + public static int thisMonth() { + return month(date()); + } + + /** + * @return 当前月份 {@link Month} + */ + public static Month thisMonthEnum() { + return monthEnum(date()); + } + + /** + * @return 当前日期所在年份的第几周 + */ + public static int thisWeekOfYear() { + return weekOfYear(date()); + } + + /** + * @return 当前日期所在年份的第几周 + */ + public static int thisWeekOfMonth() { + return weekOfMonth(date()); + } + + /** + * @return 当前日期是这个日期所在月份的第几天 + */ + public static int thisDayOfMonth() { + return dayOfMonth(date()); + } + + /** + * @return 当前日期是星期几 + */ + public static int thisDayOfWeek() { + return dayOfWeek(date()); + } + + /** + * @return 当前日期是星期几 {@link Week} + */ + public static Week thisDayOfWeekEnum() { + return dayOfWeekEnum(date()); + } + + /** + * @param is24HourClock 是否24小时制 + * @return 当前日期的小时数部分
+ */ + public static int thisHour(boolean is24HourClock) { + return hour(date(), is24HourClock); + } + + /** + * @return 当前日期的分钟数部分
+ */ + public static int thisMinute() { + return minute(date()); + } + + /** + * @return 当前日期的秒数部分
+ */ + public static int thisSecond() { + return second(date()); + } + + /** + * @return 当前日期的毫秒数部分
+ */ + public static int thisMillsecond() { + return millsecond(date()); + } + // -------------------------------------------------------------- Part of Date end + + /** + * 获得指定日期年份和季节
+ * 格式:[20131]表示2013年第一季度 + * + * @param date 日期 + * @return Season ,类似于 20132 + */ + public static String yearAndSeason(Date date) { + return yearAndSeason(calendar(date)); + } + + /** + * 获得指定日期区间内的年份和季节
+ * + * @param startDate 起始日期(包含) + * @param endDate 结束日期(包含) + * @return Season列表 ,元素类似于 20132 + */ + public static LinkedHashSet yearAndSeasons(Date startDate, Date endDate) { + final LinkedHashSet seasons = new LinkedHashSet(); + if (startDate == null || endDate == null) { + return seasons; + } + + final Calendar cal = Calendar.getInstance(); + cal.setTime(startDate); + while (true) { + // 如果开始时间超出结束时间,让结束时间为开始时间,处理完后结束循环 + if (startDate.after(endDate)) { + startDate = endDate; + } + + seasons.add(yearAndSeason(cal)); + + if (startDate.equals(endDate)) { + break; + } + + cal.add(Calendar.MONTH, 3); + startDate = cal.getTime(); + } + + return seasons; + } + + // ------------------------------------ Format start ---------------------------------------------- + /** + * 根据特定格式格式化日期 + * + * @param date 被格式化的日期 + * @param format 日期格式,常用格式见: {@link DatePattern} + * @return 格式化后的字符串 + */ + public static String format(Date date, String format) { + if(null == date || StringUtil.isBlank(format)) { + return null; + } + return format(date, FastDateFormat.getInstance(format)); + } + + /** + * 根据特定格式格式化日期 + * + * @param date 被格式化的日期 + * @param format {@link DatePrinter} 或 {@link FastDateFormat} + * @return 格式化后的字符串 + */ + public static String format(Date date, DatePrinter format) { + if(null == format || null == date) { + return null; + } + return format.format(date); + } + + /** + * 根据特定格式格式化日期 + * + * @param date 被格式化的日期 + * @param format {@link SimpleDateFormat} + * @return 格式化后的字符串 + */ + public static String format(Date date, DateFormat format) { + if(null == format || null == date) { + return null; + } + return format.format(date); + } + + /** + * 格式化日期时间
+ * 格式 yyyy-MM-dd HH:mm:ss + * + * @param date 被格式化的日期 + * @return 格式化后的日期 + */ + public static String formatDateTime(Date date) { + if (null == date) { + return null; + } + return DatePattern.NORM_DATETIME_FORMAT.format(date); + } + + /** + * 格式化日期部分(不包括时间)
+ * 格式 yyyy-MM-dd + * + * @param date 被格式化的日期 + * @return 格式化后的字符串 + */ + public static String formatDate(Date date) { + if (null == date) { + return null; + } + return DatePattern.NORM_DATE_FORMAT.format(date); + } + + /** + * 格式化时间
+ * 格式 HH:mm:ss + * + * @param date 被格式化的日期 + * @return 格式化后的字符串 + * @since 3.0.1 + */ + public static String formatTime(Date date) { + if (null == date) { + return null; + } + return DatePattern.NORM_TIME_FORMAT.format(date); + } + + /** + * 格式化为Http的标准日期格式 + * + * @param date 被格式化的日期 + * @return HTTP标准形式日期字符串 + */ + public static String formatHttpDate(Date date) { + if (null == date) { + return null; + } + return DatePattern.HTTP_DATETIME_FORMAT.format(date); + } + // ------------------------------------ Format end ---------------------------------------------- + + // ------------------------------------ Parse start ---------------------------------------------- + + /** + * 构建DateTime对象 + * + * @param dateStr Date字符串 + * @param dateFormat 格式化器 {@link SimpleDateFormat} + * @return DateTime对象 + */ + public static DateTime parse(String dateStr, DateFormat dateFormat) { + return new DateTime(dateStr, dateFormat); + } + + /** + * 构建DateTime对象 + * + * @param dateStr Date字符串 + * @param parser 格式化器,{@link FastDateFormat} + * @return DateTime对象 + */ + public static DateTime parse(String dateStr, DateParser parser) { + return new DateTime(dateStr, parser); + } + + /** + * 将特定格式的日期转换为Date对象 + * + * @param dateStr 特定格式的日期 + * @param format 格式,例如yyyy-MM-dd + * @return 日期对象 + */ + public static DateTime parse(String dateStr, String format) { + return new DateTime(dateStr, format); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param format ConcurrentDateFormat + * @return 时间 + */ + public static Date parse(String dateStr, ConcurrentDateFormat format) { + try { + return format.parse(dateStr); + } catch (ParseException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 格式yyyy-MM-dd HH:mm:ss + * + * @param dateString 标准形式的时间字符串 + * @return 日期对象 + */ + public static DateTime parseDateTime(String dateString) { + dateString = normalize(dateString); + return parse(dateString, DatePattern.NORM_DATETIME_FORMAT); + } + + /** + * 格式yyyy-MM-dd + * + * @param dateString 标准形式的日期字符串 + * @return 日期对象 + */ + public static DateTime parseDate(String dateString) { + dateString = normalize(dateString); + return parse(dateString, DatePattern.NORM_DATE_FORMAT); + } + + /** + * 解析时间,格式HH:mm:ss,默认为1970-01-01 + * + * @param timeString 标准形式的日期字符串 + * @return 日期对象 + */ + public static DateTime parseTime(String timeString) { + timeString = normalize(timeString); + return parse(timeString, DatePattern.NORM_TIME_FORMAT); + } + + /** + * 解析时间,格式HH:mm:ss,日期默认为今天 + * + * @param timeString 标准形式的日期字符串 + * @return 日期对象 + * @since 3.1.1 + */ + public static DateTime parseTimeToday(String timeString) { + timeString = StringUtil.format("{} {}", today(), timeString); + return parse(timeString, DatePattern.NORM_TIME_FORMAT); + } + + /** + * 将日期字符串转换为{@link DateTime}对象,格式:
+ *
    + *
  1. yyyy-MM-dd HH:mm:ss
  2. + *
  3. yyyy/MM/dd HH:mm:ss
  4. + *
  5. yyyy.MM.dd HH:mm:ss
  6. + *
  7. yyyy年MM月dd日 HH时mm分ss秒
  8. + *
  9. yyyy-MM-dd
  10. + *
  11. yyyy/MM/dd
  12. + *
  13. yyyy.MM.dd
  14. + *
  15. HH:mm:ss
  16. + *
  17. HH时mm分ss秒
  18. + *
  19. yyyy-MM-dd HH:mm
  20. + *
  21. yyyy-MM-dd HH:mm:ss.SSS
  22. + *
  23. yyyyMMddHHmmss
  24. + *
  25. yyyyMMddHHmmssSSS
  26. + *
  27. yyyyMMdd
  28. + *
+ * + * @param dateStr 日期字符串 + * @return 日期 + */ + public static DateTime parse(String dateStr) { + if (null == dateStr) { + return null; + } + //去掉两边空格并去掉中文日期中的“日”,以规范长度 + dateStr = dateStr.trim().replace("日", ""); + int length = dateStr.length(); + + if(Func.isNumeric(dateStr)) { + //纯数字形式 + if(length == DatePattern.PURE_DATETIME_PATTERN.length()) { + return parse(dateStr, DatePattern.PURE_DATETIME_FORMAT); + } else if(length == DatePattern.PURE_DATETIME_MS_PATTERN.length()) { + return parse(dateStr, DatePattern.PURE_DATETIME_MS_FORMAT); + } else if(length == DatePattern.PURE_DATE_PATTERN.length()) { + return parse(dateStr, DatePattern.PURE_DATE_FORMAT); + } else if(length == DatePattern.PURE_TIME_PATTERN.length()) { + return parse(dateStr, DatePattern.PURE_TIME_FORMAT); + } + } + + if (length == DatePattern.NORM_DATETIME_PATTERN.length() || length == DatePattern.NORM_DATETIME_PATTERN.length()+1) { + return parseDateTime(dateStr); + } else if (length == DatePattern.NORM_DATE_PATTERN.length()) { + return parseDate(dateStr); + } else if (length == DatePattern.NORM_TIME_PATTERN.length() || length == DatePattern.NORM_TIME_PATTERN.length()+1) { + return parseTime(dateStr); + } else if (length == DatePattern.NORM_DATETIME_MINUTE_PATTERN.length() || length == DatePattern.NORM_DATETIME_MINUTE_PATTERN.length()+1) { + return parse(normalize(dateStr), DatePattern.NORM_DATETIME_MINUTE_PATTERN); + } else if (length >= DatePattern.NORM_DATETIME_MS_PATTERN.length() - 2) { + return parse(normalize(dateStr), DatePattern.NORM_DATETIME_MS_PATTERN); + } + + // 没有更多匹配的时间格式 + throw new DateException("No format fit for date String [{}] !", dateStr); + } + + // ------------------------------------ Parse end ---------------------------------------------- + + // ------------------------------------ Offset start ---------------------------------------------- + /** + * 获取某天的开始时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime beginOfDay(Date date) { + return new DateTime(beginOfDay(calendar(date))); + } + + /** + * 获取某天的结束时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime endOfDay(Date date) { + return new DateTime(endOfDay(calendar(date))); + } + + /** + * 获取某天的开始时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar beginOfDay(Calendar calendar) { + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar; + } + + /** + * 获取某天的结束时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar endOfDay(Calendar calendar) { + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar; + } + + /** + * 获取某周的开始时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime beginOfWeek(Date date) { + return new DateTime(beginOfWeek(calendar(date))); + } + + /** + * 获取某周的结束时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime endOfWeek(Date date) { + return new DateTime(endOfWeek(calendar(date))); + } + + /** + * 获取某周的开始时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar beginOfWeek(Calendar calendar) { + return beginOfWeek(calendar, true); + } + + /** + * 获取某周的开始时间,周一定为一周的开始时间 + * + * @param calendar 日期 {@link Calendar} + * @param isMondayAsFirstDay 是否周一做为一周的第一天(false表示周日做为第一天) + * @return {@link Calendar} + * @since 3.1.2 + */ + public static Calendar beginOfWeek(Calendar calendar, boolean isMondayAsFirstDay) { + if(isMondayAsFirstDay) { + //设置周一为一周开始 + calendar.setFirstDayOfWeek(Week.MONDAY.getValue()); + calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + }else { + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + } + return beginOfDay(calendar); + } + + /** + * 获取某周的结束时间,周日定为一周的结束 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar endOfWeek(Calendar calendar) { + return endOfWeek(calendar, true); + } + + /** + * 获取某周的结束时间 + * + * @param calendar 日期 {@link Calendar} + * @param isSundayAsLastDay 是否周日做为一周的最后一天(false表示周六做为最后一天) + * @return {@link Calendar} + * @since 3.1.2 + */ + public static Calendar endOfWeek(Calendar calendar, boolean isSundayAsLastDay) { + if(isSundayAsLastDay) { + //设置周一为一周开始 + calendar.setFirstDayOfWeek(Week.MONDAY.getValue()); + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + }else { + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY); + } + return endOfDay(calendar); + } + + /** + * 获取某月的开始时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime beginOfMonth(Date date) { + return new DateTime(beginOfMonth(calendar(date))); + } + + /** + * 获取某月的结束时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime endOfMonth(Date date) { + return new DateTime(endOfMonth(calendar(date))); + } + + /** + * 获取某月的开始时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar beginOfMonth(Calendar calendar) { + calendar.set(Calendar.DAY_OF_MONTH, 1); + return beginOfDay(calendar); + } + + /** + * 获取某月的结束时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar endOfMonth(Calendar calendar) { + calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + return endOfDay(calendar); + } + + /** + * 获取某年的开始时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime beginOfYear(Date date) { + return new DateTime(beginOfYear(calendar(date))); + } + + /** + * 获取某年的结束时间 + * + * @param date 日期 + * @return {@link DateTime} + */ + public static DateTime endOfYear(Date date) { + return new DateTime(endOfYear(calendar(date))); + } + + /** + * 获取某年的开始时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar beginOfYear(Calendar calendar) { + calendar.set(Calendar.MONTH, Calendar.JANUARY); + return beginOfMonth(calendar); + } + + /** + * 获取某年的结束时间 + * + * @param calendar 日期 {@link Calendar} + * @return {@link Calendar} + */ + public static Calendar endOfYear(Calendar calendar) { + calendar.set(Calendar.MONTH, Calendar.DECEMBER); + return endOfMonth(calendar); + } + + // --------------------------------------------------- Offset for now + /** + * 昨天 + * + * @return 昨天 + */ + public static DateTime yesterday() { + return offsetDay(new DateTime(), -1); + } + + /** + * 明天 + * + * @return 明天 + * @since 3.0.1 + */ + public static DateTime tomorrow() { + return offsetDay(new DateTime(), 1); + } + + /** + * 上周 + * + * @return 上周 + */ + public static DateTime lastWeek() { + return offsetWeek(new DateTime(), -1); + } + + /** + * 下周 + * + * @return 下周 + * @since 3.0.1 + */ + public static DateTime nextWeek() { + return offsetWeek(new DateTime(), 1); + } + + /** + * 上个月 + * + * @return 上个月 + */ + public static DateTime lastMonth() { + return offsetMonth(new DateTime(), -1); + } + + /** + * 下个月 + * + * @return 下个月 + * @since 3.0.1 + */ + public static DateTime nextMonth() { + return offsetMonth(new DateTime(), 1); + } + + /** + * 偏移毫秒数 + * + * @param date 日期 + * @param offset 偏移毫秒数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetMillisecond(Date date, int offset) { + return offset(date, DateField.MILLISECOND, offset); + } + + /** + * 偏移秒数 + * + * @param date 日期 + * @param offset 偏移秒数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetSecond(Date date, int offset) { + return offset(date, DateField.SECOND, offset); + } + + /** + * 偏移分钟 + * + * @param date 日期 + * @param offset 偏移分钟数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetMinute(Date date, int offset) { + return offset(date, DateField.MINUTE, offset); + } + + /** + * 偏移小时 + * + * @param date 日期 + * @param offset 偏移小时数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetHour(Date date, int offset) { + return offset(date, DateField.HOUR_OF_DAY, offset); + } + + /** + * 偏移天 + * + * @param date 日期 + * @param offset 偏移天数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetDay(Date date, int offset) { + return offset(date, DateField.DAY_OF_YEAR, offset); + } + + /** + * 偏移周 + * + * @param date 日期 + * @param offset 偏移周数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetWeek(Date date, int offset) { + return offset(date, DateField.WEEK_OF_YEAR, offset); + } + + /** + * 偏移月 + * + * @param date 日期 + * @param offset 偏移月数,正数向未来偏移,负数向历史偏移 + * @return 偏移后的日期 + */ + public static DateTime offsetMonth(Date date, int offset) { + return offset(date, DateField.MONTH, offset); + } + + /** + * 获取指定日期偏移指定时间后的时间 + * + * @param date 基准日期 + * @param dateField 偏移的粒度大小(小时、天、月等){@link DateField} + * @param offset 偏移量,正数为向后偏移,负数为向前偏移 + * @return 偏移后的日期 + */ + public static DateTime offset(Date date, DateField dateField, int offset) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(dateField.getValue(), offset); + return new DateTime(cal.getTime()); + } + + /** + * 获取指定日期偏移指定时间后的时间 + * + * @param date 基准日期 + * @param dateField 偏移的粒度大小(小时、天、月等){@link DateField} + * @param offset 偏移量,正数为向后偏移,负数为向前偏移 + * @return 偏移后的日期 + * @deprecated please use {@link DateUtil#offset(Date, DateField, int)} + */ + @Deprecated + public static DateTime offsetDate(Date date, DateField dateField, int offset) { + return offset(date, dateField, offset); + } + // ------------------------------------ Offset end ---------------------------------------------- + + /** + * 判断两个日期相差的时长,只保留绝对值 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param unit 相差的单位:相差 天{@link DateUnit#DAY}、小时{@link DateUnit#HOUR} 等 + * @return 日期差 + */ + public static long between(Date beginDate, Date endDate, DateUnit unit) { + return between(beginDate, endDate, unit, true); + } + + /** + * 判断两个日期相差的时长 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param unit 相差的单位:相差 天{@link DateUnit#DAY}、小时{@link DateUnit#HOUR} 等 + * @param isAbs 日期间隔是否只保留绝对值正数 + * @return 日期差 + * @since 3.3.1 + */ + public static long between(Date beginDate, Date endDate, DateUnit unit, boolean isAbs) { + return new DateBetween(beginDate, endDate, isAbs).between(unit); + } + + /** + * 判断两个日期相差的毫秒数 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @return 日期差 + * @since 3.0.1 + */ + public static long betweenMs(Date beginDate, Date endDate) { + return new DateBetween(beginDate, endDate).between(DateUnit.MS); + } + + /** + * 判断两个日期相差的天数
+ * + *
+	 * 有时候我们计算相差天数的时候需要忽略时分秒。
+	 * 比如:2016-02-01 23:59:59和2016-02-02 00:00:00相差一秒
+	 * 如果isReset为false相差天数为0。
+	 * 如果isReset为true相差天数将被计算为1
+	 * 
+ * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param isReset 是否重置时间为起始时间 + * @return 日期差 + * @since 3.0.1 + */ + public static long betweenDay(Date beginDate, Date endDate, boolean isReset) { + if (isReset) { + beginDate = beginOfDay(beginDate); + endDate = beginOfDay(endDate); + } + return between(beginDate, endDate, DateUnit.DAY); + } + + /** + * 计算两个日期相差月数
+ * 在非重置情况下,如果起始日期的天小于结束日期的天,月数要少算1(不足1个月) + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param isReset 是否重置时间为起始时间(重置天时分秒) + * @return 相差月数 + * @since 3.0.8 + */ + public static long betweenMonth(Date beginDate, Date endDate, boolean isReset) { + return new DateBetween(beginDate, endDate).betweenMonth(isReset); + } + + /** + * 计算两个日期相差年数
+ * 在非重置情况下,如果起始日期的月小于结束日期的月,年数要少算1(不足1年) + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param isReset 是否重置时间为起始时间(重置月天时分秒) + * @return 相差年数 + * @since 3.0.8 + */ + public static long betweenYear(Date beginDate, Date endDate, boolean isReset) { + return new DateBetween(beginDate, endDate).betweenYear(isReset); + } + + /** + * 格式化日期间隔输出 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @param level 级别,按照天、小时、分、秒、毫秒分为5个等级 + * @return XX天XX小时XX分XX秒 + */ + public static String formatBetween(Date beginDate, Date endDate, BetweenFormater.Level level) { + return formatBetween(between(beginDate, endDate, DateUnit.MS), level); + } + + /** + * 格式化日期间隔输出,精确到毫秒 + * + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @return XX天XX小时XX分XX秒 + * @since 3.0.1 + */ + public static String formatBetween(Date beginDate, Date endDate) { + return formatBetween(between(beginDate, endDate, DateUnit.MS)); + } + + /** + * 格式化日期间隔输出 + * + * @param betweenMs 日期间隔 + * @param level 级别,按照天、小时、分、秒、毫秒分为5个等级 + * @return XX天XX小时XX分XX秒XX毫秒 + */ + public static String formatBetween(long betweenMs, BetweenFormater.Level level) { + return new BetweenFormater(betweenMs, level).format(); + } + + /** + * 格式化日期间隔输出,精确到毫秒 + * + * @param betweenMs 日期间隔 + * @return XX天XX小时XX分XX秒XX毫秒 + * @since 3.0.1 + */ + public static String formatBetween(long betweenMs) { + return new BetweenFormater(betweenMs, BetweenFormater.Level.MILLSECOND).format(); + } + + /** + * 当前日期是否在日期指定范围内
+ * 起始日期和结束日期可以互换 + * + * @param date 被检查的日期 + * @param beginDate 起始日期 + * @param endDate 结束日期 + * @return 是否在范围内 + * @since 3.0.8 + */ + public static boolean isIn(Date date, Date beginDate, Date endDate) { + if (date instanceof DateTime) { + return ((DateTime) date).isIn(beginDate, endDate); + } else { + return new DateTime(date).isIn(beginDate, endDate); + } + } + + /** + * 计时,常用于记录某段代码的执行时间,单位:纳秒 + * + * @param preTime 之前记录的时间 + * @return 时间差,纳秒 + */ + public static long spendNt(long preTime) { + return System.nanoTime() - preTime; + } + + /** + * 计时,常用于记录某段代码的执行时间,单位:毫秒 + * + * @param preTime 之前记录的时间 + * @return 时间差,毫秒 + */ + public static long spendMs(long preTime) { + return System.currentTimeMillis() - preTime; + } + + /** + * 格式化成yyMMddHHmm后转换为int型 + * + * @param date 日期 + * @return int + */ + public static int toIntSecond(Date date) { + return Integer.parseInt(DateUtil.format(date, "yyMMddHHmm")); + } + + /** + * 计算指定指定时间区间内的周数 + * + * @param start 开始时间 + * @param end 结束时间 + * @return 周数 + */ + public static int weekCount(Date start, Date end) { + final Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(start); + final Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(end); + + final int startWeekofYear = startCalendar.get(Calendar.WEEK_OF_YEAR); + final int endWeekofYear = endCalendar.get(Calendar.WEEK_OF_YEAR); + + int count = endWeekofYear - startWeekofYear + 1; + + if (Calendar.SUNDAY != startCalendar.get(Calendar.DAY_OF_WEEK)) { + count--; + } + + return count; + } + + /** + * 计时器
+ * 计算某个过程花费的时间,精确到毫秒 + * + * @return Timer + */ + public static TimeInterval timer() { + return new TimeInterval(); + + } + + /** + * 生日转为年龄,计算法定年龄 + * + * @param birthDay 生日,标准日期字符串 + * @return 年龄 + */ + public static int ageOfNow(String birthDay) { + return ageOfNow(parse(birthDay)); + } + + /** + * 生日转为年龄,计算法定年龄 + * + * @param birthDay 生日 + * @return 年龄 + */ + public static int ageOfNow(Date birthDay) { + return age(birthDay, date()); + } + + /** + * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄 + * + * @param birthDay 生日 + * @param dateToCompare 需要对比的日期 + * @return 年龄 + */ + public static int age(Date birthDay, Date dateToCompare) { + Calendar cal = Calendar.getInstance(); + cal.setTime(dateToCompare); + + if (cal.before(birthDay)) { + throw new IllegalArgumentException(StringUtil.format("Birthday is after date {}!", formatDate(dateToCompare))); + } + + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); + + cal.setTime(birthDay); + int age = year - cal.get(Calendar.YEAR); + + int monthBirth = cal.get(Calendar.MONTH); + if (month == monthBirth) { + int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH); + if (dayOfMonth < dayOfMonthBirth) { + // 如果生日在当月,但是未达到生日当天的日期,年龄减一 + age--; + } + } else if (month < monthBirth) { + // 如果当前月份未达到生日的月份,年龄计算减一 + age--; + } + + return age; + } + + /** + * 是否闰年 + * + * @param year 年 + * @return 是否闰年 + */ + public static boolean isLeapYear(int year) { + return new GregorianCalendar().isLeapYear(year); + } + + /** + * 判定给定开始时间经过某段时间后是否过期 + * + * @param startDate 开始时间 + * @param dateField 时间单位 + * @param timeLength 时长 + * @param checkedDate 被比较的时间。如果经过时长后的时间晚于被检查的时间,就表示过期 + * @return 是否过期 + * @since 3.1.1 + */ + public static boolean isExpired(Date startDate, DateField dateField, int timeLength, Date checkedDate) { + final Date endDate = offset(startDate, dateField, timeLength); + return endDate.after(checkedDate); + } + + /** + * 时间格式字符串转为秒数
+ * 参考:https://github.com/iceroot + * + * @param timeStr 字符串时分秒(HH:mm:ss)格式 + * @return 时分秒转换后的秒数 + * @since 3.1.2 + */ + public static int timeToSecond(String timeStr) { + if(StringUtil.isEmpty(timeStr)) { + return 0; + } + + final List hms = StringUtil.splitTrim(timeStr, StringPool.COLON, 3); + int lastIndex = hms.size() - 1; + + int result = 0; + for(int i = lastIndex; i >= 0; i--) { + result += Integer.parseInt(hms.get(i)) * Math.pow(60, (lastIndex - i)); + } + return result; + } + + /** + * 秒数转为时间格式(HH:mm:ss)
+ * 参考:https://github.com/iceroot + * + * @param seconds 需要转换的秒数 + * @return 转换后的字符串 + * @since 3.1.2 + */ + public static String secondToTime(int seconds) { + if(seconds < 0) { + throw new IllegalArgumentException("Seconds must be a positive number!"); + } + + int hour = seconds / 3600; + int other = seconds % 3600; + int minute = other / 60; + int second = other % 60; + final StringBuilder sb = new StringBuilder(); + if (hour < 10) { + sb.append("0"); + } + sb.append(hour); + sb.append(":"); + if (minute < 10) { + sb.append("0"); + } + sb.append(minute); + sb.append(":"); + if (second < 10) { + sb.append("0"); + } + sb.append(second); + return sb.toString(); + } + + // ------------------------------------------------------------------------ Private method start + /** + * 获得指定日期年份和季节
+ * 格式:[20131]表示2013年第一季度 + * + * @param cal 日期 + */ + private static String yearAndSeason(Calendar cal) { + return new StringBuilder().append(cal.get(Calendar.YEAR)).append(cal.get(Calendar.MONTH) / 3 + 1).toString(); + } + + /** + * 标准化日期,默认处理以空格区分的日期时间格式,空格前为日期,空格后为时间:
+ * 将以下字符替换为"-" + *
+	 * "."
+	 * "/"
+	 * "年"
+	 * "月"
+	 * 
+ * + * 将以下字符去除 + *
+	 * "日"
+	 * 
+ * + * 将以下字符替换为":" + *
+	 * "时"
+	 * "分"
+	 * "秒"
+	 * 
+ * 当末位是":"时去除之(不存在毫秒时) + * + * @param dateStr 日期时间字符串 + * @return 格式化后的日期字符串 + */ + private static String normalize(String dateStr) { + if(StringUtil.isBlank(dateStr)) { + return dateStr; + } + + //日期时间分开处理 + final List dateAndTime = StringUtil.splitTrim(dateStr, ' '); + final int size = dateAndTime.size(); + if(size < 1 || size > 2) { + //非可被标准处理的格式 + return dateStr; + } + + final StringBuilder builder = new StringBuilder(); + + //日期部分("\"、"/"、"."、"年"、"月"都替换为"-") + String datePart = dateAndTime.get(0).replaceAll("[\\/.年月]", "-"); + datePart = StringUtil.removeSuffix(datePart, "日"); + builder.append(datePart); + + //时间部分 + if(size == 2) { + builder.append(' '); + String timePart = dateAndTime.get(1).replaceAll("[时分秒]", ":"); + timePart = StringUtil.removeSuffix(timePart, ":"); + builder.append(timePart); + } + + return builder.toString(); + } + // ------------------------------------------------------------------------ Private method end +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/Month.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Month.java new file mode 100644 index 0000000..f4358bf --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Month.java @@ -0,0 +1,118 @@ +package org.springblade.core.tool.date; + +import java.util.Calendar; + +/** + * 月份枚举
+ * 与Calendar中的月份int值对应 + * + * @see Calendar#JANUARY + * @see Calendar#FEBRUARY + * @see Calendar#MARCH + * @see Calendar#APRIL + * @see Calendar#MAY + * @see Calendar#JUNE + * @see Calendar#JULY + * @see Calendar#AUGUST + * @see Calendar#SEPTEMBER + * @see Calendar#OCTOBER + * @see Calendar#NOVEMBER + * @see Calendar#DECEMBER + * @see Calendar#UNDECIMBER + * + * @author Looly + * + */ +public enum Month { + + /** 一月 */ + JANUARY(Calendar.JANUARY), + /** 二月 */ + FEBRUARY(Calendar.FEBRUARY), + /** 三月 */ + MARCH(Calendar.MARCH), + /** 四月 */ + APRIL(Calendar.APRIL), + /** 五月 */ + MAY(Calendar.MAY), + /** 六月 */ + JUNE(Calendar.JUNE), + /** 七月 */ + JULY(Calendar.JULY), + /** 八月 */ + AUGUST(Calendar.AUGUST), + /** 九月 */ + SEPTEMBER(Calendar.SEPTEMBER), + /** 十月 */ + OCTOBER(Calendar.OCTOBER), + /** 十一月 */ + NOVEMBER(Calendar.NOVEMBER), + /** 十二月 */ + DECEMBER(Calendar.DECEMBER), + /** 十三月,仅用于农历 */ + UNDECIMBER(Calendar.UNDECIMBER); + + // --------------------------------------------------------------- + private int value; + + private Month(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + /** + * 将 {@link Calendar}月份相关值转换为Month枚举对象
+ * + * @see Calendar#JANUARY + * @see Calendar#FEBRUARY + * @see Calendar#MARCH + * @see Calendar#APRIL + * @see Calendar#MAY + * @see Calendar#JUNE + * @see Calendar#JULY + * @see Calendar#AUGUST + * @see Calendar#SEPTEMBER + * @see Calendar#OCTOBER + * @see Calendar#NOVEMBER + * @see Calendar#DECEMBER + * @see Calendar#UNDECIMBER + * + * @param calendarMonthIntValue Calendar中关于Month的int值 + * @return {@link Month} + */ + public static Month of(int calendarMonthIntValue) { + switch (calendarMonthIntValue) { + case Calendar.JANUARY: + return JANUARY; + case Calendar.FEBRUARY: + return FEBRUARY; + case Calendar.MARCH: + return MARCH; + case Calendar.APRIL: + return APRIL; + case Calendar.MAY: + return MAY; + case Calendar.JUNE: + return JUNE; + case Calendar.JULY: + return JULY; + case Calendar.AUGUST: + return AUGUST; + case Calendar.SEPTEMBER: + return SEPTEMBER; + case Calendar.OCTOBER: + return OCTOBER; + case Calendar.NOVEMBER: + return NOVEMBER; + case Calendar.DECEMBER: + return DECEMBER; + case Calendar.UNDECIMBER: + return UNDECIMBER; + default: + return null; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/Season.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Season.java new file mode 100644 index 0000000..9cb0e75 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Season.java @@ -0,0 +1,61 @@ +package org.springblade.core.tool.date; + +/** + * 季度枚举
+ * + * @see #SPRING + * @see #SUMMER + * @see #AUTUMN + * @see #WINTER + * + * @author Looly + * + */ +public enum Season { + + /** 春季(第一季度) */ + SPRING(1), + /** 夏季(第二季度) */ + SUMMER(2), + /** 秋季(第三季度) */ + AUTUMN(3), + /** 冬季(第四季度) */ + WINTER(4); + + // --------------------------------------------------------------- + private int value; + + private Season(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + /** + * 将 季度int转换为Season枚举对象
+ * + * @see #SPRING + * @see #SUMMER + * @see #AUTUMN + * @see #WINTER + * + * @param intValue 季度int表示 + * @return {@link Season} + */ + public static Season of(int intValue) { + switch (intValue) { + case 1: + return SPRING; + case 2: + return SUMMER; + case 3: + return AUTUMN; + case 4: + return WINTER; + default: + return null; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/SystemClock.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/SystemClock.java new file mode 100644 index 0000000..2841904 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/SystemClock.java @@ -0,0 +1,94 @@ +package org.springblade.core.tool.date; + +import java.sql.Timestamp; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +/** + * 系统时钟
+ * 高并发场景下System.currentTimeMillis()的性能问题的优化 + * System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右) + * System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道 + * 后台定时更新时钟,JVM退出时,线程自动回收 + * + * see: http://git.oschina.net/yu120/sequence + * @author lry,looly + */ +public class SystemClock { + + /** 时钟更新间隔,单位毫秒 */ + private final long period; + /** 现在时刻的毫秒数 */ + private volatile long now; + + /** + * 构造 + * @param period + */ + private SystemClock(long period) { + this.period = period; + this.now = System.currentTimeMillis(); + scheduleClockUpdating(); + } + + /** + * 开启计时器线程 + */ + private void scheduleClockUpdating() { + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory(){ + @Override + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "System Clock"); + thread.setDaemon(true); + return thread; + } + }); + scheduler.scheduleAtFixedRate(new Runnable(){ + @Override + public void run() { + now = System.currentTimeMillis(); + } + }, period, period, TimeUnit.MILLISECONDS); + } + + /** + * @return 当前时间毫秒数 + */ + private long currentTimeMillis() { + return now; + } + + //------------------------------------------------------------------------ static + /** + * 单例 + * @author Looly + * + */ + private static class InstanceHolder { + public static final SystemClock INSTANCE = new SystemClock(1); + } + + /** + * 单例实例 + * @return 单例实例 + */ + private static SystemClock instance() { + return InstanceHolder.INSTANCE; + } + + /** + * @return 当前时间 + */ + public static long now() { + return instance().currentTimeMillis(); + } + + /** + * @return 当前时间字符串表现形式 + */ + public static String nowDate() { + return new Timestamp(instance().currentTimeMillis()).toString(); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/TimeInterval.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/TimeInterval.java new file mode 100644 index 0000000..0d6ec58 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/TimeInterval.java @@ -0,0 +1,109 @@ +package org.springblade.core.tool.date; + +/** + * 计时器
+ * 计算某个过程花费的时间,精确到毫秒 + * + * @author Looly + * + */ +public class TimeInterval { + private long time; + private boolean isNano; + + public TimeInterval() { + this(false); + } + + public TimeInterval(boolean isNano) { + this.isNano = isNano; + start(); + } + + /** + * @return 开始计时并返回当前时间 + */ + public long start() { + time = DateUtil.current(isNano); + return time; + } + + /** + * @return 重新计时并返回从开始到当前的持续时间 + */ + public long intervalRestart() { + long now = DateUtil.current(isNano); + long d = now - time; + time = now; + return d; + } + + /** + * 重新开始计算时间(重置开始时间) + * @return this + * @since 3.0.1 + */ + public TimeInterval restart(){ + time = DateUtil.current(isNano); + return this; + } + + //----------------------------------------------------------- Interval + /** + * 从开始到当前的间隔时间(毫秒数)
+ * 如果使用纳秒计时,返回纳秒差,否则返回毫秒差 + * @return 从开始到当前的间隔时间(毫秒数) + */ + public long interval() { + return DateUtil.current(isNano) - time; + } + + /** + * 从开始到当前的间隔时间(毫秒数) + * @return 从开始到当前的间隔时间(毫秒数) + */ + public long intervalMs() { + return isNano ? interval() / 1000000L : interval(); + } + + /** + * 从开始到当前的间隔秒数,取绝对值 + * @return 从开始到当前的间隔秒数,取绝对值 + */ + public long intervalSecond(){ + return intervalMs() / DateUnit.SECOND.getMillis(); + } + + /** + * 从开始到当前的间隔分钟数,取绝对值 + * @return 从开始到当前的间隔分钟数,取绝对值 + */ + public long intervalMinute(){ + return intervalMs() / DateUnit.MINUTE.getMillis(); + } + + /** + * 从开始到当前的间隔小时数,取绝对值 + * @return 从开始到当前的间隔小时数,取绝对值 + */ + public long intervalHour(){ + return intervalMs() / DateUnit.HOUR.getMillis(); + } + + /** + * 从开始到当前的间隔天数,取绝对值 + * @return 从开始到当前的间隔天数,取绝对值 + */ + public long intervalDay(){ + return intervalMs() / DateUnit.DAY.getMillis(); + } + + /** + * 从开始到当前的间隔周数,取绝对值 + * @return 从开始到当前的间隔周数,取绝对值 + */ + public long intervalWeek(){ + return intervalMs() / DateUnit.WEEK.getMillis(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/Week.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Week.java new file mode 100644 index 0000000..caaa504 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/Week.java @@ -0,0 +1,120 @@ +package org.springblade.core.tool.date; + +import java.util.Calendar; + +/** + * 星期枚举
+ * 与Calendar中的星期int值对应 + * + * @see #SUNDAY + * @see #MONDAY + * @see #TUESDAY + * @see #WEDNESDAY + * @see #THURSDAY + * @see #FRIDAY + * @see #SATURDAY + * + * @author Looly + * + */ +public enum Week { + + /** 周日 */ + SUNDAY(Calendar.SUNDAY), + /** 周一 */ + MONDAY(Calendar.MONDAY), + /** 周二 */ + TUESDAY(Calendar.TUESDAY), + /** 周三 */ + WEDNESDAY(Calendar.WEDNESDAY), + /** 周四 */ + THURSDAY(Calendar.THURSDAY), + /** 周五 */ + FRIDAY(Calendar.FRIDAY), + /** 周六 */ + SATURDAY(Calendar.SATURDAY); + + // --------------------------------------------------------------- + /** 星期对应{@link Calendar} 中的Week值 */ + private int value; + + /** + * 构造 + * + * @param value 星期对应{@link Calendar} 中的Week值 + */ + private Week(int value) { + this.value = value; + } + + /** + * 获得星期对应{@link Calendar} 中的Week值 + * + * @return 星期对应{@link Calendar} 中的Week值 + */ + public int getValue() { + return this.value; + } + + /** + * 转换为中文名 + * + * @return 星期的中文名 + * @since 3.3.0 + */ + public String toChinese() { + switch (this) { + case SUNDAY: + return "星期日"; + case MONDAY: + return "星期一"; + case TUESDAY: + return "星期二"; + case WEDNESDAY: + return "星期三"; + case THURSDAY: + return "星期四"; + case FRIDAY: + return "星期五"; + case SATURDAY: + return "星期六"; + default: + return null; + } + } + + /** + * 将 {@link Calendar}星期相关值转换为Week枚举对象
+ * + * @see #SUNDAY + * @see #MONDAY + * @see #TUESDAY + * @see #WEDNESDAY + * @see #THURSDAY + * @see #FRIDAY + * @see #SATURDAY + * + * @param calendarWeekIntValue Calendar中关于Week的int值 + * @return {@link Week} + */ + public static Week of(int calendarWeekIntValue) { + switch (calendarWeekIntValue) { + case Calendar.SUNDAY: + return SUNDAY; + case Calendar.MONDAY: + return MONDAY; + case Calendar.TUESDAY: + return TUESDAY; + case Calendar.WEDNESDAY: + return WEDNESDAY; + case Calendar.THURSDAY: + return THURSDAY; + case Calendar.FRIDAY: + return FRIDAY; + case Calendar.SATURDAY: + return SATURDAY; + default: + return null; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/AbstractDateBasic.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/AbstractDateBasic.java new file mode 100644 index 0000000..2c2d10e --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/AbstractDateBasic.java @@ -0,0 +1,64 @@ +package org.springblade.core.tool.date.format; + +import java.io.Serializable; +import java.util.Locale; +import java.util.TimeZone; + +public abstract class AbstractDateBasic implements DateBasic, Serializable { + private static final long serialVersionUID = 6333136319870641818L; + + /** The pattern */ + protected final String pattern; + /** The time zone. */ + protected final TimeZone timeZone; + /** The locale. */ + protected final Locale locale; + + /** + * 构造,内部使用 + * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 + * @param timeZone 非空时区{@link TimeZone} + * @param locale 非空{@link Locale} 日期地理位置 + */ + protected AbstractDateBasic(final String pattern, final TimeZone timeZone, final Locale locale) { + this.pattern = pattern; + this.timeZone = timeZone; + this.locale = locale; + } + + // ----------------------------------------------------------------------- Accessors + @Override + public String getPattern() { + return pattern; + } + + @Override + public TimeZone getTimeZone() { + return timeZone; + } + + @Override + public Locale getLocale() { + return locale; + } + + // ----------------------------------------------------------------------- Basics + @Override + public boolean equals(final Object obj) { + if (obj instanceof FastDatePrinter == false) { + return false; + } + final AbstractDateBasic other = (AbstractDateBasic) obj; + return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale); + } + + @Override + public int hashCode() { + return pattern.hashCode() + 13 * (timeZone.hashCode() + 13 * locale.hashCode()); + } + + @Override + public String toString() { + return "FastDatePrinter[" + pattern + "," + locale + "," + timeZone.getID() + "]"; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateBasic.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateBasic.java new file mode 100644 index 0000000..5dc9463 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateBasic.java @@ -0,0 +1,33 @@ +package org.springblade.core.tool.date.format; + +import java.util.Locale; +import java.util.TimeZone; + +/** + * 日期基本信息获取接口 + * + * @author Looly + * @since 2.16.2 + */ +public interface DateBasic { + /** + * 获得日期格式化或者转换的格式 + * + * @return {@link java.text.SimpleDateFormat}兼容的格式 + */ + String getPattern(); + + /** + * 获得时区 + * + * @return {@link TimeZone} + */ + TimeZone getTimeZone(); + + /** + * 获得 日期地理位置 + * + * @return {@link Locale} + */ + Locale getLocale(); +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateParser.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateParser.java new file mode 100644 index 0000000..edc05be --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DateParser.java @@ -0,0 +1,68 @@ +package org.springblade.core.tool.date.format; + +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Calendar; +import java.util.Date; + +/** + * 日期解析接口,用于解析日期字符串为 {@link Date} 对象
+ * Thanks to Apache Commons Lang 3.5 + * @since 2.16.2 + */ +public interface DateParser extends DateBasic { + + /** + * 将日期字符串解析并转换为 {@link Date} 对象
+ * 等价于 {@link java.text.DateFormat#parse(String)} + * + * @param source 日期字符串 + * @return {@link Date} + * @throws ParseException 转换异常,被转换的字符串格式错误。 + */ + Date parse(String source) throws ParseException; + + /** + * 将日期字符串解析并转换为 {@link Date} 对象
+ * 等价于 {@link java.text.DateFormat#parse(String, ParsePosition)} + * + * @param source 日期字符串 + * @param pos {@link ParsePosition} + * @return {@link Date} + */ + Date parse(String source, ParsePosition pos); + + /** + * 根据给定格式转换日期字符串 + * Updates the Calendar with parsed fields. Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed. + * Not all source text needs to be consumed. + * Upon parse failure, ParsePosition error index is updated to the offset of the source text which does not match the supplied format. + * + * @param source 被转换的日期字符串 + * @param pos 定义开始转换的位置,转换结束后更新转换到的位置 + * @param calendar The calendar into which to set parsed fields. + * @return true, if source has been parsed (pos parsePosition is updated); otherwise false (and pos errorIndex is updated) + * @throws IllegalArgumentException when Calendar has been set to be not lenient, and a parsed field is out of range. + */ + boolean parse(String source, ParsePosition pos, Calendar calendar); + + /** + * 将日期字符串解析并转换为 {@link Date} 对象
+ * + * @param source A String whose beginning should be parsed. + * @return a java.util.Date object + * @throws ParseException if the beginning of the specified string cannot be parsed. + * @see java.text.DateFormat#parseObject(String) + */ + Object parseObject(String source) throws ParseException; + + /** + * 根据 {@link ParsePosition} 给定将日期字符串解析并转换为 {@link Date} 对象
+ * + * @param source A String whose beginning should be parsed. + * @param pos the parse position + * @return a java.util.Date object + * @see java.text.DateFormat#parseObject(String, ParsePosition) + */ + Object parseObject(String source, ParsePosition pos); +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DatePrinter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DatePrinter.java new file mode 100644 index 0000000..decc2ef --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/DatePrinter.java @@ -0,0 +1,78 @@ +package org.springblade.core.tool.date.format; + +import java.util.Calendar; +import java.util.Date; + +/** + * 日期格式化输出接口
+ * Thanks to Apache Commons Lang 3.5 + * @author Looly + * @since 2.16.2 + */ +public interface DatePrinter extends DateBasic { + + /** + * 格式化日期表示的毫秒数 + * + * @param millis 日期毫秒数 + * @return the formatted string + * @since 2.1 + */ + String format(long millis); + + /** + * 使用 {@code GregorianCalendar} 格式化 {@code Date} + * + * @param date 日期 {@link Date} + * @return 格式化后的字符串 + */ + String format(Date date); + + /** + *

+ * Formats a {@code Calendar} object. + *

+ * 格式化 {@link Calendar} + * + * @param calendar {@link Calendar} + * @return 格式化后的字符串 + */ + String format(Calendar calendar); + + /** + *

+ * Formats a millisecond {@code long} value into the supplied {@code Appendable}. + *

+ * + * @param millis the millisecond value to format + * @param buf the buffer to format into + * @param the Appendable class type, usually StringBuilder or StringBuffer. + * @return the specified string buffer + */ + B format(long millis, B buf); + + /** + *

+ * Formats a {@code Date} object into the supplied {@code Appendable} using a {@code GregorianCalendar}. + *

+ * + * @param date the date to format + * @param buf the buffer to format into + * @param the Appendable class type, usually StringBuilder or StringBuffer. + * @return the specified string buffer + */ + B format(Date date, B buf); + + /** + *

+ * Formats a {@code Calendar} object into the supplied {@code Appendable}. + *

+ * The TimeZone set on the Calendar is only used to adjust the time offset. The TimeZone specified during the construction of the Parser will determine the TimeZone used in the formatted string. + * + * @param calendar the calendar to format + * @param buf the buffer to format into + * @param the Appendable class type, usually StringBuilder or StringBuffer. + * @return the specified string buffer + */ + B format(Calendar calendar, B buf); +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateFormat.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateFormat.java new file mode 100644 index 0000000..dfc685d --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateFormat.java @@ -0,0 +1,392 @@ +package org.springblade.core.tool.date.format; + +import java.text.*; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

+ * FastDateFormat 是一个线程安全的 {@link SimpleDateFormat} 实现。 + *

+ * + *

+ * 通过以下静态方法获得此对象:
+ * {@link #getInstance(String, TimeZone, Locale)}
+ * {@link #getDateInstance(int, TimeZone, Locale)}
+ * {@link #getTimeInstance(int, TimeZone, Locale)}
+ * {@link #getDateTimeInstance(int, int, TimeZone, Locale)} + *

+ * + * Thanks to Apache Commons Lang 3.5 + * @since 2.16.2 + */ +public class FastDateFormat extends Format implements DateParser, DatePrinter { + private static final long serialVersionUID = 8097890768636183236L; + + /** FULL locale dependent date or time style. */ + public static final int FULL = DateFormat.FULL; + /** LONG locale dependent date or time style. */ + public static final int LONG = DateFormat.LONG; + /** MEDIUM locale dependent date or time style. */ + public static final int MEDIUM = DateFormat.MEDIUM; + /** SHORT locale dependent date or time style. */ + public static final int SHORT = DateFormat.SHORT; + + private static final FormatCache cache = new FormatCache(){ + @Override + protected FastDateFormat createInstance(final String pattern, final TimeZone timeZone, final Locale locale) { + return new FastDateFormat(pattern, timeZone, locale); + } + }; + + private final FastDatePrinter printer; + private final FastDateParser parser; + + // ----------------------------------------------------------------------- + /** + * 获得 {@link FastDateFormat} 实例,使用默认格式和地区 + * + * @return {@link FastDateFormat} + */ + public static FastDateFormat getInstance() { + return cache.getInstance(); + } + + /** + * 获得 {@link FastDateFormat} 实例,使用默认地区
+ * 支持缓存 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @return {@link FastDateFormat} + * @throws IllegalArgumentException 日期格式问题 + */ + public static FastDateFormat getInstance(final String pattern) { + return cache.getInstance(pattern, null, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @param timeZone 时区{@link TimeZone} + * @return {@link FastDateFormat} + * @throws IllegalArgumentException 日期格式问题 + */ + public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone) { + return cache.getInstance(pattern, timeZone, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @param locale {@link Locale} 日期地理位置 + * @return {@link FastDateFormat} + * @throws IllegalArgumentException 日期格式问题 + */ + public static FastDateFormat getInstance(final String pattern, final Locale locale) { + return cache.getInstance(pattern, null, locale); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @param timeZone 时区{@link TimeZone} + * @param locale {@link Locale} 日期地理位置 + * @return {@link FastDateFormat} + * @throws IllegalArgumentException 日期格式问题 + */ + public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone, final Locale locale) { + return cache.getInstance(pattern, timeZone, locale); + } + + // ----------------------------------------------------------------------- + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateInstance(final int style) { + return cache.getDateInstance(style, null, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateInstance(final int style, final Locale locale) { + return cache.getDateInstance(style, null, locale); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone 时区{@link TimeZone} + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone) { + return cache.getDateInstance(style, timeZone, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone 时区{@link TimeZone} + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone, final Locale locale) { + return cache.getDateInstance(style, timeZone, locale); + } + + // ----------------------------------------------------------------------- + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getTimeInstance(final int style) { + return cache.getTimeInstance(style, null, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getTimeInstance(final int style, final Locale locale) { + return cache.getTimeInstance(style, null, locale); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted time + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone) { + return cache.getTimeInstance(style, timeZone, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted time + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone, final Locale locale) { + return cache.getTimeInstance(style, timeZone, locale); + } + + // ----------------------------------------------------------------------- + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle) { + return cache.getDateTimeInstance(dateStyle, timeStyle, null, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final Locale locale) { + return cache.getDateTimeInstance(dateStyle, timeStyle, null, locale); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone 时区{@link TimeZone} + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone) { + return getDateTimeInstance(dateStyle, timeStyle, timeZone, null); + } + + /** + * 获得 {@link FastDateFormat} 实例
+ * 支持缓存 + * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone 时区{@link TimeZone} + * @param locale {@link Locale} 日期地理位置 + * @return 本地化 {@link FastDateFormat} + */ + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone, final Locale locale) { + return cache.getDateTimeInstance(dateStyle, timeStyle, timeZone, locale); + } + + // ----------------------------------------------------------------------- Constructor start + /** + * 构造 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @param timeZone 非空时区 {@link TimeZone} + * @param locale {@link Locale} 日期地理位置 + * @throws NullPointerException if pattern, timeZone, or locale is null. + */ + protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale) { + this(pattern, timeZone, locale, null); + } + + /** + * 构造 + * + * @param pattern 使用{@link SimpleDateFormat} 相同的日期格式 + * @param timeZone 非空时区 {@link TimeZone} + * @param locale {@link Locale} 日期地理位置 + * @param centuryStart The start of the 100 year period to use as the "default century" for 2 digit year parsing. If centuryStart is null, defaults to now - 80 years + * @throws NullPointerException if pattern, timeZone, or locale is null. + */ + protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) { + printer = new FastDatePrinter(pattern, timeZone, locale); + parser = new FastDateParser(pattern, timeZone, locale, centuryStart); + } + // ----------------------------------------------------------------------- Constructor end + + // ----------------------------------------------------------------------- Format methods + @Override + public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) { + return toAppendTo.append(printer.format(obj)); + } + + @Override + public String format(final long millis) { + return printer.format(millis); + } + + @Override + public String format(final Date date) { + return printer.format(date); + } + + @Override + public String format(final Calendar calendar) { + return printer.format(calendar); + } + + @Override + public B format(final long millis, final B buf) { + return printer.format(millis, buf); + } + + @Override + public B format(final Date date, final B buf) { + return printer.format(date, buf); + } + + @Override + public B format(final Calendar calendar, final B buf) { + return printer.format(calendar, buf); + } + + // ----------------------------------------------------------------------- Parsing + @Override + public Date parse(final String source) throws ParseException { + return parser.parse(source); + } + + @Override + public Date parse(final String source, final ParsePosition pos) { + return parser.parse(source, pos); + } + + @Override + public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) { + return parser.parse(source, pos, calendar); + } + + @Override + public Object parseObject(final String source, final ParsePosition pos) { + return parser.parseObject(source, pos); + } + + // ----------------------------------------------------------------------- Accessors + @Override + public String getPattern() { + return printer.getPattern(); + } + + @Override + public TimeZone getTimeZone() { + return printer.getTimeZone(); + } + + @Override + public Locale getLocale() { + return printer.getLocale(); + } + + /** + *估算生成的日期字符串长度
+ * 实际生成的字符串长度小于或等于此值 + * + * @return 日期字符串长度 + */ + public int getMaxLengthEstimate() { + return printer.getMaxLengthEstimate(); + } + + // Basics + // ----------------------------------------------------------------------- + @Override + public boolean equals(final Object obj) { + if (obj instanceof FastDateFormat == false) { + return false; + } + final FastDateFormat other = (FastDateFormat) obj; + // no need to check parser, as it has same invariants as printer + return printer.equals(other.printer); + } + + @Override + public int hashCode() { + return printer.hashCode(); + } + + @Override + public String toString() { + return "FastDateFormat[" + printer.getPattern() + "," + printer.getLocale() + "," + printer.getTimeZone().getID() + "]"; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateParser.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateParser.java new file mode 100644 index 0000000..95a0717 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDateParser.java @@ -0,0 +1,822 @@ +package org.springblade.core.tool.date.format; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.text.DateFormatSymbols; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * {@link java.text.SimpleDateFormat} 的线程安全版本,用于解析日期字符串并转换为 {@link Date} 对象
+ * Thanks to Apache Commons Lang 3.5 + * + * @since 2.16.2 + * @see FastDatePrinter + */ +class FastDateParser extends AbstractDateBasic implements DateParser { + private static final long serialVersionUID = -3199383897950947498L; + + static final Locale JAPANESE_IMPERIAL = new Locale("ja", "JP", "JP"); + + /** 世纪:2000年前为19, 之后为20 */ + private final int century; + private final int startYear; + + // derived fields + private transient List patterns; + + // comparator used to sort regex alternatives + // alternatives should be ordered longer first, and shorter last. ('february' before 'feb') + // all entries must be lowercase by locale. + private static final Comparator LONGER_FIRST_LOWERCASE = new Comparator(){ + @Override + public int compare(final String left, final String right) { + return right.compareTo(left); + } + }; + + /** + *

+ * Constructs a new FastDateParser. + *

+ * + * Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the factory methods of {@link FastDateFormat} to get a cached FastDateParser instance. + * + * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone non-null time zone to use + * @param locale non-null locale + */ + protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale) { + this(pattern, timeZone, locale, null); + } + + /** + *

+ * Constructs a new FastDateParser. + *

+ * + * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone non-null time zone to use + * @param locale non-null locale + * @param centuryStart The start of the century for 2 digit year parsing + */ + protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) { + super(pattern, timeZone, locale); + final Calendar definingCalendar = Calendar.getInstance(timeZone, locale); + + int centuryStartYear; + if (centuryStart != null) { + definingCalendar.setTime(centuryStart); + centuryStartYear = definingCalendar.get(Calendar.YEAR); + } else if (locale.equals(JAPANESE_IMPERIAL)) { + centuryStartYear = 0; + } else { + // from 80 years ago to 20 years from now + definingCalendar.setTime(new Date()); + centuryStartYear = definingCalendar.get(Calendar.YEAR) - 80; + } + century = centuryStartYear / 100 * 100; + startYear = centuryStartYear - century; + + init(definingCalendar); + } + + /** + * Initialize derived fields from defining fields. This is called from constructor and from readObject (de-serialization) + * + * @param definingCalendar the {@link Calendar} instance used to initialize this FastDateParser + */ + private void init(final Calendar definingCalendar) { + patterns = new ArrayList<>(); + + final StrategyParser fm = new StrategyParser(definingCalendar); + for (;;) { + final StrategyAndWidth field = fm.getNextStrategy(); + if (field == null) { + break; + } + patterns.add(field); + } + } + + // helper classes to parse the format string + // ----------------------------------------------------------------------- + + /** + * Holds strategy and field width + */ + private static class StrategyAndWidth { + final Strategy strategy; + final int width; + + StrategyAndWidth(final Strategy strategy, final int width) { + this.strategy = strategy; + this.width = width; + } + + int getMaxWidth(final ListIterator lt) { + if (!strategy.isNumber() || !lt.hasNext()) { + return 0; + } + final Strategy nextStrategy = lt.next().strategy; + lt.previous(); + return nextStrategy.isNumber() ? width : 0; + } + } + + /** + * Parse format into Strategies + */ + private class StrategyParser { + final private Calendar definingCalendar; + private int currentIdx; + + StrategyParser(final Calendar definingCalendar) { + this.definingCalendar = definingCalendar; + } + + StrategyAndWidth getNextStrategy() { + if (currentIdx >= pattern.length()) { + return null; + } + + final char c = pattern.charAt(currentIdx); + if (isFormatLetter(c)) { + return letterPattern(c); + } + return literal(); + } + + private StrategyAndWidth letterPattern(final char c) { + final int begin = currentIdx; + while (++currentIdx < pattern.length()) { + if (pattern.charAt(currentIdx) != c) { + break; + } + } + + final int width = currentIdx - begin; + return new StrategyAndWidth(getStrategy(c, width, definingCalendar), width); + } + + private StrategyAndWidth literal() { + boolean activeQuote = false; + + final StringBuilder sb = new StringBuilder(); + while (currentIdx < pattern.length()) { + final char c = pattern.charAt(currentIdx); + if (!activeQuote && isFormatLetter(c)) { + break; + } else if (c == '\'' && (++currentIdx == pattern.length() || pattern.charAt(currentIdx) != '\'')) { + activeQuote = !activeQuote; + continue; + } + ++currentIdx; + sb.append(c); + } + + if (activeQuote) { + throw new IllegalArgumentException("Unterminated quote"); + } + + final String formatField = sb.toString(); + return new StrategyAndWidth(new CopyQuotedStrategy(formatField), formatField.length()); + } + } + + private static boolean isFormatLetter(final char c) { + return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'; + } + + // Serializing + // ----------------------------------------------------------------------- + /** + * Create the object after serialization. This implementation reinitializes the transient properties. + * + * @param in ObjectInputStream from which the object is being deserialized. + * @throws IOException if there is an IO issue. + * @throws ClassNotFoundException if a class cannot be found. + */ + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + final Calendar definingCalendar = Calendar.getInstance(timeZone, locale); + init(definingCalendar); + } + + @Override + public Object parseObject(final String source) throws ParseException { + return parse(source); + } + + @Override + public Date parse(final String source) throws ParseException { + final ParsePosition pp = new ParsePosition(0); + final Date date = parse(source, pp); + if (date == null) { + // Add a note re supported date range + if (locale.equals(JAPANESE_IMPERIAL)) { + throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" + "Unparseable date: \"" + source, pp.getErrorIndex()); + } + throw new ParseException("Unparseable date: " + source, pp.getErrorIndex()); + } + return date; + } + + @Override + public Object parseObject(final String source, final ParsePosition pos) { + return parse(source, pos); + } + + @Override + public Date parse(final String source, final ParsePosition pos) { + // timing tests indicate getting new instance is 19% faster than cloning + final Calendar cal = Calendar.getInstance(timeZone, locale); + cal.clear(); + + return parse(source, pos, cal) ? cal.getTime() : null; + } + + @Override + public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) { + final ListIterator lt = patterns.listIterator(); + while (lt.hasNext()) { + final StrategyAndWidth strategyAndWidth = lt.next(); + final int maxWidth = strategyAndWidth.getMaxWidth(lt); + if (!strategyAndWidth.strategy.parse(this, calendar, source, pos, maxWidth)) { + return false; + } + } + return true; + } + + // Support for strategies + // ----------------------------------------------------------------------- + + private static StringBuilder simpleQuote(final StringBuilder sb, final String value) { + for (int i = 0; i < value.length(); ++i) { + final char c = value.charAt(i); + switch (c) { + case '\\': + case '^': + case '$': + case '.': + case '|': + case '?': + case '*': + case '+': + case '(': + case ')': + case '[': + case '{': + sb.append('\\'); + default: + sb.append(c); + } + } + return sb; + } + + /** + * Get the short and long values displayed for a field + * + * @param cal The calendar to obtain the short and long values + * @param locale The locale of display names + * @param field The field of interest + * @param regex The regular expression to build + * @return The map of string display names to field values + */ + private static Map appendDisplayNames(final Calendar cal, final Locale locale, final int field, final StringBuilder regex) { + final Map values = new HashMap<>(); + + final Map displayNames = cal.getDisplayNames(field, Calendar.ALL_STYLES, locale); + final TreeSet sorted = new TreeSet<>(LONGER_FIRST_LOWERCASE); + for (final Map.Entry displayName : displayNames.entrySet()) { + final String key = displayName.getKey().toLowerCase(locale); + if (sorted.add(key)) { + values.put(key, displayName.getValue()); + } + } + for (final String symbol : sorted) { + simpleQuote(regex, symbol).append('|'); + } + return values; + } + + /** + * 使用当前的世纪调整两位数年份为四位数年份 + * + * @param twoDigitYear 两位数年份 + * @return A value between centuryStart(inclusive) to centuryStart+100(exclusive) + */ + private int adjustYear(final int twoDigitYear) { + final int trial = century + twoDigitYear; + return twoDigitYear >= startYear ? trial : trial + 100; + } + + /** + * 单个日期字段的分析策略 + */ + private static abstract class Strategy { + /** + * Is this field a number? The default implementation returns false. + * + * @return true, if field is a number + */ + boolean isNumber() { + return false; + } + + abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos, int maxWidth); + } + + /** + * A strategy to parse a single field from the parsing pattern + */ + private static abstract class PatternStrategy extends Strategy { + + private Pattern pattern; + + void createPattern(final StringBuilder regex) { + createPattern(regex.toString()); + } + + void createPattern(final String regex) { + this.pattern = Pattern.compile(regex); + } + + /** + * Is this field a number? The default implementation returns false. + * + * @return true, if field is a number + */ + @Override + boolean isNumber() { + return false; + } + + @Override + boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) { + final Matcher matcher = pattern.matcher(source.substring(pos.getIndex())); + if (!matcher.lookingAt()) { + pos.setErrorIndex(pos.getIndex()); + return false; + } + pos.setIndex(pos.getIndex() + matcher.end(1)); + setCalendar(parser, calendar, matcher.group(1)); + return true; + } + + abstract void setCalendar(FastDateParser parser, Calendar cal, String value); + } + + /** + * Obtain a Strategy given a field from a SimpleDateFormat pattern + * + * @param formatField A sub-sequence of the SimpleDateFormat pattern + * @param definingCalendar The calendar to obtain the short and long values + * @return The Strategy that will handle parsing for the field + */ + private Strategy getStrategy(final char f, final int width, final Calendar definingCalendar) { + switch (f) { + default: + throw new IllegalArgumentException("Format '" + f + "' not supported"); + case 'D': + return DAY_OF_YEAR_STRATEGY; + case 'E': + return getLocaleSpecificStrategy(Calendar.DAY_OF_WEEK, definingCalendar); + case 'F': + return DAY_OF_WEEK_IN_MONTH_STRATEGY; + case 'G': + return getLocaleSpecificStrategy(Calendar.ERA, definingCalendar); + case 'H': // Hour in day (0-23) + return HOUR_OF_DAY_STRATEGY; + case 'K': // Hour in am/pm (0-11) + return HOUR_STRATEGY; + case 'M': + return width >= 3 ? getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) : NUMBER_MONTH_STRATEGY; + case 'S': + return MILLISECOND_STRATEGY; + case 'W': + return WEEK_OF_MONTH_STRATEGY; + case 'a': + return getLocaleSpecificStrategy(Calendar.AM_PM, definingCalendar); + case 'd': + return DAY_OF_MONTH_STRATEGY; + case 'h': // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0 + return HOUR12_STRATEGY; + case 'k': // Hour in day (1-24), i.e. midnight is 24, not 0 + return HOUR24_OF_DAY_STRATEGY; + case 'm': + return MINUTE_STRATEGY; + case 's': + return SECOND_STRATEGY; + case 'u': + return DAY_OF_WEEK_STRATEGY; + case 'w': + return WEEK_OF_YEAR_STRATEGY; + case 'y': + case 'Y': + return width > 2 ? LITERAL_YEAR_STRATEGY : ABBREVIATED_YEAR_STRATEGY; + case 'X': + return ISO8601TimeZoneStrategy.getStrategy(width); + case 'Z': + if (width == 2) { + return ISO8601TimeZoneStrategy.ISO_8601_3_STRATEGY; + } + //$FALL-THROUGH$ + case 'z': + return getLocaleSpecificStrategy(Calendar.ZONE_OFFSET, definingCalendar); + } + } + + @SuppressWarnings("unchecked") // OK because we are creating an array with no entries + private static final ConcurrentMap[] caches = new ConcurrentMap[Calendar.FIELD_COUNT]; + + /** + * Get a cache of Strategies for a particular field + * + * @param field The Calendar field + * @return a cache of Locale to Strategy + */ + private static ConcurrentMap getCache(final int field) { + synchronized (caches) { + if (caches[field] == null) { + caches[field] = new ConcurrentHashMap<>(3); + } + return caches[field]; + } + } + + /** + * Construct a Strategy that parses a Text field + * + * @param field The Calendar field + * @param definingCalendar The calendar to obtain the short and long values + * @return a TextStrategy for the field and Locale + */ + private Strategy getLocaleSpecificStrategy(final int field, final Calendar definingCalendar) { + final ConcurrentMap cache = getCache(field); + Strategy strategy = cache.get(locale); + if (strategy == null) { + strategy = field == Calendar.ZONE_OFFSET ? new TimeZoneStrategy(locale) : new CaseInsensitiveTextStrategy(field, definingCalendar, locale); + final Strategy inCache = cache.putIfAbsent(locale, strategy); + if (inCache != null) { + return inCache; + } + } + return strategy; + } + + /** + * A strategy that copies the static or quoted field in the parsing pattern + */ + private static class CopyQuotedStrategy extends Strategy { + + final private String formatField; + + /** + * Construct a Strategy that ensures the formatField has literal text + * + * @param formatField The literal text to match + */ + CopyQuotedStrategy(final String formatField) { + this.formatField = formatField; + } + + /** + * {@inheritDoc} + */ + @Override + boolean isNumber() { + return false; + } + + @Override + boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) { + for (int idx = 0; idx < formatField.length(); ++idx) { + final int sIdx = idx + pos.getIndex(); + if (sIdx == source.length()) { + pos.setErrorIndex(sIdx); + return false; + } + if (formatField.charAt(idx) != source.charAt(sIdx)) { + pos.setErrorIndex(sIdx); + return false; + } + } + pos.setIndex(formatField.length() + pos.getIndex()); + return true; + } + } + + /** + * A strategy that handles a text field in the parsing pattern + */ + private static class CaseInsensitiveTextStrategy extends PatternStrategy { + private final int field; + final Locale locale; + private final Map lKeyValues; + + /** + * Construct a Strategy that parses a Text field + * + * @param field The Calendar field + * @param definingCalendar The Calendar to use + * @param locale The Locale to use + */ + CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) { + this.field = field; + this.locale = locale; + + final StringBuilder regex = new StringBuilder(); + regex.append("((?iu)"); + lKeyValues = appendDisplayNames(definingCalendar, locale, field, regex); + regex.setLength(regex.length() - 1); + regex.append(")"); + createPattern(regex); + } + + /** + * {@inheritDoc} + */ + @Override + void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { + final Integer iVal = lKeyValues.get(value.toLowerCase(locale)); + cal.set(field, iVal.intValue()); + } + } + + /** + * A strategy that handles a number field in the parsing pattern + */ + private static class NumberStrategy extends Strategy { + private final int field; + + /** + * Construct a Strategy that parses a Number field + * + * @param field The Calendar field + */ + NumberStrategy(final int field) { + this.field = field; + } + + /** + * {@inheritDoc} + */ + @Override + boolean isNumber() { + return true; + } + + @Override + boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) { + int idx = pos.getIndex(); + int last = source.length(); + + if (maxWidth == 0) { + // if no maxWidth, strip leading white space + for (; idx < last; ++idx) { + final char c = source.charAt(idx); + if (!Character.isWhitespace(c)) { + break; + } + } + pos.setIndex(idx); + } else { + final int end = idx + maxWidth; + if (last > end) { + last = end; + } + } + + for (; idx < last; ++idx) { + final char c = source.charAt(idx); + if (!Character.isDigit(c)) { + break; + } + } + + if (pos.getIndex() == idx) { + pos.setErrorIndex(idx); + return false; + } + + final int value = Integer.parseInt(source.substring(pos.getIndex(), idx)); + pos.setIndex(idx); + + calendar.set(field, modify(parser, value)); + return true; + } + + /** + * Make any modifications to parsed integer + * + * @param parser The parser + * @param iValue The parsed integer + * @return The modified value + */ + int modify(final FastDateParser parser, final int iValue) { + return iValue; + } + + } + + private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR){ + /** + * {@inheritDoc} + */ + @Override + int modify(final FastDateParser parser, final int iValue) { + return iValue < 100 ? parser.adjustYear(iValue) : iValue; + } + }; + + /** + * A strategy that handles a timezone field in the parsing pattern + */ + static class TimeZoneStrategy extends PatternStrategy { + private static final String RFC_822_TIME_ZONE = "[+-]\\d{4}"; + private static final String GMT_OPTION = "GMT[+-]\\d{1,2}:\\d{2}"; + + private final Locale locale; + private final Map tzNames = new HashMap<>(); + + private static class TzInfo { + TimeZone zone; + int dstOffset; + + TzInfo(final TimeZone tz, final boolean useDst) { + zone = tz; + dstOffset = useDst ? tz.getDSTSavings() : 0; + } + } + + /** + * Index of zone id + */ + private static final int ID = 0; + + /** + * Construct a Strategy that parses a TimeZone + * + * @param locale The Locale + */ + TimeZoneStrategy(final Locale locale) { + this.locale = locale; + + final StringBuilder sb = new StringBuilder(); + sb.append("((?iu)" + RFC_822_TIME_ZONE + "|" + GMT_OPTION); + + final Set sorted = new TreeSet<>(LONGER_FIRST_LOWERCASE); + + final String[][] zones = DateFormatSymbols.getInstance(locale).getZoneStrings(); + for (final String[] zoneNames : zones) { + // offset 0 is the time zone ID and is not localized + final String tzId = zoneNames[ID]; + if (tzId.equalsIgnoreCase("GMT")) { + continue; + } + final TimeZone tz = TimeZone.getTimeZone(tzId); + // offset 1 is long standard name + // offset 2 is short standard name + final TzInfo standard = new TzInfo(tz, false); + TzInfo tzInfo = standard; + for (int i = 1; i < zoneNames.length; ++i) { + switch (i) { + case 3: // offset 3 is long daylight savings (or summertime) name + // offset 4 is the short summertime name + tzInfo = new TzInfo(tz, true); + break; + case 5: // offset 5 starts additional names, probably standard time + tzInfo = standard; + break; + } + if (zoneNames[i] != null) { + final String key = zoneNames[i].toLowerCase(locale); + // ignore the data associated with duplicates supplied in + // the additional names + if (sorted.add(key)) { + tzNames.put(key, tzInfo); + } + } + } + } + // order the regex alternatives with longer strings first, greedy + // match will ensure longest string will be consumed + for (final String zoneName : sorted) { + simpleQuote(sb.append('|'), zoneName); + } + sb.append(")"); + createPattern(sb); + } + + /** + * {@inheritDoc} + */ + @Override + void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { + if (value.charAt(0) == '+' || value.charAt(0) == '-') { + final TimeZone tz = TimeZone.getTimeZone("GMT" + value); + cal.setTimeZone(tz); + } else if (value.regionMatches(true, 0, "GMT", 0, 3)) { + final TimeZone tz = TimeZone.getTimeZone(value.toUpperCase()); + cal.setTimeZone(tz); + } else { + final TzInfo tzInfo = tzNames.get(value.toLowerCase(locale)); + cal.set(Calendar.DST_OFFSET, tzInfo.dstOffset); + cal.set(Calendar.ZONE_OFFSET, tzInfo.zone.getRawOffset()); + } + } + } + + private static class ISO8601TimeZoneStrategy extends PatternStrategy { + // Z, +hh, -hh, +hhmm, -hhmm, +hh:mm or -hh:mm + + /** + * Construct a Strategy that parses a TimeZone + * + * @param pattern The Pattern + */ + ISO8601TimeZoneStrategy(final String pattern) { + createPattern(pattern); + } + + /** + * {@inheritDoc} + */ + @Override + void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { + if (value.equals("Z")) { + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + } else { + cal.setTimeZone(TimeZone.getTimeZone("GMT" + value)); + } + } + + private static final Strategy ISO_8601_1_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}))"); + private static final Strategy ISO_8601_2_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}\\d{2}))"); + private static final Strategy ISO_8601_3_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}(?::)\\d{2}))"); + + /** + * Factory method for ISO8601TimeZoneStrategies. + * + * @param tokenLen a token indicating the length of the TimeZone String to be formatted. + * @return a ISO8601TimeZoneStrategy that can format TimeZone String of length {@code tokenLen}. If no such strategy exists, an IllegalArgumentException will be thrown. + */ + static Strategy getStrategy(final int tokenLen) { + switch (tokenLen) { + case 1: + return ISO_8601_1_STRATEGY; + case 2: + return ISO_8601_2_STRATEGY; + case 3: + return ISO_8601_3_STRATEGY; + default: + throw new IllegalArgumentException("invalid number of X"); + } + } + } + + private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH){ + @Override + int modify(final FastDateParser parser, final int iValue) { + return iValue - 1; + } + }; + private static final Strategy LITERAL_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR); + private static final Strategy WEEK_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_YEAR); + private static final Strategy WEEK_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_MONTH); + private static final Strategy DAY_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.DAY_OF_YEAR); + private static final Strategy DAY_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_MONTH); + private static final Strategy DAY_OF_WEEK_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK){ + @Override + int modify(final FastDateParser parser, final int iValue) { + return iValue != 7 ? iValue + 1 : Calendar.SUNDAY; + } + }; + private static final Strategy DAY_OF_WEEK_IN_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK_IN_MONTH); + private static final Strategy HOUR_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY); + private static final Strategy HOUR24_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY){ + @Override + int modify(final FastDateParser parser, final int iValue) { + return iValue == 24 ? 0 : iValue; + } + }; + private static final Strategy HOUR12_STRATEGY = new NumberStrategy(Calendar.HOUR){ + @Override + int modify(final FastDateParser parser, final int iValue) { + return iValue == 12 ? 0 : iValue; + } + }; + private static final Strategy HOUR_STRATEGY = new NumberStrategy(Calendar.HOUR); + private static final Strategy MINUTE_STRATEGY = new NumberStrategy(Calendar.MINUTE); + private static final Strategy SECOND_STRATEGY = new NumberStrategy(Calendar.SECOND); + private static final Strategy MILLISECOND_STRATEGY = new NumberStrategy(Calendar.MILLISECOND); +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDatePrinter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDatePrinter.java new file mode 100644 index 0000000..82f5298 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FastDatePrinter.java @@ -0,0 +1,1320 @@ +package org.springblade.core.tool.date.format; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.text.DateFormatSymbols; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * {@link java.text.SimpleDateFormat} 的线程安全版本,用于将 {@link Date} 格式化输出
+ * Thanks to Apache Commons Lang 3.5 + * + * @since 2.16.2 + * @see FastDateParser + */ +class FastDatePrinter extends AbstractDateBasic implements DatePrinter { + private static final long serialVersionUID = -6305750172255764887L; + + /** 规则列表. */ + private transient Rule[] rules; + /** 估算最大长度. */ + private transient int mMaxLengthEstimate; + + // Constructor + // ----------------------------------------------------------------------- + /** + * 构造,内部使用
+ * + * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 + * @param timeZone 非空时区{@link TimeZone} + * @param locale 非空{@link Locale} 日期地理位置 + */ + protected FastDatePrinter(final String pattern, final TimeZone timeZone, final Locale locale) { + super(pattern, timeZone, locale); + init(); + } + + /** + * 初始化 + */ + private void init() { + final List rulesList = parsePattern(); + rules = rulesList.toArray(new Rule[rulesList.size()]); + + int len = 0; + for (int i = rules.length; --i >= 0;) { + len += rules[i].estimateLength(); + } + + mMaxLengthEstimate = len; + } + + // Parse the pattern + // ----------------------------------------------------------------------- + /** + *

+ * Returns a list of Rules given a pattern. + *

+ * + * @return a {@code List} of Rule objects + * @throws IllegalArgumentException if pattern is invalid + */ + protected List parsePattern() { + final DateFormatSymbols symbols = new DateFormatSymbols(locale); + final List rules = new ArrayList<>(); + + final String[] ERAs = symbols.getEras(); + final String[] months = symbols.getMonths(); + final String[] shortMonths = symbols.getShortMonths(); + final String[] weekdays = symbols.getWeekdays(); + final String[] shortWeekdays = symbols.getShortWeekdays(); + final String[] AmPmStrings = symbols.getAmPmStrings(); + + final int length = pattern.length(); + final int[] indexRef = new int[1]; + + for (int i = 0; i < length; i++) { + indexRef[0] = i; + final String token = parseToken(pattern, indexRef); + i = indexRef[0]; + + final int tokenLen = token.length(); + if (tokenLen == 0) { + break; + } + + Rule rule; + final char c = token.charAt(0); + + switch (c) { + case 'G': // era designator (text) + rule = new TextField(Calendar.ERA, ERAs); + break; + case 'y': // year (number) + case 'Y': // week year + if (tokenLen == 2) { + rule = TwoDigitYearField.INSTANCE; + } else { + rule = selectNumberRule(Calendar.YEAR, tokenLen < 4 ? 4 : tokenLen); + } + if (c == 'Y') { + rule = new WeekYear((NumberRule) rule); + } + break; + case 'M': // month in year (text and number) + if (tokenLen >= 4) { + rule = new TextField(Calendar.MONTH, months); + } else if (tokenLen == 3) { + rule = new TextField(Calendar.MONTH, shortMonths); + } else if (tokenLen == 2) { + rule = TwoDigitMonthField.INSTANCE; + } else { + rule = UnpaddedMonthField.INSTANCE; + } + break; + case 'd': // day in month (number) + rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen); + break; + case 'h': // hour in am/pm (number, 1..12) + rule = new TwelveHourField(selectNumberRule(Calendar.HOUR, tokenLen)); + break; + case 'H': // hour in day (number, 0..23) + rule = selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen); + break; + case 'm': // minute in hour (number) + rule = selectNumberRule(Calendar.MINUTE, tokenLen); + break; + case 's': // second in minute (number) + rule = selectNumberRule(Calendar.SECOND, tokenLen); + break; + case 'S': // millisecond (number) + rule = selectNumberRule(Calendar.MILLISECOND, tokenLen); + break; + case 'E': // day in week (text) + rule = new TextField(Calendar.DAY_OF_WEEK, tokenLen < 4 ? shortWeekdays : weekdays); + break; + case 'u': // day in week (number) + rule = new DayInWeekField(selectNumberRule(Calendar.DAY_OF_WEEK, tokenLen)); + break; + case 'D': // day in year (number) + rule = selectNumberRule(Calendar.DAY_OF_YEAR, tokenLen); + break; + case 'F': // day of week in month (number) + rule = selectNumberRule(Calendar.DAY_OF_WEEK_IN_MONTH, tokenLen); + break; + case 'w': // week in year (number) + rule = selectNumberRule(Calendar.WEEK_OF_YEAR, tokenLen); + break; + case 'W': // week in month (number) + rule = selectNumberRule(Calendar.WEEK_OF_MONTH, tokenLen); + break; + case 'a': // am/pm marker (text) + rule = new TextField(Calendar.AM_PM, AmPmStrings); + break; + case 'k': // hour in day (1..24) + rule = new TwentyFourHourField(selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen)); + break; + case 'K': // hour in am/pm (0..11) + rule = selectNumberRule(Calendar.HOUR, tokenLen); + break; + case 'X': // ISO 8601 + rule = Iso8601_Rule.getRule(tokenLen); + break; + case 'z': // time zone (text) + if (tokenLen >= 4) { + rule = new TimeZoneNameRule(timeZone, locale, TimeZone.LONG); + } else { + rule = new TimeZoneNameRule(timeZone, locale, TimeZone.SHORT); + } + break; + case 'Z': // time zone (value) + if (tokenLen == 1) { + rule = TimeZoneNumberRule.INSTANCE_NO_COLON; + } else if (tokenLen == 2) { + rule = Iso8601_Rule.ISO8601_HOURS_COLON_MINUTES; + } else { + rule = TimeZoneNumberRule.INSTANCE_COLON; + } + break; + case '\'': // literal text + final String sub = token.substring(1); + if (sub.length() == 1) { + rule = new CharacterLiteral(sub.charAt(0)); + } else { + rule = new StringLiteral(sub); + } + break; + default: + throw new IllegalArgumentException("Illegal pattern component: " + token); + } + + rules.add(rule); + } + + return rules; + } + + /** + *

+ * Performs the parsing of tokens. + *

+ * + * @param pattern the pattern + * @param indexRef index references + * @return parsed token + */ + protected String parseToken(final String pattern, final int[] indexRef) { + final StringBuilder buf = new StringBuilder(); + + int i = indexRef[0]; + final int length = pattern.length(); + + char c = pattern.charAt(i); + if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') { + // Scan a run of the same character, which indicates a time + // pattern. + buf.append(c); + + while (i + 1 < length) { + final char peek = pattern.charAt(i + 1); + if (peek == c) { + buf.append(c); + i++; + } else { + break; + } + } + } else { + // This will identify token as text. + buf.append('\''); + + boolean inLiteral = false; + + for (; i < length; i++) { + c = pattern.charAt(i); + + if (c == '\'') { + if (i + 1 < length && pattern.charAt(i + 1) == '\'') { + // '' is treated as escaped ' + i++; + buf.append(c); + } else { + inLiteral = !inLiteral; + } + } else if (!inLiteral && (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) { + i--; + break; + } else { + buf.append(c); + } + } + } + + indexRef[0] = i; + return buf.toString(); + } + + /** + *

+ * Gets an appropriate rule for the padding required. + *

+ * + * @param field the field to get a rule for + * @param padding the padding required + * @return a new rule with the correct padding + */ + protected NumberRule selectNumberRule(final int field, final int padding) { + switch (padding) { + case 1: + return new UnpaddedNumberField(field); + case 2: + return new TwoDigitNumberField(field); + default: + return new PaddedNumberField(field, padding); + } + } + + // Format methods + // ----------------------------------------------------------------------- + + /** + *

+ * Formats a {@code Date}, {@code Calendar} or {@code Long} (milliseconds) object. + *

+ * + * @param obj the object to format + * @return The formatted value. + */ + String format(final Object obj) { + if (obj instanceof Date) { + return format((Date) obj); + } else if (obj instanceof Calendar) { + return format((Calendar) obj); + } else if (obj instanceof Long) { + return format(((Long) obj).longValue()); + } else { + throw new IllegalArgumentException("Unknown class: " + (obj == null ? "" : obj.getClass().getName())); + } + } + + @Override + public String format(final long millis) { + final Calendar c = Calendar.getInstance(timeZone, locale); + c.setTimeInMillis(millis); + return applyRulesToString(c); + } + + @Override + public String format(final Date date) { + final Calendar c = Calendar.getInstance(timeZone, locale); + c.setTime(date); + return applyRulesToString(c); + } + + @Override + public String format(final Calendar calendar) { + return format(calendar, new StringBuilder(mMaxLengthEstimate)).toString(); + } + + @Override + public B format(final long millis, final B buf) { + final Calendar c = Calendar.getInstance(timeZone, locale); + c.setTimeInMillis(millis); + return applyRules(c, buf); + } + + @Override + public B format(final Date date, final B buf) { + final Calendar c = Calendar.getInstance(timeZone, locale); + c.setTime(date); + return applyRules(c, buf); + } + + @Override + public B format(Calendar calendar, final B buf) { + // do not pass in calendar directly, this will cause TimeZone of FastDatePrinter to be ignored + if (!calendar.getTimeZone().equals(timeZone)) { + calendar = (Calendar) calendar.clone(); + calendar.setTimeZone(timeZone); + } + return applyRules(calendar, buf); + } + + /** + * Creates a String representation of the given Calendar by applying the rules of this printer to it. + * + * @param c the Calender to apply the rules to. + * @return a String representation of the given Calendar. + */ + private String applyRulesToString(final Calendar c) { + return applyRules(c, new StringBuilder(mMaxLengthEstimate)).toString(); + } + + /** + *

+ * Performs the formatting by applying the rules to the specified calendar. + *

+ * + * @param calendar the calendar to format + * @param buf the buffer to format into + * @param the Appendable class type, usually StringBuilder or StringBuffer. + * @return the specified string buffer + */ + private B applyRules(final Calendar calendar, final B buf) { + try { + for (final Rule rule : this.rules) { + rule.appendTo(buf, calendar); + } + } catch (final IOException e) { + throw new RuntimeException(e); + } + return buf; + } + + /** + *估算生成的日期字符串长度
+ * 实际生成的字符串长度小于或等于此值 + * + * @return 日期字符串长度 + */ + public int getMaxLengthEstimate() { + return mMaxLengthEstimate; + } + + // Serializing + // ----------------------------------------------------------------------- + /** + * Create the object after serialization. This implementation reinitializes the transient properties. + * + * @param in ObjectInputStream from which the object is being deserialized. + * @throws IOException if there is an IO issue. + * @throws ClassNotFoundException if a class cannot be found. + */ + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + init(); + } + + /** + * Appends two digits to the given buffer. + * + * @param buffer the buffer to append to. + * @param value the value to append digits from. + */ + private static void appendDigits(final Appendable buffer, final int value) throws IOException { + buffer.append((char) (value / 10 + '0')); + buffer.append((char) (value % 10 + '0')); + } + + private static final int MAX_DIGITS = 10; // log10(Integer.MAX_VALUE) ~= 9.3 + + /** + * Appends all digits to the given buffer. + * + * @param buffer the buffer to append to. + * @param value the value to append digits from. + */ + private static void appendFullDigits(final Appendable buffer, int value, int minFieldWidth) throws IOException { + // specialized paths for 1 to 4 digits -> avoid the memory allocation from the temporary work array + // see LANG-1248 + if (value < 10000) { + // less memory allocation path works for four digits or less + + int nDigits = 4; + if (value < 1000) { + --nDigits; + if (value < 100) { + --nDigits; + if (value < 10) { + --nDigits; + } + } + } + // left zero pad + for (int i = minFieldWidth - nDigits; i > 0; --i) { + buffer.append('0'); + } + + switch (nDigits) { + case 4: + buffer.append((char) (value / 1000 + '0')); + value %= 1000; + case 3: + if (value >= 100) { + buffer.append((char) (value / 100 + '0')); + value %= 100; + } else { + buffer.append('0'); + } + case 2: + if (value >= 10) { + buffer.append((char) (value / 10 + '0')); + value %= 10; + } else { + buffer.append('0'); + } + case 1: + buffer.append((char) (value + '0')); + } + } else { + // more memory allocation path works for any digits + + // build up decimal representation in reverse + final char[] work = new char[MAX_DIGITS]; + int digit = 0; + while (value != 0) { + work[digit++] = (char) (value % 10 + '0'); + value = value / 10; + } + + // pad with zeros + while (digit < minFieldWidth) { + buffer.append('0'); + --minFieldWidth; + } + + // reverse + while (--digit >= 0) { + buffer.append(work[digit]); + } + } + } + + // Rules + // ----------------------------------------------------------------------- + /** + * 规则 + */ + private interface Rule { + /** + * Returns the estimated length of the result. + * + * @return the estimated length + */ + int estimateLength(); + + /** + * Appends the value of the specified calendar to the output buffer based on the rule implementation. + * + * @param buf the output buffer + * @param calendar calendar to be appended + * @throws IOException if an I/O error occurs + */ + void appendTo(Appendable buf, Calendar calendar) throws IOException; + } + + /** + *

+ * Inner class defining a numeric rule. + *

+ */ + private interface NumberRule extends Rule { + /** + * Appends the specified value to the output buffer based on the rule implementation. + * + * @param buffer the output buffer + * @param value the value to be appended + * @throws IOException if an I/O error occurs + */ + void appendTo(Appendable buffer, int value) throws IOException; + } + + /** + *

+ * Inner class to output a constant single character. + *

+ */ + private static class CharacterLiteral implements Rule { + private final char mValue; + + /** + * Constructs a new instance of {@code CharacterLiteral} to hold the specified value. + * + * @param value the character literal + */ + CharacterLiteral(final char value) { + mValue = value; + } + + @Override + public int estimateLength() { + return 1; + } + + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + buffer.append(mValue); + } + } + + /** + *

+ * Inner class to output a constant string. + *

+ */ + private static class StringLiteral implements Rule { + private final String mValue; + + /** + * Constructs a new instance of {@code StringLiteral} to hold the specified value. + * + * @param value the string literal + */ + StringLiteral(final String value) { + mValue = value; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return mValue.length(); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + buffer.append(mValue); + } + } + + /** + *

+ * Inner class to output one of a set of values. + *

+ */ + private static class TextField implements Rule { + private final int mField; + private final String[] mValues; + + /** + * Constructs an instance of {@code TextField} with the specified field and values. + * + * @param field the field + * @param values the field values + */ + TextField(final int field, final String[] values) { + mField = field; + mValues = values; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + int max = 0; + for (int i = mValues.length; --i >= 0;) { + final int len = mValues[i].length(); + if (len > max) { + max = len; + } + } + return max; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + buffer.append(mValues[calendar.get(mField)]); + } + } + + /** + *

+ * Inner class to output an unpadded number. + *

+ */ + private static class UnpaddedNumberField implements NumberRule { + private final int mField; + + /** + * Constructs an instance of {@code UnpadedNumberField} with the specified field. + * + * @param field the field + */ + UnpaddedNumberField(final int field) { + mField = field; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 4; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(mField)); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + if (value < 10) { + buffer.append((char) (value + '0')); + } else if (value < 100) { + appendDigits(buffer, value); + } else { + appendFullDigits(buffer, value, 1); + } + } + } + + /** + *

+ * Inner class to output an unpadded month. + *

+ */ + private static class UnpaddedMonthField implements NumberRule { + static final UnpaddedMonthField INSTANCE = new UnpaddedMonthField(); + + /** + * Constructs an instance of {@code UnpaddedMonthField}. + * + */ + UnpaddedMonthField() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 2; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(Calendar.MONTH) + 1); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + if (value < 10) { + buffer.append((char) (value + '0')); + } else { + appendDigits(buffer, value); + } + } + } + + /** + *

+ * Inner class to output a padded number. + *

+ */ + private static class PaddedNumberField implements NumberRule { + private final int mField; + private final int mSize; + + /** + * Constructs an instance of {@code PaddedNumberField}. + * + * @param field the field + * @param size size of the output field + */ + PaddedNumberField(final int field, final int size) { + if (size < 3) { + // Should use UnpaddedNumberField or TwoDigitNumberField. + throw new IllegalArgumentException(); + } + mField = field; + mSize = size; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return mSize; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(mField)); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + appendFullDigits(buffer, value, mSize); + } + } + + /** + *

+ * Inner class to output a two digit number. + *

+ */ + private static class TwoDigitNumberField implements NumberRule { + private final int mField; + + /** + * Constructs an instance of {@code TwoDigitNumberField} with the specified field. + * + * @param field the field + */ + TwoDigitNumberField(final int field) { + mField = field; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 2; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(mField)); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + if (value < 100) { + appendDigits(buffer, value); + } else { + appendFullDigits(buffer, value, 2); + } + } + } + + /** + *

+ * Inner class to output a two digit year. + *

+ */ + private static class TwoDigitYearField implements NumberRule { + static final TwoDigitYearField INSTANCE = new TwoDigitYearField(); + + /** + * Constructs an instance of {@code TwoDigitYearField}. + */ + TwoDigitYearField() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 2; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(Calendar.YEAR) % 100); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + appendDigits(buffer, value); + } + } + + /** + *

+ * Inner class to output a two digit month. + *

+ */ + private static class TwoDigitMonthField implements NumberRule { + static final TwoDigitMonthField INSTANCE = new TwoDigitMonthField(); + + /** + * Constructs an instance of {@code TwoDigitMonthField}. + */ + TwoDigitMonthField() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 2; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + appendTo(buffer, calendar.get(Calendar.MONTH) + 1); + } + + /** + * {@inheritDoc} + */ + @Override + public final void appendTo(final Appendable buffer, final int value) throws IOException { + appendDigits(buffer, value); + } + } + + /** + *

+ * Inner class to output the twelve hour field. + *

+ */ + private static class TwelveHourField implements NumberRule { + private final NumberRule mRule; + + /** + * Constructs an instance of {@code TwelveHourField} with the specified {@code NumberRule}. + * + * @param rule the rule + */ + TwelveHourField(final NumberRule rule) { + mRule = rule; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return mRule.estimateLength(); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + int value = calendar.get(Calendar.HOUR); + if (value == 0) { + value = calendar.getLeastMaximum(Calendar.HOUR) + 1; + } + mRule.appendTo(buffer, value); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final int value) throws IOException { + mRule.appendTo(buffer, value); + } + } + + /** + *

+ * Inner class to output the twenty four hour field. + *

+ */ + private static class TwentyFourHourField implements NumberRule { + private final NumberRule mRule; + + /** + * Constructs an instance of {@code TwentyFourHourField} with the specified {@code NumberRule}. + * + * @param rule the rule + */ + TwentyFourHourField(final NumberRule rule) { + mRule = rule; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return mRule.estimateLength(); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + int value = calendar.get(Calendar.HOUR_OF_DAY); + if (value == 0) { + value = calendar.getMaximum(Calendar.HOUR_OF_DAY) + 1; + } + mRule.appendTo(buffer, value); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final int value) throws IOException { + mRule.appendTo(buffer, value); + } + } + + /** + *

+ * Inner class to output the numeric day in week. + *

+ */ + private static class DayInWeekField implements NumberRule { + private final NumberRule mRule; + + DayInWeekField(final NumberRule rule) { + mRule = rule; + } + + @Override + public int estimateLength() { + return mRule.estimateLength(); + } + + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + final int value = calendar.get(Calendar.DAY_OF_WEEK); + mRule.appendTo(buffer, value != Calendar.SUNDAY ? value - 1 : 7); + } + + @Override + public void appendTo(final Appendable buffer, final int value) throws IOException { + mRule.appendTo(buffer, value); + } + } + + /** + *

+ * Inner class to output the numeric day in week. + *

+ */ + private static class WeekYear implements NumberRule { + private final NumberRule mRule; + + WeekYear(final NumberRule rule) { + mRule = rule; + } + + @Override + public int estimateLength() { + return mRule.estimateLength(); + } + + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + mRule.appendTo(buffer, calendar.getWeekYear()); + } + + @Override + public void appendTo(final Appendable buffer, final int value) throws IOException { + mRule.appendTo(buffer, value); + } + } + + // ----------------------------------------------------------------------- + + private static final ConcurrentMap cTimeZoneDisplayCache = new ConcurrentHashMap<>(7); + + /** + *

+ * Gets the time zone display name, using a cache for performance. + *

+ * + * @param tz the zone to query + * @param daylight true if daylight savings + * @param style the style to use {@code TimeZone.LONG} or {@code TimeZone.SHORT} + * @param locale the locale to use + * @return the textual name of the time zone + */ + static String getTimeZoneDisplay(final TimeZone tz, final boolean daylight, final int style, final Locale locale) { + final TimeZoneDisplayKey key = new TimeZoneDisplayKey(tz, daylight, style, locale); + String value = cTimeZoneDisplayCache.get(key); + if (value == null) { + // This is a very slow call, so cache the results. + value = tz.getDisplayName(daylight, style, locale); + final String prior = cTimeZoneDisplayCache.putIfAbsent(key, value); + if (prior != null) { + value = prior; + } + } + return value; + } + + /** + *

+ * Inner class to output a time zone name. + *

+ */ + private static class TimeZoneNameRule implements Rule { + private final Locale mLocale; + private final int mStyle; + private final String mStandard; + private final String mDaylight; + + /** + * Constructs an instance of {@code TimeZoneNameRule} with the specified properties. + * + * @param timeZone the time zone + * @param locale the locale + * @param style the style + */ + TimeZoneNameRule(final TimeZone timeZone, final Locale locale, final int style) { + mLocale = locale; + mStyle = style; + + mStandard = getTimeZoneDisplay(timeZone, false, style, locale); + mDaylight = getTimeZoneDisplay(timeZone, true, style, locale); + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + // We have no access to the Calendar object that will be passed to + // appendTo so base estimate on the TimeZone passed to the + // constructor + return Math.max(mStandard.length(), mDaylight.length()); + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + final TimeZone zone = calendar.getTimeZone(); + if (calendar.get(Calendar.DST_OFFSET) != 0) { + buffer.append(getTimeZoneDisplay(zone, true, mStyle, mLocale)); + } else { + buffer.append(getTimeZoneDisplay(zone, false, mStyle, mLocale)); + } + } + } + + /** + *

+ * Inner class to output a time zone as a number {@code +/-HHMM} or {@code +/-HH:MM}. + *

+ */ + private static class TimeZoneNumberRule implements Rule { + static final TimeZoneNumberRule INSTANCE_COLON = new TimeZoneNumberRule(true); + static final TimeZoneNumberRule INSTANCE_NO_COLON = new TimeZoneNumberRule(false); + + final boolean mColon; + + /** + * Constructs an instance of {@code TimeZoneNumberRule} with the specified properties. + * + * @param colon add colon between HH and MM in the output if {@code true} + */ + TimeZoneNumberRule(final boolean colon) { + mColon = colon; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return 5; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + + int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); + + if (offset < 0) { + buffer.append('-'); + offset = -offset; + } else { + buffer.append('+'); + } + + final int hours = offset / (60 * 60 * 1000); + appendDigits(buffer, hours); + + if (mColon) { + buffer.append(':'); + } + + final int minutes = offset / (60 * 1000) - 60 * hours; + appendDigits(buffer, minutes); + } + } + + /** + *

+ * Inner class to output a time zone as a number {@code +/-HHMM} or {@code +/-HH:MM}. + *

+ */ + private static class Iso8601_Rule implements Rule { + + // Sign TwoDigitHours or Z + static final Iso8601_Rule ISO8601_HOURS = new Iso8601_Rule(3); + // Sign TwoDigitHours Minutes or Z + static final Iso8601_Rule ISO8601_HOURS_MINUTES = new Iso8601_Rule(5); + // Sign TwoDigitHours : Minutes or Z + static final Iso8601_Rule ISO8601_HOURS_COLON_MINUTES = new Iso8601_Rule(6); + + /** + * Factory method for Iso8601_Rules. + * + * @param tokenLen a token indicating the length of the TimeZone String to be formatted. + * @return a Iso8601_Rule that can format TimeZone String of length {@code tokenLen}. If no such rule exists, an IllegalArgumentException will be thrown. + */ + static Iso8601_Rule getRule(final int tokenLen) { + switch (tokenLen) { + case 1: + return Iso8601_Rule.ISO8601_HOURS; + case 2: + return Iso8601_Rule.ISO8601_HOURS_MINUTES; + case 3: + return Iso8601_Rule.ISO8601_HOURS_COLON_MINUTES; + default: + throw new IllegalArgumentException("invalid number of X"); + } + } + + final int length; + + /** + * Constructs an instance of {@code Iso8601_Rule} with the specified properties. + * + * @param length The number of characters in output (unless Z is output) + */ + Iso8601_Rule(final int length) { + this.length = length; + } + + /** + * {@inheritDoc} + */ + @Override + public int estimateLength() { + return length; + } + + /** + * {@inheritDoc} + */ + @Override + public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { + int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); + if (offset == 0) { + buffer.append("Z"); + return; + } + + if (offset < 0) { + buffer.append('-'); + offset = -offset; + } else { + buffer.append('+'); + } + + final int hours = offset / (60 * 60 * 1000); + appendDigits(buffer, hours); + + if (length < 5) { + return; + } + + if (length == 6) { + buffer.append(':'); + } + + final int minutes = offset / (60 * 1000) - 60 * hours; + appendDigits(buffer, minutes); + } + } + + // ---------------------------------------------------------------------- + /** + *

+ * Inner class that acts as a compound key for time zone names. + *

+ */ + private static class TimeZoneDisplayKey { + private final TimeZone mTimeZone; + private final int mStyle; + private final Locale mLocale; + + /** + * Constructs an instance of {@code TimeZoneDisplayKey} with the specified properties. + * + * @param timeZone the time zone + * @param daylight adjust the style for daylight saving time if {@code true} + * @param style the timezone style + * @param locale the timezone locale + */ + TimeZoneDisplayKey(final TimeZone timeZone, final boolean daylight, final int style, final Locale locale) { + mTimeZone = timeZone; + if (daylight) { + mStyle = style | 0x80000000; + } else { + mStyle = style; + } + mLocale = locale; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return (mStyle * 31 + mLocale.hashCode()) * 31 + mTimeZone.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TimeZoneDisplayKey) { + final TimeZoneDisplayKey other = (TimeZoneDisplayKey) obj; + return mTimeZone.equals(other.mTimeZone) && mStyle == other.mStyle && mLocale.equals(other.mLocale); + } + return false; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FormatCache.java b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FormatCache.java new file mode 100644 index 0000000..0d8924a --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/date/format/FormatCache.java @@ -0,0 +1,252 @@ +package org.springblade.core.tool.date.format; + +import java.text.DateFormat; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Locale; +import java.util.TimeZone; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * 日期格式化器缓存
+ * Thanks to Apache Commons Lang 3.5 + * + * @since 2.16.2 + */ +abstract class FormatCache { + + /** + * No date or no time. Used in same parameters as DateFormat.SHORT or DateFormat.LONG + */ + static final int NONE = -1; + + private final ConcurrentMap cInstanceCache = new ConcurrentHashMap<>(7); + + private static final ConcurrentMap cDateTimeInstanceCache = new ConcurrentHashMap<>(7); + + /** + * 使用默认的pattern、timezone和locale获得缓存中的实例 + * @return a date/time formatter + */ + public F getInstance() { + return getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, TimeZone.getDefault(), Locale.getDefault()); + } + + /** + * 使用 pattern, time zone and locale 获得对应的 格式化器 + * + * @param pattern 非空日期格式,使用与 {@link SimpleDateFormat}相同格式 + * @param timeZone 时区,默认当前时区 + * @param locale 地区,默认使用当前地区 + * @return 格式化器 + * @throws IllegalArgumentException pattern 无效或null + */ + public F getInstance(final String pattern, TimeZone timeZone, Locale locale) { + if (pattern == null) { + throw new NullPointerException("pattern must not be null"); + } + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + if (locale == null) { + locale = Locale.getDefault(); + } + final MultipartKey key = new MultipartKey(pattern, timeZone, locale); + F format = cInstanceCache.get(key); + if (format == null) { + format = createInstance(pattern, timeZone, locale); + final F previousValue = cInstanceCache.putIfAbsent(key, format); + if (previousValue != null) { + // another thread snuck in and did the same work + // we should return the instance that is in ConcurrentMap + format = previousValue; + } + } + return format; + } + + /** + * 创建格式化器 + * + * @param pattern 非空日期格式,使用与 {@link SimpleDateFormat}相同格式 + * @param timeZone 时区,默认当前时区 + * @param locale 地区,默认使用当前地区 + * @return 格式化器 + * @throws IllegalArgumentException pattern 无效或null + */ + abstract protected F createInstance(String pattern, TimeZone timeZone, Locale locale); + + /** + *

+ * Gets a date/time formatter instance using the specified style, time zone and locale. + *

+ * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format + * @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time pattern defined + */ + // This must remain private, see LANG-884 + private F getDateTimeInstance(final Integer dateStyle, final Integer timeStyle, final TimeZone timeZone, Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + final String pattern = getPatternForStyle(dateStyle, timeStyle, locale); + return getInstance(pattern, timeZone, locale); + } + + /** + *

+ * Gets a date/time formatter instance using the specified style, time zone and locale. + *

+ * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time pattern defined + */ + // package protected, for access from FastDateFormat; do not make public or protected + F getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone, final Locale locale) { + return getDateTimeInstance(Integer.valueOf(dateStyle), Integer.valueOf(timeStyle), timeZone, locale); + } + + /** + *

+ * Gets a date formatter instance using the specified style, time zone and locale. + *

+ * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time pattern defined + */ + // package protected, for access from FastDateFormat; do not make public or protected + F getDateInstance(final int dateStyle, final TimeZone timeZone, final Locale locale) { + return getDateTimeInstance(Integer.valueOf(dateStyle), null, timeZone, locale); + } + + /** + *

+ * Gets a time formatter instance using the specified style, time zone and locale. + *

+ * + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time pattern defined + */ + // package protected, for access from FastDateFormat; do not make public or protected + F getTimeInstance(final int timeStyle, final TimeZone timeZone, final Locale locale) { + return getDateTimeInstance(null, Integer.valueOf(timeStyle), timeZone, locale); + } + + /** + *

+ * Gets a date/time format for the specified styles and locale. + *

+ * + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format + * @param locale The non-null locale of the desired format + * @return a localized standard date/time format + * @throws IllegalArgumentException if the Locale has no date/time pattern defined + */ + // package protected, for access from test code; do not make public or protected + static String getPatternForStyle(final Integer dateStyle, final Integer timeStyle, final Locale locale) { + final MultipartKey key = new MultipartKey(dateStyle, timeStyle, locale); + + String pattern = cDateTimeInstanceCache.get(key); + if (pattern == null) { + try { + DateFormat formatter; + if (dateStyle == null) { + formatter = DateFormat.getTimeInstance(timeStyle.intValue(), locale); + } else if (timeStyle == null) { + formatter = DateFormat.getDateInstance(dateStyle.intValue(), locale); + } else { + formatter = DateFormat.getDateTimeInstance(dateStyle.intValue(), timeStyle.intValue(), locale); + } + pattern = ((SimpleDateFormat) formatter).toPattern(); + final String previous = cDateTimeInstanceCache.putIfAbsent(key, pattern); + if (previous != null) { + // even though it doesn't matter if another thread put the pattern + // it's still good practice to return the String instance that is + // actually in the ConcurrentMap + pattern = previous; + } + } catch (final ClassCastException ex) { + throw new IllegalArgumentException("No date time pattern for locale: " + locale); + } + } + return pattern; + } + + // ---------------------------------------------------------------------- + /** + *

+ * Helper class to hold multi-part Map keys + *

+ */ + private static class MultipartKey { + private final Object[] keys; + private int hashCode; + + /** + * Constructs an instance of MultipartKey to hold the specified objects. + * + * @param keys the set of objects that make up the key. Each key may be null. + */ + public MultipartKey(final Object... keys) { + this.keys = keys; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final MultipartKey other = (MultipartKey) obj; + if (false == Arrays.equals(keys, other.keys)) { + return false; + } + return true; + } + + + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + if (hashCode == 0) { + int rc = 0; + for (final Object key : keys) { + if (key != null) { + rc = rc * 7 + key.hashCode(); + } + } + hashCode = rc; + } + return hashCode; + } + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/AbstractReadWriteJackson2HttpMessageConverter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/AbstractReadWriteJackson2HttpMessageConverter.java new file mode 100644 index 0000000..eb62cbb --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/AbstractReadWriteJackson2HttpMessageConverter.java @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.jackson; + +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.PrettyPrinter; +import com.fasterxml.jackson.core.util.DefaultIndenter; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.exc.InvalidDefinitionException; +import com.fasterxml.jackson.databind.ser.FilterProvider; +import org.springblade.core.tool.utils.Charsets; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConversionException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; +import org.springframework.http.converter.json.MappingJacksonValue; +import org.springframework.lang.Nullable; +import org.springframework.util.TypeUtils; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicReference; + +/** + * 分读写的 json 消息 处理器 + * + * @author L.cm + */ +public abstract class AbstractReadWriteJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter { + private static final java.nio.charset.Charset DEFAULT_CHARSET = Charsets.UTF_8; + + private ObjectMapper writeObjectMapper; + @Nullable + private PrettyPrinter ssePrettyPrinter; + + public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper) { + super(readObjectMapper); + this.writeObjectMapper = writeObjectMapper; + initSsePrettyPrinter(); + } + + public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, MediaType supportedMediaType) { + this(readObjectMapper, writeObjectMapper); + setSupportedMediaTypes(Collections.singletonList(supportedMediaType)); + initSsePrettyPrinter(); + } + + public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, MediaType... supportedMediaTypes) { + this(readObjectMapper, writeObjectMapper); + setSupportedMediaTypes(Arrays.asList(supportedMediaTypes)); + } + + private void initSsePrettyPrinter() { + setDefaultCharset(DEFAULT_CHARSET); + DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); + prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:")); + this.ssePrettyPrinter = prettyPrinter; + } + + @Override + public boolean canWrite(Class clazz, @Nullable MediaType mediaType) { + if (!canWrite(mediaType)) { + return false; + } + AtomicReference causeRef = new AtomicReference<>(); + if (this.objectMapper.canSerialize(clazz, causeRef)) { + return true; + } + logWarningIfNecessary(clazz, causeRef.get()); + return false; + } + + @Override + protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage) + throws IOException, HttpMessageNotWritableException { + + MediaType contentType = outputMessage.getHeaders().getContentType(); + JsonEncoding encoding = getJsonEncoding(contentType); + JsonGenerator generator = this.writeObjectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding); + try { + writePrefix(generator, object); + + Object value = object; + Class serializationView = null; + FilterProvider filters = null; + JavaType javaType = null; + + if (object instanceof MappingJacksonValue) { + MappingJacksonValue container = (MappingJacksonValue) object; + value = container.getValue(); + serializationView = container.getSerializationView(); + filters = container.getFilters(); + } + if (type != null && TypeUtils.isAssignable(type, value.getClass())) { + javaType = getJavaType(type, null); + } + + ObjectWriter objectWriter = (serializationView != null ? + this.writeObjectMapper.writerWithView(serializationView) : this.writeObjectMapper.writer()); + if (filters != null) { + objectWriter = objectWriter.with(filters); + } + if (javaType != null && javaType.isContainerType()) { + objectWriter = objectWriter.forType(javaType); + } + SerializationConfig config = objectWriter.getConfig(); + if (contentType != null && contentType.isCompatibleWith(MediaType.TEXT_EVENT_STREAM) && + config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { + objectWriter = objectWriter.with(this.ssePrettyPrinter); + } + objectWriter.writeValue(generator, value); + + writeSuffix(generator, object); + generator.flush(); + } catch (InvalidDefinitionException ex) { + throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex); + } catch (JsonProcessingException ex) { + throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getOriginalMessage(), ex); + } + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeBeanSerializerModifier.java b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeBeanSerializerModifier.java new file mode 100644 index 0000000..782baf1 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeBeanSerializerModifier.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.temporal.TemporalAccessor; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * jackson 默认值为 null 时的处理 + * + * 主要是为了避免 app 端出现null导致闪退 + * + * 规则: + * number -1 + * string "" + * date "" + * boolean false + * array [] + * Object {} + * + * @author L.cm + */ +public class BladeBeanSerializerModifier extends BeanSerializerModifier { + @Override + public List changeProperties( + SerializationConfig config, BeanDescription beanDesc, + List beanProperties) { + // 循环所有的beanPropertyWriter + beanProperties.forEach(writer -> { + // 如果已经有 null 序列化处理如注解:@JsonSerialize(nullsUsing = xxx) 跳过 + if (writer.hasNullSerializer()) { + return; + } + JavaType type = writer.getType(); + Class clazz = type.getRawClass(); + if (type.isTypeOrSubTypeOf(Number.class)) { + writer.assignNullSerializer(NullJsonSerializers.NUMBER_JSON_SERIALIZER); + }else if (type.isTypeOrSubTypeOf(Boolean.class)) { + writer.assignNullSerializer(NullJsonSerializers.BOOLEAN_JSON_SERIALIZER); + } else if (type.isTypeOrSubTypeOf(Character.class)) { + writer.assignNullSerializer(NullJsonSerializers.STRING_JSON_SERIALIZER); + } else if (type.isTypeOrSubTypeOf(String.class)) { + writer.assignNullSerializer(NullJsonSerializers.STRING_JSON_SERIALIZER); + } else if (type.isArrayType() || clazz.isArray() || type.isTypeOrSubTypeOf(Collection.class)) { + writer.assignNullSerializer(NullJsonSerializers.ARRAY_JSON_SERIALIZER); + } else if (type.isTypeOrSubTypeOf(OffsetDateTime.class)) { + writer.assignNullSerializer(NullJsonSerializers.STRING_JSON_SERIALIZER); + } else if (type.isTypeOrSubTypeOf(Date.class) || type.isTypeOrSubTypeOf(TemporalAccessor.class)) { + writer.assignNullSerializer(NullJsonSerializers.STRING_JSON_SERIALIZER); + } else { + writer.assignNullSerializer(NullJsonSerializers.OBJECT_JSON_SERIALIZER); + } + }); + return super.changeProperties(config, beanDesc, beanProperties); + } + + public interface NullJsonSerializers { + + JsonSerializer STRING_JSON_SERIALIZER = new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(StringPool.EMPTY); + } + }; + + JsonSerializer NUMBER_JSON_SERIALIZER = new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeNumber(StringUtil.INDEX_NOT_FOUND); + } + }; + + JsonSerializer BOOLEAN_JSON_SERIALIZER = new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeObject(Boolean.FALSE); + } + }; + + JsonSerializer ARRAY_JSON_SERIALIZER = new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartArray(); + gen.writeEndArray(); + } + }; + + JsonSerializer OBJECT_JSON_SERIALIZER = new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeEndObject(); + } + }; + + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeJavaTimeModule.java b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeJavaTimeModule.java new file mode 100644 index 0000000..d6d6b1a --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/BladeJavaTimeModule.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.jackson; + +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.PackageVersion; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.springblade.core.tool.utils.DateTimeUtil; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + +/** + * java 8 时间默认序列化 + * + * @author L.cm + */ +public class BladeJavaTimeModule extends SimpleModule { + + public BladeJavaTimeModule() { + super(PackageVersion.VERSION); + this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeUtil.DATETIME_FORMAT)); + this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeUtil.DATE_FORMAT)); + this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeUtil.TIME_FORMAT)); + this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeUtil.DATETIME_FORMAT)); + this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeUtil.DATE_FORMAT)); + this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeUtil.TIME_FORMAT)); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/JsonUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/JsonUtil.java new file mode 100644 index 0000000..9d39c20 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/JsonUtil.java @@ -0,0 +1,328 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tool.date.DatePattern; +import org.springblade.core.tool.utils.Exceptions; +import org.springblade.core.tool.utils.StringUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.util.*; + +/** + * Jackson工具类 + */ +@Slf4j +public class JsonUtil { + + /** + * 将对象序列化成json字符串 + * + * @param value javaBean + * @return jsonString json字符串 + */ + public static String toJson(T value) { + try { + return getInstance().writeValueAsString(value); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 将对象序列化成 json byte 数组 + * + * @param object javaBean + * @return jsonString json字符串 + */ + public static byte[] toJsonAsBytes(Object object) { + try { + return getInstance().writeValueAsBytes(object); + } catch (JsonProcessingException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json反序列化成对象 + * + * @param content content + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(String content, Class valueType) { + try { + return getInstance().readValue(content, valueType); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 将json反序列化成对象 + * + * @param content content + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(String content, TypeReference typeReference) { + try { + return getInstance().readValue(content, typeReference); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json byte 数组反序列化成对象 + * + * @param bytes json bytes + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(byte[] bytes, Class valueType) { + try { + return getInstance().readValue(bytes, valueType); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + + /** + * 将json反序列化成对象 + * + * @param bytes bytes + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(byte[] bytes, TypeReference typeReference) { + try { + return getInstance().readValue(bytes, typeReference); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json反序列化成对象 + * + * @param in InputStream + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(InputStream in, Class valueType) { + try { + return getInstance().readValue(in, valueType); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json反序列化成对象 + * + * @param in InputStream + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(InputStream in, TypeReference typeReference) { + try { + return getInstance().readValue(in, typeReference); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json反序列化成List对象 + * @param content content + * @param valueTypeRef class + * @param T 泛型标记 + * @return + */ + public static List parseArray(String content, Class valueTypeRef) { + try { + + if (!StringUtil.startsWithIgnoreCase(content, "[")) { + content = "[" + content + "]"; + } + + List> list = getInstance().readValue(content, new TypeReference>() { + }); + List result = new ArrayList<>(); + for (Map map : list) { + result.add(toPojo(map, valueTypeRef)); + } + return result; + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return null; + } + + public static Map toMap(String content) { + try { + return getInstance().readValue(content, Map.class); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return null; + } + + public static Map toMap(String content, Class valueTypeRef) { + try { + Map> map = getInstance().readValue(content, new TypeReference>() { + }); + Map result = new HashMap<>(); + for (Map.Entry> entry : map.entrySet()) { + result.put(entry.getKey(), toPojo(entry.getValue(), valueTypeRef)); + } + return result; + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return null; + } + + public static T toPojo(Map fromValue, Class toValueType) { + return getInstance().convertValue(fromValue, toValueType); + } + + /** + * 将json字符串转成 JsonNode + * + * @param jsonString jsonString + * @return jsonString json字符串 + */ + public static JsonNode readTree(String jsonString) { + try { + return getInstance().readTree(jsonString); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json字符串转成 JsonNode + * + * @param in InputStream + * @return jsonString json字符串 + */ + public static JsonNode readTree(InputStream in) { + try { + return getInstance().readTree(in); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json字符串转成 JsonNode + * + * @param content content + * @return jsonString json字符串 + */ + public static JsonNode readTree(byte[] content) { + try { + return getInstance().readTree(content); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 将json字符串转成 JsonNode + * + * @param jsonParser JsonParser + * @return jsonString json字符串 + */ + public static JsonNode readTree(JsonParser jsonParser) { + try { + return getInstance().readTree(jsonParser); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } + } + + public static ObjectMapper getInstance() { + return JacksonHolder.INSTANCE; + } + + private static class JacksonHolder { + private static ObjectMapper INSTANCE = new JacksonObjectMapper(); + } + + public static class JacksonObjectMapper extends ObjectMapper { + private static final long serialVersionUID = 4288193147502386170L; + + private static final Locale CHINA = Locale.CHINA; + + public JacksonObjectMapper() { + super(); + //设置地点为中国 + super.setLocale(CHINA); + //去掉默认的时间戳格式 + super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + //设置为中国上海时区 + super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault())); + //序列化时,日期的统一格式 + super.setDateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN, Locale.CHINA)); + //序列化处理 + super.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); + super.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true); + super.findAndRegisterModules(); + //失败处理 + super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //单引号处理 + super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + //反序列化时,属性不存在的兼容处理s + super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + //序列化处理 + super.setSerializerFactory(this.getSerializerFactory().withSerializerModifier(new BladeBeanSerializerModifier())); + super.getSerializerProvider().setNullValueSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER); + //日期格式化 + super.registerModule(new BladeJavaTimeModule()); + super.findAndRegisterModules(); + } + + @Override + public ObjectMapper copy() { + return super.copy(); + } + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/MappingApiJackson2HttpMessageConverter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/MappingApiJackson2HttpMessageConverter.java new file mode 100644 index 0000000..8c6536b --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/MappingApiJackson2HttpMessageConverter.java @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.lang.Nullable; + +import java.io.IOException; + +/** + * 针对 api 服务对 android 和 ios 和 web 处理的 分读写的 jackson 处理 + * + *

+ * 1. app 端上报数据是 使用 readObjectMapper + * 2. 返回给 app 端的数据使用 writeObjectMapper + *

+ * + * @author L.cm + */ +public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJackson2HttpMessageConverter { + + @Nullable + private String jsonPrefix; + + /** + * Construct a new {@link MappingApiJackson2HttpMessageConverter} using default configuration + * provided by {@link Jackson2ObjectMapperBuilder}. + */ + public MappingApiJackson2HttpMessageConverter() { + this(Jackson2ObjectMapperBuilder.json().build()); + } + + /** + * Construct a new {@link MappingApiJackson2HttpMessageConverter} with a custom {@link ObjectMapper}. + * You can use {@link Jackson2ObjectMapperBuilder} to build it easily. + * @param objectMapper ObjectMapper + * @see Jackson2ObjectMapperBuilder#json() + */ + public MappingApiJackson2HttpMessageConverter(ObjectMapper objectMapper) { + super(objectMapper, initWriteObjectMapper(objectMapper), MediaType.APPLICATION_JSON, new MediaType("application", "*+json")); + } + + private static ObjectMapper initWriteObjectMapper(ObjectMapper readObjectMapper) { + // 拷贝 readObjectMapper + ObjectMapper writeObjectMapper = readObjectMapper.copy(); + // null 处理 + writeObjectMapper.setSerializerFactory(writeObjectMapper.getSerializerFactory().withSerializerModifier(new BladeBeanSerializerModifier())); + writeObjectMapper.getSerializerProvider().setNullValueSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER); + return writeObjectMapper; + } + + /** + * Specify a custom prefix to use for this view's JSON output. + * Default is none. + * + * @param jsonPrefix jsonPrefix + * @see #setPrefixJson + */ + public void setJsonPrefix(String jsonPrefix) { + this.jsonPrefix = jsonPrefix; + } + + /** + * Indicate whether the JSON output by this view should be prefixed with ")]}', ". Default is false. + *

Prefixing the JSON string in this manner is used to help prevent JSON Hijacking. + * The prefix renders the string syntactically invalid as a script so that it cannot be hijacked. + * This prefix should be stripped before parsing the string as JSON. + * + * @param prefixJson prefixJson + * @see #setJsonPrefix + */ + public void setPrefixJson(boolean prefixJson) { + this.jsonPrefix = (prefixJson ? ")]}', " : null); + } + + @Override + protected void writePrefix(JsonGenerator generator, Object object) throws IOException { + if (this.jsonPrefix != null) { + generator.writeRaw(this.jsonPrefix); + } + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/BeanProperty.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/BeanProperty.java new file mode 100644 index 0000000..d8ecaa6 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/BeanProperty.java @@ -0,0 +1,14 @@ +package org.springblade.core.tool.support; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Bean属性 + */ +@Getter +@AllArgsConstructor +public class BeanProperty { + private final String name; + private final Class type; +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/CMap.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/CMap.java new file mode 100644 index 0000000..911f567 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/CMap.java @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support; + +import org.springblade.core.tool.utils.Func; + +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; + +/** + * 链式map + */ +public class CMap extends CaseInsensitiveHashMap { + + + private CMap(){ + + } + + /** + * 创建CMap + * @return CMap + */ + public static CMap init() { + return new CMap(); + } + + public static HashMap newHashMap() { + return new HashMap(); + } + + /** + * 设置列 + * @param attr 属性 + * @param value 值 + * @return 本身 + */ + public CMap set(String attr, Object value) { + this.put(attr, value); + return this; + } + + /** + * 设置列,当键或值为null时忽略 + * @param attr 属性 + * @param value 值 + * @return 本身 + */ + public CMap setIgnoreNull(String attr, Object value) { + if(null != attr && null != value) { + set(attr, value); + } + return this; + } + + public Object getObj(String key) { + return super.get(key); + } + + /** + * 获得特定类型值 + * + * @param 值类型 + * @param attr 字段名 + * @param defaultValue 默认值 + * @return 字段值 + */ + public T get(String attr, T defaultValue) { + final Object result = get(attr); + return (T)(result != null ? result : defaultValue); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public String getStr(String attr) { + return Func.toStr(get(attr), null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Integer getInt(String attr) { + return Func.toInt(get(attr), -1); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Long getLong(String attr) { + return Func.toLong(get(attr), -1l); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Float getFloat(String attr) { + return Func.toFloat(get(attr), null); + } + + public Double getDouble(String attr) { + return Func.toDouble(get(attr), null); + } + + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Boolean getBool(String attr) { + return Func.toBoolean(get(attr), null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public byte[] getBytes(String attr) { + return get(attr, null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Date getDate(String attr) { + return get(attr, null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Time getTime(String attr) { + return get(attr, null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Timestamp getTimestamp(String attr) { + return get(attr, null); + } + + /** + * 获得特定类型值 + * + * @param attr 字段名 + * @return 字段值 + */ + public Number getNumber(String attr) { + return get(attr, null); + } + + @Override + public CMap clone() { + return (CMap) super.clone(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/CaseInsensitiveHashMap.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/CaseInsensitiveHashMap.java new file mode 100644 index 0000000..e62b81d --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/CaseInsensitiveHashMap.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support; + +import java.util.*; + + +public class CaseInsensitiveHashMap extends LinkedHashMap { + + private static final long serialVersionUID = 9178606903603606031L; + + private final Map lowerCaseMap = new HashMap(); + + @Override + public boolean containsKey(Object key) { + Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); + return super.containsKey(realKey); + } + + @Override + public Object get(Object key) { + Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); + return super.get(realKey); + } + + @Override + public Set keySet() { + return lowerCaseMap.keySet(); + } + + @Override + public Object put(String key, Object value) { + Object oldKey = lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key); + Object oldValue = super.remove(oldKey); + super.put(key, value); + return oldValue; + } + + @Override + public void putAll(Map m) { + for (Map.Entry entry : m.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + this.put(key, value); + } + } + + @Override + public Object remove(Object key) { + Object realKey = lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH)); + return super.remove(realKey); + } + + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/FastStringWriter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/FastStringWriter.java new file mode 100644 index 0000000..4f15919 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/FastStringWriter.java @@ -0,0 +1,103 @@ +package org.springblade.core.tool.support; + +import org.springblade.core.tool.utils.StringPool; +import org.springframework.lang.Nullable; + +import java.io.Writer; + +/** + * FastStringWriter + * + * @author L.cm + */ +public class FastStringWriter extends Writer { + private StringBuilder builder; + + public FastStringWriter() { + builder = new StringBuilder(64); + } + + public FastStringWriter(final int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Negative builderfer size"); + } + builder = new StringBuilder(capacity); + } + + public FastStringWriter(@Nullable final StringBuilder builder) { + this.builder = builder != null ? builder : new StringBuilder(64); + } + + /** + * Gets the underlying StringBuilder. + * + * @return StringBuilder + */ + public StringBuilder getBuilder() { + return builder; + } + + @Override + public void write(int c) { + builder.append((char) c); + } + + @Override + public void write(char[] cbuilder, int off, int len) { + if ((off < 0) || (off > cbuilder.length) || (len < 0) || + ((off + len) > cbuilder.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + builder.append(cbuilder, off, len); + } + + @Override + public void write(String str) { + builder.append(str); + } + + @Override + public void write(String str, int off, int len) { + builder.append(str.substring(off, off + len)); + } + + @Override + public FastStringWriter append(CharSequence csq) { + if (csq == null) { + write(StringPool.NULL); + } else { + write(csq.toString()); + } + return this; + } + + @Override + public FastStringWriter append(CharSequence csq, int start, int end) { + CharSequence cs = (csq == null ? StringPool.NULL : csq); + write(cs.subSequence(start, end).toString()); + return this; + } + + @Override + public FastStringWriter append(char c) { + write(c); + return this; + } + + @Override + public String toString() { + return builder.toString(); + } + + @Override + public void flush() { + } + + @Override + public void close() { + builder.setLength(0); + builder.trimToSize(); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/IMultiOutputStream.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/IMultiOutputStream.java new file mode 100644 index 0000000..1afb28a --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/IMultiOutputStream.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support; + +import java.io.OutputStream; + +/** + * A factory for creating MultiOutputStream objects. + */ +public interface IMultiOutputStream { + + /** + * Builds the output stream. + * + * @param params the params + * @return the output stream + */ + OutputStream buildOutputStream(Integer... params) ; + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/ImagePosition.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/ImagePosition.java new file mode 100644 index 0000000..de6dca9 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/ImagePosition.java @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support; + +public class ImagePosition { + + /** 图片顶部. */ + public static final int TOP = 32; + + /** 图片中部. */ + public static final int MIDDLE = 16; + + /** 图片底部. */ + public static final int BOTTOM = 8; + + /** 图片左侧. */ + public static final int LEFT = 4; + + /** 图片居中. */ + public static final int CENTER = 2; + + /** 图片右侧. */ + public static final int RIGHT = 1; + + /** 横向边距,靠左或靠右时和边界的距离. */ + private static final int PADDING_HORI = 6; + + /** 纵向边距,靠上或靠底时和边界的距离. */ + private static final int PADDING_VERT = 6; + + + /** 图片中盒[左上角]的x坐标. */ + private int boxPosX ; + + /** 图片中盒[左上角]的y坐标. */ + private int boxPosY ; + + /** + * Instantiates a new image position. + * + * @param width the width + * @param height the height + * @param boxWidth the box width + * @param boxHeight the box height + * @param style the style + */ + public ImagePosition(int width , int height , int boxWidth , int boxHeight, int style ) { + switch(style & 7) { + case LEFT: + boxPosX = PADDING_HORI; + break; + case RIGHT: + boxPosX = width - boxWidth - PADDING_HORI; + break; + case CENTER: + default: + boxPosX = (width - boxWidth)/2; + } + switch(style >> 3 << 3) { + case TOP: + boxPosY = PADDING_VERT; + break; + case MIDDLE: + boxPosY = (height - boxHeight)/2; + break; + case BOTTOM: + default: + boxPosY = height - boxHeight - PADDING_VERT; + } + } + + + /** + * Gets the x. + * + * @return the x + */ + public int getX() { + return getX(0); + } + + /** + * Gets the x. + * + * @param x 横向偏移 + * @return the x + */ + public int getX(int x) { + return this.boxPosX + x; + } + + /** + * Gets the y. + * + * @return the y + */ + public int getY() { + return getY(0); + } + + /** + * Gets the y. + * + * @param y 纵向偏移 + * @return the y + */ + public int getY(int y) { + return this.boxPosY + y; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrFormatter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrFormatter.java new file mode 100644 index 0000000..8c2b729 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrFormatter.java @@ -0,0 +1,67 @@ +package org.springblade.core.tool.support; + +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.StringPool; + +public class StrFormatter { + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") =》 this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
+ * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) { + if (Func.isBlank(strPattern) || Func.isEmpty(argArray)) { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + //初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0;//记录已经处理到的位置 + int delimIndex;//占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) { + delimIndex = strPattern.indexOf(StringPool.EMPTY_JSON, handledPosition); + if (delimIndex == -1) {//剩余部分无占位符 + if (handledPosition == 0) { //不带占位符的模板直接返回 + return strPattern; + } else { //字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } else { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == StringPool.BACK_SLASH) {//转义符 + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == StringPool.BACK_SLASH) {//双转义符 + //转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Func.toStr(argArray[argIndex])); + handledPosition = delimIndex + 2; + } else { + //占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(StringPool.LEFT_BRACE); + handledPosition = delimIndex + 1; + } + } else {//正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Func.toStr(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // append the characters following the last {} pair. + //加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrSpliter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrSpliter.java new file mode 100644 index 0000000..9c9880a --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/StrSpliter.java @@ -0,0 +1,499 @@ +package org.springblade.core.tool.support; + +import org.springblade.core.tool.utils.Func; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 字符串切分器 + * @author Looly + * + */ +public class StrSpliter { + + //---------------------------------------------------------------------------------------------- Split by char + /** + * 切分字符串路径,仅支持Unix分界符:/ + * + * @param str 被切分的字符串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List splitPath(String str){ + return splitPath(str, 0); + } + + /** + * 切分字符串路径,仅支持Unix分界符:/ + * + * @param str 被切分的字符串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitPathToArray(String str){ + return toArray(splitPath(str)); + } + + /** + * 切分字符串路径,仅支持Unix分界符:/ + * + * @param str 被切分的字符串 + * @param limit 限制分片数 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List splitPath(String str, int limit){ + return split(str, StringPool.SLASH, limit, true, true); + } + + /** + * 切分字符串路径,仅支持Unix分界符:/ + * + * @param str 被切分的字符串 + * @param limit 限制分片数 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitPathToArray(String str, int limit){ + return toArray(splitPath(str, limit)); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitTrim(String str, char separator, boolean ignoreEmpty){ + return split(str, separator, 0, true, ignoreEmpty); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, char separator, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, 0, isTrim, ignoreEmpty); + } + + /** + * 切分字符串,大小写敏感,去除每个元素两边空白符 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List splitTrim(String str, char separator, int limit, boolean ignoreEmpty){ + return split(str, separator, limit, true, ignoreEmpty, false); + } + + /** + * 切分字符串,大小写敏感 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, limit, isTrim, ignoreEmpty, false); + } + + /** + * 切分字符串,忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitIgnoreCase(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, limit, isTrim, ignoreEmpty, true); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @param ignoreCase 是否忽略大小写 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase){ + if(StringUtil.isEmpty(str)){ + return new ArrayList(0); + } + if(limit == 1){ + return addToList(new ArrayList(1), str, isTrim, ignoreEmpty); + } + + final ArrayList list = new ArrayList<>(limit > 0 ? limit : 16); + int len = str.length(); + int start = 0;//切分后每个部分的起始 + for(int i = 0; i < len; i++){ + if(Func.equals(separator, str.charAt(i))){ + addToList(list, str.substring(start, i), isTrim, ignoreEmpty); + start = i+1;//i+1同时将start与i保持一致 + + //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串) + if(limit > 0 && list.size() > limit-2){ + break; + } + } + } + return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);//收尾 + } + + /** + * 切分字符串为字符串数组 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitToArray(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return toArray(split(str, separator, limit, isTrim, ignoreEmpty)); + } + + //---------------------------------------------------------------------------------------------- Split by String + + /** + * 切分字符串,不忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, String separator, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, -1, isTrim, ignoreEmpty, false); + } + + /** + * 切分字符串,去除每个元素两边空格,忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitTrim(String str, String separator, boolean ignoreEmpty){ + return split(str, separator, true, ignoreEmpty); + } + + /** + * 切分字符串,不忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, limit, isTrim, ignoreEmpty, false); + } + + /** + * 切分字符串,去除每个元素两边空格,忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param limit 限制分片数 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitTrim(String str, String separator, int limit, boolean ignoreEmpty){ + return split(str, separator, limit, true, ignoreEmpty); + } + + /** + * 切分字符串,忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitIgnoreCase(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return split(str, separator, limit, isTrim, ignoreEmpty, true); + } + + /** + * 切分字符串,去除每个元素两边空格,忽略大小写 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param limit 限制分片数 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List splitTrimIgnoreCase(String str, String separator, int limit, boolean ignoreEmpty){ + return split(str, separator, limit, true, ignoreEmpty, true); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符串 + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @param ignoreCase 是否忽略大小写 + * @return 切分后的集合 + * @since 3.2.1 + */ + public static List split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase){ + if(StringUtil.isEmpty(str)){ + return new ArrayList(0); + } + if(limit == 1){ + return addToList(new ArrayList(1), str, isTrim, ignoreEmpty); + } + + if(StringUtil.isEmpty(separator)){//分隔符为空时按照空白符切分 + return split(str, limit); + }else if(separator.length() == 1){//分隔符只有一个字符长度时按照单分隔符切分 + return split(str, separator.charAt(0), limit, isTrim, ignoreEmpty, ignoreCase); + } + + final ArrayList list = new ArrayList<>(); + int len = str.length(); + int separatorLen = separator.length(); + int start = 0; + int i = 0; + while(i < len){ + i = StringUtil.indexOf(str, separator, start, ignoreCase); + if(i > -1){ + addToList(list, str.substring(start, i), isTrim, ignoreEmpty); + start = i + separatorLen; + + //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串) + if(limit > 0 && list.size() > limit-2){ + break; + } + }else{ + break; + } + } + return addToList(list, str.substring(start, len), isTrim, ignoreEmpty); + } + + /** + * 切分字符串为字符串数组 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitToArray(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty){ + return toArray(split(str, separator, limit, isTrim, ignoreEmpty)); + } + + //---------------------------------------------------------------------------------------------- Split by Whitespace + + /** + * 使用空白符切分字符串
+ * 切分后的字符串两边不包含空白符,空串或空白符串并不做为元素之一 + * + * @param str 被切分的字符串 + * @param limit 限制分片数 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, int limit){ + if(StringUtil.isEmpty(str)){ + return new ArrayList(0); + } + if(limit == 1){ + return addToList(new ArrayList(1), str, true, true); + } + + final ArrayList list = new ArrayList<>(); + int len = str.length(); + int start = 0;//切分后每个部分的起始 + for(int i = 0; i < len; i++){ + if(Func.isEmpty(str.charAt(i))){ + addToList(list, str.substring(start, i), true, true); + start = i+1;//i+1同时将start与i保持一致 + + //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串) + if(limit > 0 && list.size() > limit-2){ + break; + } + } + } + return addToList(list, str.substring(start, len), true, true);//收尾 + } + + /** + * 切分字符串为字符串数组 + * + * @param str 被切分的字符串 + * @param limit 限制分片数 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitToArray(String str, int limit){ + return toArray(split(str, limit)); + } + + //---------------------------------------------------------------------------------------------- Split by regex + + /** + * 通过正则切分字符串 + * @param str 字符串 + * @param separatorPattern 分隔符正则{@link Pattern} + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty){ + if(StringUtil.isEmpty(str)){ + return new ArrayList(0); + } + if(limit == 1){ + return addToList(new ArrayList(1), str, isTrim, ignoreEmpty); + } + + if(null == separatorPattern){//分隔符为空时按照空白符切分 + return split(str, limit); + } + + final Matcher matcher = separatorPattern.matcher(str); + final ArrayList list = new ArrayList<>(); + int len = str.length(); + int start = 0; + while(matcher.find()){ + addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty); + start = matcher.end(); + + //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串) + if(limit > 0 && list.size() > limit-2){ + break; + } + } + return addToList(list, str.substring(start, len), isTrim, ignoreEmpty); + } + + /** + * 通过正则切分字符串为字符串数组 + * + * @param str 被切分的字符串 + * @param separatorPattern 分隔符正则{@link Pattern} + * @param limit 限制分片数 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static String[] splitToArray(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty){ + return toArray(split(str, separatorPattern, limit, isTrim, ignoreEmpty)); + } + + //---------------------------------------------------------------------------------------------- Split by length + + /** + * 根据给定长度,将给定字符串截取为多个部分 + * + * @param str 字符串 + * @param len 每一个小节的长度 + * @return 截取后的字符串数组 + */ + public static String[] splitByLength(String str, int len) { + int partCount = str.length() / len; + int lastPartCount = str.length() % len; + int fixPart = 0; + if (lastPartCount != 0) { + fixPart = 1; + } + + final String[] strs = new String[partCount + fixPart]; + for (int i = 0; i < partCount + fixPart; i++) { + if (i == partCount + fixPart - 1 && lastPartCount != 0) { + strs[i] = str.substring(i * len, i * len + lastPartCount); + } else { + strs[i] = str.substring(i * len, i * len + len); + } + } + return strs; + } + + //---------------------------------------------------------------------------------------------------------- Private method start + /** + * 将字符串加入List中 + * @param list 列表 + * @param part 被加入的部分 + * @param isTrim 是否去除两端空白符 + * @param ignoreEmpty 是否略过空字符串(空字符串不做为一个元素) + * @return 列表 + */ + private static List addToList(List list, String part, boolean isTrim, boolean ignoreEmpty){ + part = part.toString(); + if(isTrim){ + part = part.trim(); + } + if(false == ignoreEmpty || false == part.isEmpty()){ + list.add(part); + } + return list; + } + + /** + * List转Array + * @param list List + * @return Array + */ + private static String[] toArray(List list){ + return list.toArray(new String[list.size()]); + } + //---------------------------------------------------------------------------------------------------------- Private method end +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/Try.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/Try.java new file mode 100644 index 0000000..0900248 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/Try.java @@ -0,0 +1,29 @@ +package org.springblade.core.tool.support; + +import org.springblade.core.tool.utils.Exceptions; + +import java.util.Objects; +import java.util.function.Function; + +/** + * 当 Lambda 遇上受检异常 + * https://segmentfault.com/a/1190000007832130 + */ +public class Try { + + public static Function of(UncheckedFunction mapper) { + Objects.requireNonNull(mapper); + return t -> { + try { + return mapper.apply(t); + } catch (Exception e) { + throw Exceptions.unchecked(e); + } + }; + } + + @FunctionalInterface + public interface UncheckedFunction { + R apply(T t) throws Exception; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/HTMLFilter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/HTMLFilter.java new file mode 100644 index 0000000..9d99b42 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/HTMLFilter.java @@ -0,0 +1,554 @@ +package org.springblade.core.tool.support.xss; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML filtering utility for protecting against XSS (Cross Site Scripting). + *

+ * This code is licensed LGPLv3 + *

+ * This code is a Java port of the original work in PHP by Cal Hendersen. + * http://code.iamcal.com/php/lib_filter/ + *

+ * The trickiest part of the translation was handling the differences in regex handling + * between PHP and Java. These resources were helpful in the process: + *

+ * http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html + * http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php + * http://www.regular-expressions.info/modifiers.html + *

+ * A note on naming conventions: instance variables are prefixed with a "v"; global + * constants are in all caps. + *

+ * Sample use: + * String input = ... + * String clean = new HTMLFilter().filter( input ); + *

+ * The class is not thread safe. Create a new instance if in doubt. + *

+ * If you find bugs or have suggestions on improvement (especially regarding + * performance), please contact us. The latest version of this + * source, and our contact details, can be found at http://xss-html-filter.sf.net + * + * @author Joseph O'Connell + * @author Cal Hendersen + * @author Michael Semb Wever + */ +public final class HTMLFilter { + + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("<"); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "" or "") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + private boolean vDebug = false; + /** + * flag determining whether to try to make tags when presented with "unbalanced" + * angle brackets (e.g. "" becomes " text "). If set to false, + * unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[]{"img"}; + vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"}; + vDisallowed = new String[]{}; + vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp. + vProtocolAtts = new String[]{"src", "href"}; + vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"}; + vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"}; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = true; + } + + /** + * Set debug flag to true. Otherwise use default settings. See the default constructor. + * + * @param debug turn debug on with a true argument + */ + public HTMLFilter(final boolean debug) { + this(); + vDebug = debug; + + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + public HTMLFilter(final Map conf) { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() { + vTagCounts.clear(); + } + + private void debug(final String msg) { + if (vDebug) { + Logger.getAnonymousLogger().info(msg); + } + } + + //--------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + //--------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted + * html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) { + reset(); + String s = input; + + debug("************************************************"); + debug(" INPUT: " + input); + + s = escapeComments(s); + debug(" escapeComments: " + s); + + s = balanceHTML(s); + debug(" balanceHTML: " + s); + + s = checkTags(s); + debug(" checkTags: " + s); + + s = processRemoveBlanks(s); + debug("processRemoveBlanks: " + s); + + s = validateEntities(s); + debug(" validateEntites: " + s); + + debug("************************************************\n\n"); + return s; + } + + public boolean isAlwaysMakeTags() { + return alwaysMakeTags; + } + + public boolean isStripComments() { + return stripComment; + } + + private String escapeComments(final String s) { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) { + final String match = m.group(1); //(.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) { + if (alwaysMakeTags) { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } else { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + s = buf.toString(); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + for (String key : vTagCounts.keySet()) { + for (int ii = 0; ii < vTagCounts.get(key); ii++) { + s += ""; + } + } + + return s; + } + + private String processRemoveBlanks(final String s) { + String result = s; + for (String tag : vRemoveBlanks) { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) { + if (!inArray(name, vSelfClosingTags)) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + //debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) { + String params = ""; + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList(); + final List paramValues = new ArrayList(); + while (m2.find()) { + paramNames.add(m2.group(1)); //([a-z0-9]+) + paramValues.add(m2.group(3)); //(.*?) + } + while (m3.find()) { + paramNames.add(m3.group(1)); //([a-z0-9]+) + paramValues.add(m3.group(3)); //([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + +// debug( "paramName='" + paramName + "'" ); +// debug( "paramValue='" + paramValue + "'" ); +// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) { + if (inArray(paramName, vProtocolAtts)) { + paramValue = processParamProtocol(paramValue); + } + params += " " + paramName + "=\"" + paramValue + "\""; + } + } + + if (inArray(name, vSelfClosingTags)) { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) { + ending = ""; + } + + if (ending == null || ending.length() < 1) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } else { + vTagCounts.put(name, 1); + } + } else { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } else { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1, s.length()); + if (s.startsWith("#//")) { + s = "#" + s.substring(3, s.length()); + } + } + } + + return s; + } + + private String decodeEntities(String s) { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) { + final String one = m.group(1); //([^&;]*) + final String two = m.group(2); //(?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) { + if (encodeQuotes) { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) { + final String one = m.group(1); //(>|^) + final String two = m.group(2); //([^<]+?) + final String three = m.group(3); //(<|$) + m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three)); + } + m.appendTail(buf); + return buf.toString(); + } else { + return s; + } + } + + private String checkEntity(final String preamble, final String term) { + + return ";".equals(term) && isValidEntity(preamble) + ? '&' + preamble + : "&" + preamble; + } + + private boolean isValidEntity(final String entity) { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) { + for (String item : array) { + if (item != null && item.equals(s)) { + return true; + } + } + return false; + } + + private boolean allowed(final String name) { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/SQLFilter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/SQLFilter.java new file mode 100644 index 0000000..0e0a1f8 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/SQLFilter.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support.xss; + + +import org.springblade.core.tool.utils.StringUtil; + +/** + * SQL过滤 + */ +public class SQLFilter { + + /** + * SQL注入过滤 + * + * @param str 待验证的字符串 + */ + public static String sqlInject(String str) { + if (StringUtil.isBlank(str)) { + return null; + } + //去掉'|"|;|\字符 + str = str.replace("'", ""); + str = str.replace("\"", ""); + str = str.replace(";", ""); + str = str.replace("\\", ""); + + //转换成小写 + str = str.toLowerCase(); + + //非法字符 + String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"}; + + //判断是否包含非法字符 + for (String keyword : keywords) { + if (str.indexOf(keyword) != -1) { + throw new RuntimeException("包含非法字符"); + } + } + + return str; + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssFilter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssFilter.java new file mode 100644 index 0000000..bb86a80 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssFilter.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support.xss; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * XSS过滤 + */ +public class XssFilter implements Filter { + + @Override + public void init(FilterConfig config) throws ServletException { + + } + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + ServletRequest requestWrapper = null; + if(request instanceof HttpServletRequest) { + requestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) request); + } + if(requestWrapper == null) { + chain.doFilter(request, response); + } else { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() { + + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssHttpServletRequestWrapper.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..184305d --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.support.xss; + +import org.springblade.core.tool.utils.Charsets; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.WebUtil; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * XSS过滤处理 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + + //没被包装过的HttpServletRequest(特殊场景,需要自己过滤) + HttpServletRequest orgRequest; + //html过滤 + private final static HTMLFilter htmlFilter = new HTMLFilter(); + // 缓存报文,支持多次读取流 + private final byte[] body; + + public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException { + super(request); + orgRequest = request; + body = WebUtil.getRequestBytes(request); + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException { + + //为空,直接返回 + if (null == super.getHeader(HttpHeaders.CONTENT_TYPE)) { + return super.getInputStream(); + } + + //非json类型,直接返回 + if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) + && !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)) { + return super.getInputStream(); + } + + //为空,直接返回 + String requestStr = WebUtil.getRequestStr(orgRequest, body); + if (StringUtil.isBlank(requestStr)) { + return super.getInputStream(); + } + + requestStr = xssEncode(requestStr); + + final ByteArrayInputStream bis = new ByteArrayInputStream(requestStr.getBytes(Charsets.UTF_8)); + + return new ServletInputStream() { + + @Override + public boolean isFinished() { + return true; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + @Override + public int read() throws IOException { + return bis.read(); + } + }; + + } + + @Override + public String getParameter(String name) { + String value = super.getParameter(xssEncode(name)); + if (StringUtil.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + @Override + public String[] getParameterValues(String name) { + String[] parameters = super.getParameterValues(name); + if (parameters == null || parameters.length == 0) { + return null; + } + + for (int i = 0; i < parameters.length; i++) { + parameters[i] = xssEncode(parameters[i]); + } + return parameters; + } + + @Override + public Map getParameterMap() { + Map map = new LinkedHashMap<>(); + Map parameters = super.getParameterMap(); + for (String key : parameters.keySet()) { + String[] values = parameters.get(key); + for (int i = 0; i < values.length; i++) { + values[i] = xssEncode(values[i]); + } + map.put(key, values); + } + return map; + } + + @Override + public String getHeader(String name) { + String value = super.getHeader(xssEncode(name)); + if (StringUtil.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + private String xssEncode(String input) { + return htmlFilter.filter(input); + } + + /** + * 获取最原始的request + */ + public HttpServletRequest getOrgRequest() { + return orgRequest; + } + + /** + * 获取最原始的request + */ + public static HttpServletRequest getOrgRequest(HttpServletRequest request) { + if (request instanceof XssHttpServletRequestWrapper) { + return ((XssHttpServletRequestWrapper) request).getOrgRequest(); + } + + return request; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/AESUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/AESUtil.java new file mode 100644 index 0000000..93168c2 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/AESUtil.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.util.Assert; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.util.Arrays; + +/** + * 完全兼容微信所使用的AES加密方式。 + * aes的key必须是256byte长(比如32个字符),可以使用AesKit.genAesKey()来生成一组key + * + * @author L.cm + */ +public class AESUtil { + + private AESUtil() {} + + public static String genAesKey() { + return StringUtil.random(32); + } + + public static byte[] encrypt(byte[] content, String aesTextKey) { + return encrypt(content, aesTextKey.getBytes(Charsets.UTF_8)); + } + + public static byte[] encrypt(String content, String aesTextKey) { + return encrypt(content.getBytes(Charsets.UTF_8), aesTextKey.getBytes(Charsets.UTF_8)); + } + + public static byte[] encrypt(String content, java.nio.charset.Charset charset, String aesTextKey) { + return encrypt(content.getBytes(charset), aesTextKey.getBytes(Charsets.UTF_8)); + } + + public static byte[] decrypt(byte[] content, String aesTextKey) { + return decrypt(content, aesTextKey.getBytes(Charsets.UTF_8)); + } + + public static String decryptToStr(byte[] content, String aesTextKey) { + return new String(decrypt(content, aesTextKey.getBytes(Charsets.UTF_8)), Charsets.UTF_8); + } + + public static String decryptToStr(byte[] content, String aesTextKey, java.nio.charset.Charset charset) { + return new String(decrypt(content, aesTextKey.getBytes(Charsets.UTF_8)), charset); + } + + public static byte[] encrypt(byte[] content, byte[] aesKey) { + Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32"); + try { + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); + return cipher.doFinal(PKCS7Encoder.encode(content)); + } catch (Exception e) { + throw Exceptions.unchecked(e); + } + } + + public static byte[] decrypt(byte[] encrypted, byte[] aesKey) { + Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32"); + try { + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16)); + cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); + return PKCS7Encoder.decode(cipher.doFinal(encrypted)); + } catch (Exception e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 提供基于PKCS7算法的加解密接口. + */ + static class PKCS7Encoder { + static int BLOCK_SIZE = 32; + + static byte[] encode(byte[] src) { + int count = src.length; + // 计算需要填充的位数 + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) { + amountToPad = BLOCK_SIZE; + } + // 获得补位所用的字符 + byte pad = (byte) (amountToPad & 0xFF); + byte[] pads = new byte[amountToPad]; + for (int index = 0; index < amountToPad; index++) { + pads[index] = pad; + } + int length = count + amountToPad; + byte[] dest = new byte[length]; + System.arraycopy(src, 0, dest, 0, count); + System.arraycopy(pads, 0, dest, count, amountToPad); + return dest; + } + + static byte[] decode(byte[] decrypted) { + int pad = (int) decrypted[decrypted.length - 1]; + if (pad < 1 || pad > 32) { + pad = 0; + } + if (pad > 0) { + return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); + } + return decrypted; + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Base64Util.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Base64Util.java new file mode 100644 index 0000000..eb7b0aa --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Base64Util.java @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +/** + * Base64工具 + * + * @author L.cm + */ +public class Base64Util extends org.springframework.util.Base64Utils { + + /** + * 编码 + * + * @param value 字符串 + * @return {String} + */ + public static String encode(String value) { + return Base64Util.encode(value, Charsets.UTF_8); + } + + /** + * 编码 + * + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String encode(String value, java.nio.charset.Charset charset) { + byte[] val = value.getBytes(charset); + return new String(Base64Util.encode(val), charset); + } + + /** + * 编码URL安全 + * + * @param value 字符串 + * @return {String} + */ + public static String encodeUrlSafe(String value) { + return Base64Util.encodeUrlSafe(value, Charsets.UTF_8); + } + + /** + * 编码URL安全 + * + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String encodeUrlSafe(String value, java.nio.charset.Charset charset) { + byte[] val = value.getBytes(charset); + return new String(Base64Util.encodeUrlSafe(val), charset); + } + + /** + * 解码 + * + * @param value 字符串 + * @return {String} + */ + public static String decode(String value) { + return Base64Util.decode(value, Charsets.UTF_8); + } + + /** + * 解码 + * + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String decode(String value, java.nio.charset.Charset charset) { + byte[] val = value.getBytes(charset); + byte[] decodedValue = Base64Util.decode(val); + return new String(decodedValue, charset); + } + + /** + * 解码URL安全 + * + * @param value 字符串 + * @return {String} + */ + public static String decodeUrlSafe(String value) { + return Base64Util.decodeUrlSafe(value, Charsets.UTF_8); + } + + /** + * 解码URL安全 + * + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String decodeUrlSafe(String value, java.nio.charset.Charset charset) { + byte[] val = value.getBytes(charset); + byte[] decodedValue = Base64Util.decodeUrlSafe(val); + return new String(decodedValue, charset); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/BeanUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/BeanUtil.java new file mode 100644 index 0000000..2912f6c --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/BeanUtil.java @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + + +import org.springblade.core.tool.support.BeanProperty; +import org.springframework.beans.BeansException; +import org.springframework.cglib.beans.BeanCopier; +import org.springframework.cglib.beans.BeanGenerator; +import org.springframework.cglib.beans.BeanMap; +import org.springframework.util.Assert; + +import java.util.Map; + +/** + * 实体工具类 + * + * @author L.cm + */ +public class BeanUtil extends org.springframework.beans.BeanUtils { + + /** + * 实例化对象 + * @param clazz 类 + * @param 泛型标记 + * @return 对象 + */ + @SuppressWarnings("unchecked") + public static T newInstance(Class clazz) { + return (T) instantiateClass(clazz); + } + + /** + * 实例化对象 + * @param clazzStr 类名 + * @param 泛型标记 + * @return 对象 + */ + public static T newInstance(String clazzStr) { + try { + Class clazz = Class.forName(clazzStr); + return newInstance(clazz); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** + * 获取Bean的属性 + * @param bean bean + * @param propertyName 属性名 + * @return 属性值 + */ + public static Object getProperty(Object bean, String propertyName) { + Assert.notNull(bean, "bean Could not null"); + return BeanMap.create(bean).get(propertyName); + } + + /** + * 设置Bean属性 + * @param bean bean + * @param propertyName 属性名 + * @param value 属性值 + */ + public static void setProperty(Object bean, String propertyName, Object value) { + Assert.notNull(bean, "bean Could not null"); + BeanMap.create(bean).put(propertyName, value); + } + + /** + * 深复制 + * + * 注意:不支持链式Bean + * + * @param source 源对象 + * @param 泛型标记 + * @return T + */ + @SuppressWarnings("unchecked") + public static T clone(T source) { + return (T) BeanUtil.copy(source, source.getClass()); + } + + /** + * copy 对象属性到另一个对象,默认不使用Convert + * + * 注意:不支持链式Bean,链式用 copyProperties + * + * @param source 源对象 + * @param clazz 类名 + * @param 泛型标记 + * @return T + */ + public static T copy(Object source, Class clazz) { + BeanCopier copier = BeanCopier.create(source.getClass(), clazz, false); + + T to = newInstance(clazz); + copier.copy(source, to, null); + return to; + } + + /** + * 拷贝对象 + * + * 注意:不支持链式Bean,链式用 copyProperties + * + * @param source 源对象 + * @param targetBean 需要赋值的对象 + */ + public static void copy(Object source, Object targetBean) { + BeanCopier copier = BeanCopier + .create(source.getClass(), targetBean.getClass(), false); + + copier.copy(source, targetBean, null); + } + + /** + * Copy the property values of the given source bean into the target class. + *

Note: The source and target classes do not have to match or even be derived + * from each other, as long as the properties match. Any bean properties that the + * source bean exposes but the target bean does not will silently be ignored. + *

This is just a convenience method. For more complex transfer needs, + * @param source the source bean + * @param target the target bean class + * @param 泛型标记 + * @throws BeansException if the copying failed + * @return T + */ + public static T copyProperties(Object source, Class target) throws BeansException { + T to = newInstance(target); + BeanUtil.copyProperties(source, to); + return to; + } + + /** + * 将对象装成map形式 + * @param bean 源对象 + * @return {Map} + */ + @SuppressWarnings("unchecked") + public static Map toMap(Object bean) { + return BeanMap.create(bean); + } + + /** + * 将map 转为 bean + * @param beanMap map + * @param valueType 对象类型 + * @param 泛型标记 + * @return {T} + */ + public static T toBean(Map beanMap, Class valueType) { + T bean = BeanUtil.newInstance(valueType); + BeanMap.create(bean).putAll(beanMap); + return bean; + } + + /** + * 给一个Bean添加字段 + * @param superBean 父级Bean + * @param props 新增属性 + * @return {Object} + */ + public static Object generator(Object superBean, BeanProperty... props) { + Class superclass = superBean.getClass(); + Object genBean = generator(superclass, props); + BeanUtil.copy(superBean, genBean); + return genBean; + } + + /** + * 给一个class添加字段 + * @param superclass 父级 + * @param props 新增属性 + * @return {Object} + */ + public static Object generator(Class superclass, BeanProperty... props) { + BeanGenerator generator = new BeanGenerator(); + generator.setSuperclass(superclass); + generator.setUseCache(true); + for (BeanProperty prop : props) { + generator.addProperty(prop.getName(), prop.getType()); + } + return generator.create(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Charsets.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Charsets.java new file mode 100644 index 0000000..16603d2 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Charsets.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + + +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; + +/** + * 字符集工具类 + */ +public class Charsets { + + /** + * 字符集ISO-8859-1 + */ + public static final java.nio.charset.Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; + /** + * 字符集GBK + */ + public static final java.nio.charset.Charset GBK = java.nio.charset.Charset.forName(StringPool.GBK); + /** + * 字符集utf-8 + */ + public static final java.nio.charset.Charset UTF_8 = StandardCharsets.UTF_8; + + /** + * 转换为Charset对象 + * @param charsetName 字符集,为空则返回默认字符集 + * @return Charsets + * @throws UnsupportedCharsetException 编码不支持 + */ + public static java.nio.charset.Charset charset(String charsetName) throws UnsupportedCharsetException { + return StringUtil.isBlank(charsetName) ? java.nio.charset.Charset.defaultCharset() : java.nio.charset.Charset.forName(charsetName); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ClassUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ClassUtil.java new file mode 100644 index 0000000..997af1f --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ClassUtil.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.core.BridgeMethodResolver; +import org.springframework.core.DefaultParameterNameDiscoverer; +import org.springframework.core.MethodParameter; +import org.springframework.core.ParameterNameDiscoverer; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.annotation.SynthesizingMethodParameter; +import org.springframework.web.method.HandlerMethod; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +/** + * 类工具类 + * + * @author L.cm + */ +public class ClassUtil extends org.springframework.util.ClassUtils { + + private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer(); + + /** + * 获取方法参数信息 + * @param constructor 构造器 + * @param parameterIndex 参数序号 + * @return {MethodParameter} + */ + public static MethodParameter getMethodParameter(Constructor constructor, int parameterIndex) { + MethodParameter methodParameter = new SynthesizingMethodParameter(constructor, parameterIndex); + methodParameter.initParameterNameDiscovery(PARAMETER_NAME_DISCOVERER); + return methodParameter; + } + + /** + * 获取方法参数信息 + * @param method 方法 + * @param parameterIndex 参数序号 + * @return {MethodParameter} + */ + public static MethodParameter getMethodParameter(Method method, int parameterIndex) { + MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex); + methodParameter.initParameterNameDiscovery(PARAMETER_NAME_DISCOVERER); + return methodParameter; + } + + /** + * 获取Annotation + * @param method Method + * @param annotationType 注解类 + * @param 泛型标记 + * @return {Annotation} + */ + public static A getAnnotation(Method method, Class annotationType) { + Class targetClass = method.getDeclaringClass(); + // The method may be on an interface, but we need attributes from the target class. + // If the target class is null, the method will be unchanged. + Method specificMethod = ClassUtil.getMostSpecificMethod(method, targetClass); + // If we are dealing with method with generic parameters, find the original method. + specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); + // 先找方法,再找方法上的类 + A annotation = AnnotatedElementUtils.findMergedAnnotation(specificMethod, annotationType);; + if (null != annotation) { + return annotation; + } + // 获取类上面的Annotation,可能包含组合注解,故采用spring的工具类 + return AnnotatedElementUtils.findMergedAnnotation(specificMethod.getDeclaringClass(), annotationType); + } + + /** + * 获取Annotation + * @param handlerMethod HandlerMethod + * @param annotationType 注解类 + * @param 泛型标记 + * @return {Annotation} + */ + public static A getAnnotation(HandlerMethod handlerMethod, Class annotationType) { + // 先找方法,再找方法上的类 + A annotation = handlerMethod.getMethodAnnotation(annotationType); + if (null != annotation) { + return annotation; + } + // 获取类上面的Annotation,可能包含组合注解,故采用spring的工具类 + Class beanType = handlerMethod.getBeanType(); + return AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/CollectionUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/CollectionUtil.java new file mode 100644 index 0000000..0d1dc22 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/CollectionUtil.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; + +/** + * 集合工具类 + * + * @author L.cm + */ +public class CollectionUtil extends org.springframework.util.CollectionUtils { + + /** + * Check whether the given Array contains the given element. + * @param array the Array to check + * @param element the element to look for + * @param The generic tag + * @return {@code true} if found, {@code false} else + */ + public static boolean contains(@Nullable T[] array, final T element) { + if (array == null) { return false; } + return Arrays.stream(array).anyMatch(x -> ObjectUtil.nullSafeEquals(x, element)); + } + + /** + * 对象是否为数组对象 + * + * @param obj 对象 + * @return 是否为数组对象,如果为{@code null} 返回false + */ + public static boolean isArray(Object obj) { + if (null == obj) { + return false; + } + return obj.getClass().isArray(); + } + + /** + * Determine whether the given Collection is not empty: + * i.e. {@code null} or of zero length. + * @param coll the Collection to check + */ + public static boolean isNotEmpty(@Nullable Collection coll) { + return !CollectionUtils.isEmpty(coll); + } + + /** + * Determine whether the given Map is not empty: + * i.e. {@code null} or of zero length. + * @param map the Map to check + */ + public static boolean isNotEmpty(@Nullable Map map) { + return !CollectionUtils.isEmpty(map); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DateTimeUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DateTimeUtil.java new file mode 100644 index 0000000..83961df --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DateTimeUtil.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springblade.core.tool.date.DatePattern; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; + +/** + * DateTime 工具类 + * + * @author L.cm + */ +public class DateTimeUtil { + public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN); + public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN); + public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN); + + /** + * 日期时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatDateTime(TemporalAccessor temporal) { + return DATETIME_FORMAT.format(temporal); + } + + /** + * 日期时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatDate(TemporalAccessor temporal) { + return DATE_FORMAT.format(temporal); + } + + /** + * 时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatTime(TemporalAccessor temporal) { + return TIME_FORMAT.format(temporal); + } + + /** + * 日期格式化 + * + * @param temporal 时间 + * @param pattern 表达式 + * @return 格式化后的时间 + */ + public static String format(TemporalAccessor temporal, String pattern) { + return DateTimeFormatter.ofPattern(pattern).format(temporal); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param pattern 表达式 + * @return 时间 + */ + public static TemporalAccessor parse(String dateStr, String pattern) { + DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern); + return format.parse(dateStr); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param formatter DateTimeFormatter + * @return 时间 + */ + public static TemporalAccessor parse(String dateStr, DateTimeFormatter formatter) { + return formatter.parse(dateStr); + } + + /** + * 时间转 Instant + * @param dateTime 时间 + * @return Instant + */ + public static Instant toInstant(LocalDateTime dateTime) { + return dateTime.atZone(ZoneId.systemDefault()).toInstant(); + } + + /** + * Instant 转 时间 + * @param instant Instant + * @return Instant + */ + public static LocalDateTime toDateTime(Instant instant) { + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DigestUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DigestUtil.java new file mode 100644 index 0000000..38e7110 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DigestUtil.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 加密相关工具类直接使用Spring util封装,减少jar依赖 + * + * @author L.cm + */ +public class DigestUtil extends org.springframework.util.DigestUtils { + + /** + * Calculates the MD5 digest and returns the value as a 32 character hex string. + * + * @param data Data to digest + * @return MD5 digest as a hex string + */ + public static String md5Hex(final String data) { + return DigestUtil.md5DigestAsHex(data.getBytes(Charsets.UTF_8)); + } + + /** + * Return a hexadecimal string representation of the MD5 digest of the given bytes. + * @param bytes the bytes to calculate the digest over + * @return a hexadecimal digest string + */ + public static String md5Hex(final byte[] bytes) { + return DigestUtil.md5DigestAsHex(bytes); + } + + private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); + + public static String sha1(String srcStr){ + return hash("SHA-1", srcStr); + } + + public static String sha256(String srcStr){ + return hash("SHA-256", srcStr); + } + + public static String sha384(String srcStr){ + return hash("SHA-384", srcStr); + } + + public static String sha512(String srcStr){ + return hash("SHA-512", srcStr); + } + + public static String hash(String algorithm, String srcStr) { + try { + MessageDigest md = MessageDigest.getInstance(algorithm); + byte[] bytes = md.digest(srcStr.getBytes(Charsets.UTF_8)); + return toHex(bytes); + } catch (NoSuchAlgorithmException e) { + throw Exceptions.unchecked(e); + } + } + + public static String toHex(byte[] bytes) { + StringBuilder ret = new StringBuilder(bytes.length * 2); + for (int i=0; i> 4) & 0x0f]); + ret.append(HEX_DIGITS[bytes[i] & 0x0f]); + } + return ret.toString(); + } + + public static boolean slowEquals(@Nullable String a, @Nullable String b) { + if (a == null || b == null) { + return false; + } + return slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8)); + } + + public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) { + if (a == null || b == null) { + return false; + } + if (a.length != b.length) { + return false; + } + int diff = a.length ^ b.length; + for(int i=0; i + * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springblade.core.tool.support.FastStringWriter; + +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.UndeclaredThrowableException; + +/** + * 异常处理工具类 + */ +public class Exceptions { + + /** + * 将CheckedException转换为UncheckedException. + * + * @param e Throwable + * @return {RuntimeException} + */ + public static RuntimeException unchecked(Throwable e) { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) { + return new IllegalArgumentException(e); + } else if (e instanceof InvocationTargetException) { + return new RuntimeException(((InvocationTargetException) e).getTargetException()); + } else if (e instanceof RuntimeException) { + return (RuntimeException) e; + } else { + return new RuntimeException(e); + } + } + + /** + * 代理异常解包 + * + * @param wrapped 包装过得异常 + * @return 解包后的异常 + */ + public static Throwable unwrap(Throwable wrapped) { + Throwable unwrapped = wrapped; + while (true) { + if (unwrapped instanceof InvocationTargetException) { + unwrapped = ((InvocationTargetException) unwrapped).getTargetException(); + } else if (unwrapped instanceof UndeclaredThrowableException) { + unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable(); + } else { + return unwrapped; + } + } + } + + /** + * 将ErrorStack转化为String. + * + * @param ex Throwable + * @return {String} + */ + public static String getStackTraceAsString(Throwable ex) { + FastStringWriter stringWriter = new FastStringWriter(); + ex.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Func.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Func.java new file mode 100644 index 0000000..8320031 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Func.java @@ -0,0 +1,1412 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import org.springblade.core.tool.date.ConcurrentDateFormat; +import org.springblade.core.tool.date.DateUtil; +import org.springblade.core.tool.jackson.JsonUtil; +import org.springframework.beans.BeansException; +import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; +import org.springframework.web.method.HandlerMethod; + +import java.io.Closeable; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.time.Duration; +import java.time.format.DateTimeFormatter; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.util.*; +import java.util.function.Supplier; + +/** + * 工具包集合,只做简单的调用,不删除原有工具类 + * + * @author L.cm + */ +public class Func { + + /** + * Checks that the specified object reference is not {@code null}. This + * method is designed primarily for doing parameter validation in methods + * and constructors, as demonstrated below: + *

+	 * public Foo(Bar bar) {
+	 *     this.bar = $.requireNotNull(bar);
+	 * }
+	 * 
+ * + * @param obj the object reference to check for nullity + * @param the type of the reference + * @return {@code obj} if not {@code null} + * @throws NullPointerException if {@code obj} is {@code null} + */ + public static T requireNotNull(T obj) { + return Objects.requireNonNull(obj); + } + + /** + * Checks that the specified object reference is not {@code null} and + * throws a customized {@link NullPointerException} if it is. This method + * is designed primarily for doing parameter validation in methods and + * constructors with multiple parameters, as demonstrated below: + *
+	 * public Foo(Bar bar, Baz baz) {
+	 *     this.bar = $.requireNotNull(bar, "bar must not be null");
+	 *     this.baz = $.requireNotNull(baz, "baz must not be null");
+	 * }
+	 * 
+ * + * @param obj the object reference to check for nullity + * @param message detail message to be used in the event that a {@code + * NullPointerException} is thrown + * @param the type of the reference + * @return {@code obj} if not {@code null} + * @throws NullPointerException if {@code obj} is {@code null} + */ + public static T requireNotNull(T obj, String message) { + return Objects.requireNonNull(obj, message); + } + + /** + * Checks that the specified object reference is not {@code null} and + * throws a customized {@link NullPointerException} if it is. + * + *

Unlike the method {@link #requireNotNull(Object, String)}, + * this method allows creation of the message to be deferred until + * after the null check is made. While this may confer a + * performance advantage in the non-null case, when deciding to + * call this method care should be taken that the costs of + * creating the message supplier are less than the cost of just + * creating the string message directly. + * + * @param obj the object reference to check for nullity + * @param messageSupplier supplier of the detail message to be + * used in the event that a {@code NullPointerException} is thrown + * @param the type of the reference + * @return {@code obj} if not {@code null} + * @throws NullPointerException if {@code obj} is {@code null} + * @since 1.8 + */ + public static T requireNotNull(T obj, Supplier messageSupplier) { + return Objects.requireNonNull(obj, messageSupplier); + } + + /** + * Returns {@code true} if the provided reference is {@code null} otherwise + * returns {@code false}. + * + * This method exists to be used as a + * {@link java.util.function.Predicate}, {@code filter($::isNull)} + * + * @param obj a reference to be checked against {@code null} + * @return {@code true} if the provided reference is {@code null} otherwise + * {@code false} + * + * @see java.util.function.Predicate + * @since 1.8 + */ + public static boolean isNull(@Nullable Object obj) { + return Objects.isNull(obj); + } + + /** + * Returns {@code true} if the provided reference is non-{@code null} + * otherwise returns {@code false}. + * + * This method exists to be used as a + * {@link java.util.function.Predicate}, {@code filter($::notNull)} + * + * @param obj a reference to be checked against {@code null} + * @return {@code true} if the provided reference is non-{@code null} + * otherwise {@code false} + * + * @see java.util.function.Predicate + * @since 1.8 + */ + public static boolean notNull(@Nullable Object obj) { + return Objects.nonNull(obj); + } + + /** + * 首字母变小写 + * @param str 字符串 + * @return {String} + */ + public static String firstCharToLower(String str) { + return StringUtil.lowerFirst(str); + } + + /** + * 首字母变大写 + * @param str 字符串 + * @return {String} + */ + public static String firstCharToUpper(String str) { + return StringUtil.upperFirst(str); + } + + /** + * Check whether the given {@code CharSequence} contains actual text. + *

More specifically, this method returns {@code true} if the + * {@code CharSequence} is not {@code null}, its length is greater than + * 0, and it contains at least one non-whitespace character. + *

+	 * $.isBlank(null)		= true
+	 * $.isBlank("")		= true
+	 * $.isBlank(" ")		= true
+	 * $.isBlank("12345")	= false
+	 * $.isBlank(" 12345 ")	= false
+	 * 
+ * + * @param cs the {@code CharSequence} to check (may be {@code null}) + * @return {@code true} if the {@code CharSequence} is not {@code null}, + * its length is greater than 0, and it does not contain whitespace only + * @see Character#isWhitespace + */ + public static boolean isBlank(@Nullable final CharSequence cs) { + return StringUtil.isBlank(cs); + } + + /** + *

Checks if a CharSequence is not empty (""), not null and not whitespace only.

+ *
+	 * $.isNotBlank(null)	= false
+	 * $.isNotBlank("")		= false
+	 * $.isNotBlank(" ")	= false
+	 * $.isNotBlank("bob")	= true
+	 * $.isNotBlank("  bob  ") = true
+	 * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is + * not empty and not null and not whitespace + * @see Character#isWhitespace + */ + public static boolean isNotBlank(@Nullable final CharSequence cs) { + return StringUtil.isNotBlank(cs); + } + + /** + * 有 任意 一个 Blank + * @param css CharSequence + * @return boolean + */ + public static boolean isAnyBlank(final CharSequence... css) { + return StringUtil.isAnyBlank(css); + } + + /** + * 是否全非 Blank + * @param css CharSequence + * @return boolean + */ + public static boolean isNoneBlank(final CharSequence... css) { + return StringUtil.isNoneBlank(css); + } + + /** + * Determine whether the given object is an array: + * either an Object array or a primitive array. + * @param obj the object to check + * @return 是否数组 + */ + public static boolean isArray(@Nullable Object obj) { + return ObjectUtil.isArray(obj); + } + + /** + * Determine whether the given object is empty: + * i.e. {@code null} or of zero length. + * @param obj the object to check + * @return 数组是否为空 + */ + public static boolean isEmpty(@Nullable Object obj) { + return ObjectUtil.isEmpty(obj); + } + + /** + * Determine whether the given object is not empty: + * i.e. {@code null} or of zero length. + * @param obj the object to check + * @return 是否不为空 + */ + public static boolean isNotEmpty(@Nullable Object obj) { + return !ObjectUtil.isEmpty(obj); + } + + /** + * Determine whether the given array is empty: + * i.e. {@code null} or of zero length. + * @param array the array to check + * @return 数组是否为空 + */ + public static boolean isEmpty(@Nullable Object[] array) { + return ObjectUtil.isEmpty(array); + } + /** + * 判断数组不为空 + * @param array 数组 + * @return 数组是否不为空 + */ + public static boolean isNotEmpty(@Nullable Object[] array) { + return ObjectUtil.isNotEmpty(array); + } + + /** + * 对象组中是否存在 Empty Object + * + * @param os + * 对象组 + * @return + */ + public static boolean hasEmpty(Object... os) { + for (Object o : os) { + if (isEmpty(o)) { + return true; + } + } + return false; + } + + /** + * 对象组中是否全是 Empty Object + * + * @param os + * @return + */ + public static boolean allEmpty(Object... os) { + for (Object o : os) { + if (!isEmpty(o)) { + return false; + } + } + return true; + } + + /** + * 比较两个对象是否相等。
+ * 相同的条件有两个,满足其一即可:
+ * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2) + * + * @param obj1 + * 对象1 + * @param obj2 + * 对象2 + * @return 是否相等 + */ + public static boolean equals(Object obj1, Object obj2) { + return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null); + } + + /** + * Determine if the given objects are equal, returning {@code true} if + * both are {@code null} or {@code false} if only one is {@code null}. + *

Compares arrays with {@code Arrays.equals}, performing an equality + * check based on the array elements rather than the array reference. + * @param o1 first Object to compare + * @param o2 second Object to compare + * @return whether the given objects are equal + * @see Object#equals(Object) + * @see Arrays#equals + */ + public static boolean equalsSafe(@Nullable Object o1, @Nullable Object o2) { + return ObjectUtil.nullSafeEquals(o1, o2); + } + + /** + * Check whether the given Array contains the given element. + * @param array the Array to check + * @param element the element to look for + * @param The generic tag + * @return {@code true} if found, {@code false} else + */ + public static boolean contains(@Nullable T[] array, final T element) { + return CollectionUtil.contains(array, element); + } + + /** + * Check whether the given Iterator contains the given element. + * @param iterator the Iterator to check + * @param element the element to look for + * @return {@code true} if found, {@code false} otherwise + */ + public static boolean contains(@Nullable Iterator iterator, Object element) { + return CollectionUtil.contains(iterator, element); + } + + /** + * Check whether the given Enumeration contains the given element. + * @param enumeration the Enumeration to check + * @param element the element to look for + * @return {@code true} if found, {@code false} otherwise + */ + public static boolean contains(@Nullable Enumeration enumeration, Object element) { + return CollectionUtil.contains(enumeration, element); + } + + /** + * 强转->string,并去掉多余空格 + * + * @param str + * @return + */ + public static String toStr(Object str) { + return toStr(str, ""); + } + + /** + * 强转->string,并去掉多余空格 + * + * @param str + * @param defaultValue + * @return + */ + public static String toStr(Object str, String defaultValue) { + if (null == str) { + return defaultValue; + } + return String.valueOf(str); + } + + /** + * 判断一个字符串是否是数字 + * @param cs the CharSequence to check, may be null + * @return {boolean} + */ + public static boolean isNumeric(final CharSequence cs) { + return StringUtil.isNumeric(cs); + } + + /** + *

Convert a String to an int, returning + * zero if the conversion fails.

+ * + *

If the string is null, zero is returned.

+ * + *
+	 *   $.toInt(null) = 0
+	 *   $.toInt("")   = 0
+	 *   $.toInt("1")  = 1
+	 * 
+ * + * @param value the string to convert, may be null + * @return the int represented by the string, or zero if + * conversion fails + */ + public static int toInt(final Object value) { + return NumberUtil.toInt(String.valueOf(value)); + } + + /** + *

Convert a String to an int, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toInt(null, 1) = 1
+	 *   $.toInt("", 1)   = 1
+	 *   $.toInt("1", 0)  = 1
+	 * 
+ * + * @param value the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static int toInt(@Nullable final Object value, final int defaultValue) { + return NumberUtil.toInt(String.valueOf(value), defaultValue); + } + + /** + *

Convert a String to a long, returning + * zero if the conversion fails.

+ * + *

If the string is null, zero is returned.

+ * + *
+	 *   $.toLong(null) = 0L
+	 *   $.toLong("")   = 0L
+	 *   $.toLong("1")  = 1L
+	 * 
+ * + * @param value the string to convert, may be null + * @return the long represented by the string, or 0 if + * conversion fails + */ + public static long toLong(final Object value) { + return NumberUtil.toLong(String.valueOf(value)); + } + + /** + *

Convert a String to a long, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toLong(null, 1L) = 1L
+	 *   $.toLong("", 1L)   = 1L
+	 *   $.toLong("1", 0L)  = 1L
+	 * 
+ * + * @param value the string to convert, may be null + * @param defaultValue the default value + * @return the long represented by the string, or the default if conversion fails + */ + public static long toLong(@Nullable final Object value, final long defaultValue) { + return NumberUtil.toLong(String.valueOf(value), defaultValue); + } + + /** + *

Convert a String to an Double, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toDouble(null, 1) = 1.0
+	 *   $.toDouble("", 1)   = 1.0
+	 *   $.toDouble("1", 0)  = 1.0
+	 * 
+ * + * @param value the string to convert, may be null + * @return the int represented by the string, or the default if conversion fails + */ + public static Double toDouble(Object value) { + return toDouble(String.valueOf(value), -1.00); + } + + /** + *

Convert a String to an Double, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toDouble(null, 1) = 1.0
+	 *   $.toDouble("", 1)   = 1.0
+	 *   $.toDouble("1", 0)  = 1.0
+	 * 
+ * + * @param value the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static Double toDouble(Object value, Double defaultValue) { + return NumberUtil.toDouble(String.valueOf(value), defaultValue); + } + + /** + *

Convert a String to an Float, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toFloat(null, 1) = 1.00f
+	 *   $.toFloat("", 1)   = 1.00f
+	 *   $.toFloat("1", 0)  = 1.00f
+	 * 
+ * + * @param value the string to convert, may be null + * @return the int represented by the string, or the default if conversion fails + */ + public static Float toFloat(Object value) { + return toFloat(String.valueOf(value), -1.0f); + } + + /** + *

Convert a String to an Float, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toFloat(null, 1) = 1.00f
+	 *   $.toFloat("", 1)   = 1.00f
+	 *   $.toFloat("1", 0)  = 1.00f
+	 * 
+ * + * @param value the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static Float toFloat(Object value, Float defaultValue) { + return NumberUtil.toFloat(String.valueOf(value), defaultValue); + } + + /** + *

Convert a String to an Boolean, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toBoolean("true", true)  = true
+	 *   $.toBoolean("false")   	= false
+	 *   $.toBoolean("", false)  	= false
+	 * 
+ * + * @param value the string to convert, may be null + * @return the int represented by the string, or the default if conversion fails + */ + public static Boolean toBoolean(Object value) { + return toBoolean(value, null); + } + + /** + *

Convert a String to an Boolean, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   $.toBoolean("true", true)  = true
+	 *   $.toBoolean("false")   	= false
+	 *   $.toBoolean("", false)  	= false
+	 * 
+ * + * @param value the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static Boolean toBoolean(Object value, Boolean defaultValue) { + if (value != null) { + String val = String.valueOf(value); + val = val.toLowerCase().trim(); + if ("true".equalsIgnoreCase(val)) { + return true; + } else if ("false".equalsIgnoreCase(val)) { + return false; + } + throw new RuntimeException("The value can not parse to Boolean : " + val); + } + return defaultValue; + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) { + return toIntArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) { + if (StringUtil.isEmpty(str)) { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) { + if (isBlank(str)) { + return new String[]{}; + } + return str.split(split); + } + + /** + * 将 long 转短字符串 为 62 进制 + * @param num 数字 + * @return 短字符串 + */ + public static String to62String(long num) { + return NumberUtil.to62String(num); + } + + /** + * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV). + *

Useful for {@code toString()} implementations. + * + * @param coll the {@code Collection} to convert + * @return the delimited {@code String} + */ + public static String join(Collection coll) { + return StringUtil.join(coll); + } + + /** + * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV). + *

Useful for {@code toString()} implementations. + * + * @param coll the {@code Collection} to convert + * @param delim the delimiter to use (typically a ",") + * @return the delimited {@code String} + */ + public static String join(Collection coll, String delim) { + return StringUtil.join(coll, delim); + } + + /** + * Convert a {@code String} array into a comma delimited {@code String} + * (i.e., CSV). + *

Useful for {@code toString()} implementations. + * + * @param arr the array to display + * @return the delimited {@code String} + */ + public static String join(Object[] arr) { + return StringUtil.join(arr); + } + + /** + * Convert a {@code String} array into a delimited {@code String} (e.g. CSV). + *

Useful for {@code toString()} implementations. + * + * @param arr the array to display + * @param delim the delimiter to use (typically a ",") + * @return the delimited {@code String} + */ + public static String join(Object[] arr, String delim) { + return StringUtil.join(arr, delim); + } + + /** + * 生成uuid + * + * @return UUID + */ + public static String randomUUID() { + return StringUtil.randomUUID(); + } + + /** + * 转义HTML用于安全过滤 + * + * @param html html + * @return {String} + */ + public static String escapeHtml(String html) { + return StringUtil.escapeHtml(html); + } + + /** + * 随机数生成 + * + * @param count 字符长度 + * @return 随机数 + */ + public static String random(int count) { + return StringUtil.random(count); + } + + /** + * 随机数生成 + * + * @param count 字符长度 + * @param randomType 随机数类别 + * @return 随机数 + */ + public static String random(int count, RandomType randomType) { + return StringUtil.random(count, randomType); + } + + /** + * Calculates the MD5 digest and returns the value as a 32 character hex string. + * + * @param data Data to digest + * @return MD5 digest as a hex string + */ + public static String md5Hex(final String data) { + return DigestUtil.md5Hex(data); + } + + /** + * Return a hexadecimal string representation of the MD5 digest of the given bytes. + * + * @param bytes the bytes to calculate the digest over + * @return a hexadecimal digest string + */ + public static String md5Hex(final byte[] bytes) { + return DigestUtil.md5Hex(bytes); + } + + public static String sha1(String srcStr) { + return DigestUtil.sha1(srcStr); + } + + public static String sha256(String srcStr) { + return DigestUtil.sha256(srcStr); + } + + public static String sha384(String srcStr) { + return DigestUtil.sha384(srcStr); + } + + public static String sha512(String srcStr) { + return DigestUtil.sha512(srcStr); + } + + /** + * 自定义加密 先MD5再SHA1 + * @param data + * @return + */ + public static String encrypt(String data) { + return DigestUtil.encrypt(data); + } + + /** + * 编码 + * @param value 字符串 + * @return {String} + */ + public static String encodeBase64(String value) { + return Base64Util.encode(value); + } + + /** + * 编码 + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String encodeBase64(String value, Charset charset) { + return Base64Util.encode(value, charset); + } + + /** + * 编码URL安全 + * @param value 字符串 + * @return {String} + */ + public static String encodeBase64UrlSafe(String value) { + return Base64Util.encodeUrlSafe(value); + } + + /** + * 编码URL安全 + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String encodeBase64UrlSafe(String value, Charset charset) { + return Base64Util.encodeUrlSafe(value, charset); + } + + /** + * 解码 + * @param value 字符串 + * @return {String} + */ + public static String decodeBase64(String value) { + return Base64Util.decode(value); + } + + /** + * 解码 + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String decodeBase64(String value, Charset charset) { + return Base64Util.decode(value, charset); + } + + /** + * 解码URL安全 + * @param value 字符串 + * @return {String} + */ + public static String decodeBase64UrlSafe(String value) { + return Base64Util.decodeUrlSafe(value); + } + + /** + * 解码URL安全 + * @param value 字符串 + * @param charset 字符集 + * @return {String} + */ + public static String decodeBase64UrlSafe(String value, Charset charset) { + return Base64Util.decodeUrlSafe(value, charset); + } + + /** + * closeQuietly + * + * @param closeable 自动关闭 + */ + public static void closeQuietly(@Nullable Closeable closeable) { + IOUtil.closeQuietly(closeable); + } + + /** + * InputStream to String utf-8 + * + * @param input the InputStream to read from + * @return the requested String + * @throws NullPointerException if the input is null + */ + public static String toString(InputStream input) { + return IOUtil.toString(input); + } + + /** + * InputStream to String + * + * @param input the InputStream to read from + * @param charset the Charsets + * @return the requested String + * @throws NullPointerException if the input is null + */ + public static String toString(@Nullable InputStream input, Charset charset) { + return IOUtil.toString(input, charset); + } + + public static byte[] toByteArray(@Nullable InputStream input) { + return IOUtil.toByteArray(input); + } + + /** + * 将对象序列化成json字符串 + * + * @param object javaBean + * @return jsonString json字符串 + */ + public static String toJson(Object object) { + return JsonUtil.toJson(object); + } + + /** + * 将对象序列化成 json byte 数组 + * + * @param object javaBean + * @return jsonString json字符串 + */ + public static byte[] toJsonAsBytes(Object object) { + return JsonUtil.toJsonAsBytes(object); + } + + /** + * 将json字符串转成 JsonNode + * + * @param jsonString jsonString + * @return jsonString json字符串 + */ + public static JsonNode readTree(String jsonString) { + return JsonUtil.readTree(jsonString); + } + + /** + * 将json字符串转成 JsonNode + * + * @param in InputStream + * @return jsonString json字符串 + */ + public static JsonNode readTree(InputStream in) { + return JsonUtil.readTree(in); + } + + /** + * 将json字符串转成 JsonNode + * + * @param content content + * @return jsonString json字符串 + */ + public static JsonNode readTree(byte[] content) { + return JsonUtil.readTree(content); + } + + /** + * 将json字符串转成 JsonNode + * + * @param jsonParser JsonParser + * @return jsonString json字符串 + */ + public static JsonNode readTree(JsonParser jsonParser) { + return JsonUtil.readTree(jsonParser); + } + + /** + * 将json byte 数组反序列化成对象 + * + * @param bytes json bytes + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(byte[] bytes, Class valueType) { + return JsonUtil.parse(bytes, valueType); + } + + /** + * 将json反序列化成对象 + * + * @param jsonString jsonString + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(String jsonString, Class valueType) { + return JsonUtil.parse(jsonString, valueType); + } + + /** + * 将json反序列化成对象 + * + * @param in InputStream + * @param valueType class + * @param T 泛型标记 + * @return Bean + */ + public static T parse(InputStream in, Class valueType) { + return JsonUtil.parse(in, valueType); + } + + /** + * 将json反序列化成对象 + * + * @param bytes bytes + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(byte[] bytes, TypeReference typeReference) { + return JsonUtil.parse(bytes, typeReference); + } + + /** + * 将json反序列化成对象 + * + * @param jsonString jsonString + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(String jsonString, TypeReference typeReference) { + return JsonUtil.parse(jsonString, typeReference); + } + + /** + * 将json反序列化成对象 + * + * @param in InputStream + * @param typeReference 泛型类型 + * @param T 泛型标记 + * @return Bean + */ + public static T parse(InputStream in, TypeReference typeReference) { + return JsonUtil.parse(in, typeReference); + } + + /** + * Encode all characters that are either illegal, or have any reserved + * meaning, anywhere within a URI, as defined in + * RFC 3986. + * This is useful to ensure that the given String will be preserved as-is + * and will not have any o impact on the structure or meaning of the URI. + * @param source the String to be encoded + * @return the encoded String + */ + public static String encode(String source) { + return URLUtil.encode(source, Charsets.UTF_8); + } + + /** + * Encode all characters that are either illegal, or have any reserved + * meaning, anywhere within a URI, as defined in + * RFC 3986. + * This is useful to ensure that the given String will be preserved as-is + * and will not have any o impact on the structure or meaning of the URI. + * @param source the String to be encoded + * @param charset the character encoding to encode to + * @return the encoded String + */ + public static String encode(String source, Charset charset) { + return URLUtil.encode(source, charset); + } + + /** + * Decode the given encoded URI component. + *

See {@link StringUtils#uriDecode(String, Charset)} for the decoding rules. + * @param source the encoded String + * @return the decoded value + * @throws IllegalArgumentException when the given source contains invalid encoded sequences + * @see StringUtils#uriDecode(String, Charset) + * @see java.net.URLDecoder#decode(String, String) + */ + public static String decode(String source) { + return StringUtils.uriDecode(source, Charsets.UTF_8); + } + + /** + * Decode the given encoded URI component. + *

See {@link StringUtils#uriDecode(String, Charset)} for the decoding rules. + * @param source the encoded String + * @param charset the character encoding to use + * @return the decoded value + * @throws IllegalArgumentException when the given source contains invalid encoded sequences + * @see StringUtils#uriDecode(String, Charset) + * @see java.net.URLDecoder#decode(String, String) + */ + public static String decode(String source, Charset charset) { + return StringUtils.uriDecode(source, charset); + } + + /** + * 日期时间格式化 + * + * @param date 时间 + * @return 格式化后的时间 + */ + public static String formatDateTime(Date date) { + return DateUtil.formatDateTime(date); + } + + /** + * 日期格式化 + * + * @param date 时间 + * @return 格式化后的时间 + */ + public static String formatDate(Date date) { + return DateUtil.formatDate(date); + } + + /** + * 时间格式化 + * + * @param date 时间 + * @return 格式化后的时间 + */ + public static String formatTime(Date date) { + return DateUtil.formatTime(date); + } + + /** + * 日期格式化 + * + * @param date 时间 + * @param pattern 表达式 + * @return 格式化后的时间 + */ + public static String format(Date date, String pattern) { + return DateUtil.format(date, pattern); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param pattern 表达式 + * @return 时间 + */ + public static Date parseDate(String dateStr, String pattern) { + return DateUtil.parse(dateStr, pattern); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param format ConcurrentDateFormat + * @return 时间 + */ + public static Date parse(String dateStr, ConcurrentDateFormat format) { + return DateUtil.parse(dateStr, format); + } + + /** + * 日期时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatDateTime(TemporalAccessor temporal) { + return DateTimeUtil.formatDateTime(temporal); + } + + /** + * 日期时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatDate(TemporalAccessor temporal) { + return DateTimeUtil.formatDate(temporal); + } + + /** + * 时间格式化 + * + * @param temporal 时间 + * @return 格式化后的时间 + */ + public static String formatTime(TemporalAccessor temporal) { + return DateTimeUtil.formatTime(temporal); + } + + /** + * 日期格式化 + * + * @param temporal 时间 + * @param pattern 表达式 + * @return 格式化后的时间 + */ + public static String format(TemporalAccessor temporal, String pattern) { + return DateTimeUtil.format(temporal, pattern); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param pattern 表达式 + * @return 时间 + */ + public static TemporalAccessor parse(String dateStr, String pattern) { + return DateTimeUtil.parse(dateStr, pattern); + } + + /** + * 将字符串转换为时间 + * + * @param dateStr 时间字符串 + * @param formatter DateTimeFormatter + * @return 时间 + */ + public static TemporalAccessor parse(String dateStr, DateTimeFormatter formatter) { + return DateTimeUtil.parse(dateStr, formatter); + } + + /** + * 时间比较 + * + * @param startInclusive the start instant, inclusive, not null + * @param endExclusive the end instant, exclusive, not null + * @return a {@code Duration}, not null + */ + public static Duration between(Temporal startInclusive, Temporal endExclusive) { + return Duration.between(startInclusive, endExclusive); + } + + /** + * 获取方法参数信息 + * @param constructor 构造器 + * @param parameterIndex 参数序号 + * @return {MethodParameter} + */ + public static MethodParameter getMethodParameter(Constructor constructor, int parameterIndex) { + return ClassUtil.getMethodParameter(constructor, parameterIndex); + } + + /** + * 获取方法参数信息 + * @param method 方法 + * @param parameterIndex 参数序号 + * @return {MethodParameter} + */ + public static MethodParameter getMethodParameter(Method method, int parameterIndex) { + return ClassUtil.getMethodParameter(method, parameterIndex); + } + + /** + * 获取Annotation + * @param annotatedElement AnnotatedElement + * @param annotationType 注解类 + * @param 泛型标记 + * @return {Annotation} + */ + @Nullable + public static A getAnnotation(AnnotatedElement annotatedElement, Class annotationType) { + return AnnotatedElementUtils.findMergedAnnotation(annotatedElement, annotationType); + } + + /** + * 获取Annotation + * @param method Method + * @param annotationType 注解类 + * @param 泛型标记 + * @return {Annotation} + */ + @Nullable + public static A getAnnotation(Method method, Class annotationType) { + return ClassUtil.getAnnotation(method, annotationType); + } + + /** + * 获取Annotation + * @param handlerMethod HandlerMethod + * @param annotationType 注解类 + * @param 泛型标记 + * @return {Annotation} + */ + @Nullable + public static A getAnnotation(HandlerMethod handlerMethod, Class annotationType) { + return ClassUtil.getAnnotation(handlerMethod, annotationType); + } + + /** + * 实例化对象 + * @param clazz 类 + * @param 泛型标记 + * @return 对象 + */ + @SuppressWarnings("unchecked") + public static T newInstance(Class clazz) { + return (T) BeanUtil.instantiateClass(clazz); + } + + /** + * 实例化对象 + * @param clazzStr 类名 + * @param 泛型标记 + * @return 对象 + */ + public static T newInstance(String clazzStr) { + return BeanUtil.newInstance(clazzStr); + } + + /** + * 获取Bean的属性 + * @param bean bean + * @param propertyName 属性名 + * @return 属性值 + */ + public static Object getProperty(Object bean, String propertyName) { + return BeanUtil.getProperty(bean, propertyName); + } + + /** + * 设置Bean属性 + * @param bean bean + * @param propertyName 属性名 + * @param value 属性值 + */ + public static void setProperty(Object bean, String propertyName, Object value) { + BeanUtil.setProperty(bean, propertyName, value); + } + + /** + * 深复制 + * + * 注意:不支持链式Bean + * + * @param source 源对象 + * @param 泛型标记 + * @return T + */ + public static T clone(T source) { + return BeanUtil.clone(source); + } + + /** + * copy 对象属性到另一个对象,默认不使用Convert + * + * 注意:不支持链式Bean,链式用 copyProperties + * + * @param source 源对象 + * @param clazz 类名 + * @param 泛型标记 + * @return T + */ + public static T copy(Object source, Class clazz) { + return BeanUtil.copy(source, clazz); + } + + /** + * 拷贝对象 + * + * 注意:不支持链式Bean,链式用 copyProperties + * + * @param source 源对象 + * @param targetBean 需要赋值的对象 + */ + public static void copy(Object source, Object targetBean) { + BeanUtil.copy(source, targetBean); + } + + /** + * Copy the property values of the given source bean into the target class. + *

Note: The source and target classes do not have to match or even be derived + * from each other, as long as the properties match. Any bean properties that the + * source bean exposes but the target bean does not will silently be ignored. + *

This is just a convenience method. For more complex transfer needs, + * @param source the source bean + * @param clazz the target bean class + * @param 泛型标记 + * @throws BeansException if the copying failed + * @return T + */ + public static T copyProperties(Object source, Class clazz) throws BeansException { + return BeanUtil.copyProperties(source, clazz); + } + + /** + * 将对象装成map形式 + * @param bean 源对象 + * @return {Map} + */ + public static Map toMap(Object bean) { + return BeanUtil.toMap(bean); + } + /** + * 将map 转为 bean + * @param beanMap map + * @param valueType 对象类型 + * @param 泛型标记 + * @return {T} + */ + public static T toBean(Map beanMap, Class valueType) { + return BeanUtil.toBean(beanMap, valueType); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/IOUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/IOUtil.java new file mode 100644 index 0000000..84be0f0 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/IOUtil.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * IOUtil + * + * @author L.cm + */ +public class IOUtil extends org.springframework.util.StreamUtils { + + /** + * closeQuietly + * + * @param closeable 自动关闭 + */ + public static void closeQuietly(@Nullable Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException ioe) { + // ignore + } + } + + /** + * InputStream to String utf-8 + * + * @param input the InputStream to read from + * @return the requested String + */ + public static String toString(InputStream input) { + return toString(input, Charsets.UTF_8); + } + + /** + * InputStream to String + * + * @param input the InputStream to read from + * @param charset the Charsets + * @return the requested String + */ + public static String toString(@Nullable InputStream input, java.nio.charset.Charset charset) { + try { + return IOUtil.copyToString(input, charset); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } finally { + IOUtil.closeQuietly(input); + } + } + + public static byte[] toByteArray(@Nullable InputStream input) { + try { + return IOUtil.copyToByteArray(input); + } catch (IOException e) { + throw Exceptions.unchecked(e); + } finally { + IOUtil.closeQuietly(input); + } + } + + /** + * Writes chars from a String to bytes on an + * OutputStream using the specified character encoding. + *

+ * This method uses {@link String#getBytes(String)}. + * + * @param data the String to write, null ignored + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws IOException if an I/O error occurs + */ + public static void write(@Nullable final String data, final OutputStream output, final java.nio.charset.Charset encoding) throws IOException { + if (data != null) { + output.write(data.getBytes(encoding)); + } + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ImageUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ImageUtil.java new file mode 100644 index 0000000..e5cb753 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ImageUtil.java @@ -0,0 +1,428 @@ + +package org.springblade.core.tool.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springblade.core.tool.support.IMultiOutputStream; +import org.springblade.core.tool.support.ImagePosition; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.color.ColorSpace; +import java.awt.geom.AffineTransform; +import java.awt.image.*; +import java.io.*; +import java.net.URL; + +public final class ImageUtil { + + /** + * Logger for this class + */ + private static Logger LOGGER = LoggerFactory.getLogger(ImageUtil.class); + + /** 默认输出图片类型 */ + public static final String DEFAULT_IMG_TYPE = "JPEG"; + + private ImageUtil() { + + } + + /** + * 转换输入流到byte + * @param src + * @return + * @throws IOException + */ + public static byte[] toByteArray(BufferedImage src, String type) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageIO.write(src, defaultString(type, DEFAULT_IMG_TYPE), os); + return os.toByteArray(); + } + + /** + * 获取图像内容 + * @param srcImageFile 文件路径 + * @return + */ + public static BufferedImage readImage(String srcImageFile) { + try { + return ImageIO.read(new File(srcImageFile)); + } catch (IOException e) { + LOGGER.error("Error readImage",e); + } + return null; + } + /** + * 获取图像内容 + * @param srcImageFile 文件 + * @return + */ + public static BufferedImage readImage(File srcImageFile) { + try { + return ImageIO.read(srcImageFile); + } catch (IOException e) { + LOGGER.error("Error readImage",e); + } + return null; + } + /** + * 获取图像内容 + * @param srcInputStream 输入流 + * @return + */ + public static BufferedImage readImage(InputStream srcInputStream) { + try { + return ImageIO.read(srcInputStream); + } catch (IOException e) { + LOGGER.error("Error readImage",e); + } + return null; + } + /** + * 获取图像内容 + * @param url URL地址 + * @return + */ + public static BufferedImage readImage(URL url) { + try { + return ImageIO.read(url); + } catch (IOException e) { + LOGGER.error("Error readImage",e); + } + return null; + } + + + /** + * 缩放图像(按比例缩放) + * @param src 源图像 + * @param output 输出流 + * @param scale 缩放比例 + * @param flag 缩放选择:true 放大; false 缩小; + */ + public final static void zoomScale(BufferedImage src, OutputStream output, String type, double scale, boolean flag) { + try { + // 得到源图宽 + int width = src.getWidth(); + // 得到源图长 + int height = src.getHeight(); + if (flag) { + // 放大 + width = Long.valueOf(Math.round(width * scale)).intValue(); + height = Long.valueOf(Math.round(height * scale)).intValue(); + } else { + // 缩小 + width = Long.valueOf(Math.round(width / scale)).intValue(); + height = Long.valueOf(Math.round(height / scale)).intValue(); + } + Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT); + BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = tag.getGraphics(); + // 绘制缩小后的图 + g.drawImage(image, 0, 0, null); + g.dispose(); + // 输出为文件 + ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } catch (IOException e) { + LOGGER.error("Error in zoom image", e); + } + } + /** + * 缩放图像(按高度和宽度缩放) + * @param src 源图像 + * @param output 输出流 + * @param height 缩放后的高度 + * @param width 缩放后的宽度 + * @param bb 比例不对时是否需要补白:true为补白; false为不补白; + * @param fillColor 填充色,null时为Color.WHITE + */ + public final static void zoomFixed(BufferedImage src, OutputStream output, String type, int height, int width, boolean bb, Color fillColor) { + try { + double ratio = 0.0; // 缩放比例 + Image itemp = src.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); + // 计算比例 + if (src.getHeight() > src.getWidth()) { + ratio = Integer.valueOf(height).doubleValue() / src.getHeight(); + } else { + ratio = Integer.valueOf(width).doubleValue() / src.getWidth(); + } + AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null); + itemp = op.filter(src, null); + + if (bb) { + //补白 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + Color fill = fillColor == null ? Color.white:fillColor ; + g.setColor(fill); + g.fillRect(0, 0, width, height); + if (width == itemp.getWidth(null)) { + g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), fill, null); + } else { + g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), fill, null); + } + g.dispose(); + itemp = image; + } + // 输出为文件 + ImageIO.write((BufferedImage) itemp, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } catch (IOException e) { + LOGGER.error("Error in zoom image", e); + } + } + + /** + * 图像裁剪(按指定起点坐标和宽高切割) + * @param src 源图像 + * @param output 切片后的图像地址 + * @param x 目标切片起点坐标X + * @param y 目标切片起点坐标Y + * @param width 目标切片宽度 + * @param height 目标切片高度 + */ + public final static void crop(BufferedImage src, OutputStream output, String type, int x, int y, int width, int height) { + try { + // 源图宽度 + int srcWidth = src.getHeight(); + // 源图高度 + int srcHeight = src.getWidth(); + if (srcWidth > 0 && srcHeight > 0) { + Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); + // 四个参数分别为图像起点坐标和宽高 + ImageFilter cropFilter = new CropImageFilter(x, y, width, height); + Image img = Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(image.getSource(), cropFilter)); + BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = tag.getGraphics(); + g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图 + g.dispose(); + // 输出为文件 + ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } + } catch (Exception e) { + LOGGER.error("Error in cut image", e); + } + } + + /** + * 图像切割(指定切片的行数和列数) + * @param src 源图像地址 + * @param mos 切片目标文件夹 + * @param prows 目标切片行数。默认2,必须是范围 [1, 20] 之内 + * @param pcols 目标切片列数。默认2,必须是范围 [1, 20] 之内 + */ + public final static void sliceWithNumber(BufferedImage src, IMultiOutputStream mos, String type, int prows, int pcols) { + try { + int rows = prows<=0|| prows>20 ? 2: prows; + int cols = pcols<=0|| pcols>20 ? 2: pcols; + // 源图宽度 + int srcWidth = src.getHeight(); + // 源图高度 + int srcHeight = src.getWidth(); + if (srcWidth > 0 && srcHeight > 0) { + Image img; + ImageFilter cropFilter; + Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); + // 每张切片的宽度 + int destWidth = (srcWidth%cols==0)?(srcWidth/cols):(srcWidth/cols + 1); + // 每张切片的高度 + int destHeight = (srcHeight%rows==0)?(srcHeight/rows):(srcHeight/rows+1); + // 循环建立切片 + // 改进的想法:是否可用多线程加快切割速度 + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + // 四个参数分别为图像起点坐标和宽高 + cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight); + img = Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(image.getSource(), cropFilter)); + BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); + Graphics g = tag.getGraphics(); + // 绘制缩小后的图 + g.drawImage(img, 0, 0, null); + g.dispose(); + // 输出为文件 + ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), mos.buildOutputStream(i,j) ); + } + } + } + } catch (Exception e) { + LOGGER.error("Error in slice image", e); + } + } + /** + * 图像切割(指定切片的宽度和高度) + * @param src 源图像地址 + * @param mos 切片目标文件夹 + * @param pdestWidth 目标切片宽度。默认200 + * @param pdestHeight 目标切片高度。默认150 + */ + public final static void sliceWithSize(BufferedImage src, IMultiOutputStream mos, String type, int pdestWidth, int pdestHeight) { + try { + int destWidth = pdestWidth<= 0 ? 200 : pdestWidth; + int destHeight = pdestHeight <= 0 ? 150 : pdestHeight; + // 源图宽度 + int srcWidth = src.getHeight(); + // 源图高度 + int srcHeight = src.getWidth(); + if (srcWidth > destWidth && srcHeight > destHeight) { + Image img; + ImageFilter cropFilter; + Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); + // 切片横向数量 + int cols = (srcWidth % destWidth == 0)?(srcWidth/destWidth):(srcWidth/destWidth + 1); + // 切片纵向数量 + int rows = (srcHeight % destHeight == 0)?(srcHeight/destHeight):(srcHeight/destHeight+1); + // 循环建立切片 + // 改进的想法:是否可用多线程加快切割速度 + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + // 四个参数分别为图像起点坐标和宽高 + cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight); + img = Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(image.getSource(), cropFilter)); + BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); + Graphics g = tag.getGraphics(); + // 绘制缩小后的图 + g.drawImage(img, 0, 0, null); + g.dispose(); + // 输出为文件 + ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), mos.buildOutputStream(i,j)); + } + } + } + } catch (Exception e) { + LOGGER.error("Error in slice image", e); + } + } + /** + * 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG + * @param src 源图像地址 + * @param formatName 包含格式非正式名称的 String:如JPG、JPEG、GIF等 + * @param output 目标图像地址 + */ + public final static void convert(BufferedImage src, OutputStream output, String formatName) { + try { + // 输出为文件 + ImageIO.write(src, formatName, output); + // 关闭流 + output.close(); + } catch (Exception e) { + LOGGER.error("Error in convert image", e); + } + } + /** + * 彩色转为黑白 + * @param src 源图像地址 + * @param output 目标图像地址 + */ + public final static void gray(BufferedImage src, OutputStream output, String type) { + try { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); + ColorConvertOp op = new ColorConvertOp(cs, null); + src = op.filter(src, null); + // 输出为文件 + ImageIO.write(src, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } catch (IOException e) { + LOGGER.error("Error in gray image", e); + } + } + /** + * 给图片添加文字水印 + * @param src 源图像 + * @param output 输出流 + * @param text 水印文字 + * @param font 水印的字体 + * @param color 水印的字体颜色 + * @param position 水印位置 {@link ImagePosition} + * @param x 修正值 + * @param y 修正值 + * @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 + */ + public final static void textStamp(BufferedImage src, OutputStream output, String type, String text, Font font, Color color + , int position, int x, int y, float alpha) { + try { + int width = src.getWidth(null); + int height = src.getHeight(null); + BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + g.drawImage(src, 0, 0, width, height, null); + g.setColor(color); + g.setFont(font); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); + // 在指定坐标绘制水印文字 + ImagePosition boxPos = new ImagePosition(width, height, calcTextWidth(text) * font.getSize(), font.getSize(), position); + g.drawString(text, boxPos.getX(x), boxPos.getY(y)); + g.dispose(); + // 输出为文件 + ImageIO.write((BufferedImage) image, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } catch (Exception e) { + LOGGER.error("Error in textStamp image", e); + } + } + + /** + * 给图片添加图片水印 + * @param src 源图像 + * @param output 输出流 + * @param stamp 水印图片 + * @param position 水印位置 {@link ImagePosition} + * @param x 修正值 + * @param y 修正值 + * @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 + */ + public final static void imageStamp(BufferedImage src, OutputStream output, String type, BufferedImage stamp + ,int position, int x, int y, float alpha) { + try { + int width = src.getWidth(); + int height = src.getHeight(); + BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + g.drawImage(src, 0, 0, width, height, null); + // 水印文件 + int stampWidth = stamp.getWidth(); + int stampHeight = stamp.getHeight(); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); + ImagePosition boxPos = new ImagePosition(width, height, stampWidth, stampHeight, position); + g.drawImage(stamp, boxPos.getX(x), boxPos.getY(y), stampWidth, stampHeight, null); + // 水印文件结束 + g.dispose(); + // 输出为文件 + ImageIO.write((BufferedImage) image, defaultString(type, DEFAULT_IMG_TYPE), output); + // 关闭流 + output.close(); + } catch (Exception e) { + LOGGER.error("Error imageStamp",e); + } + } + /** + * 计算text的长度(一个中文算两个字符) + * @param text + * @return + */ + public final static int calcTextWidth(String text) { + int length = 0; + for (int i = 0; i < text.length(); i++) { + if (new String(text.charAt(i) + "").getBytes().length > 1) { + length += 2; + } else { + length += 1; + } + } + return length / 2; + } + + public static String defaultString(String str, String defaultStr) { + return ((str == null) ? defaultStr : str); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Lazy.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Lazy.java new file mode 100644 index 0000000..ce9b15e --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/Lazy.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +import java.io.Serializable; +import java.util.function.Supplier; + +/** + * Holder of a value that is computed lazy. + * + * @author L.cm + */ +public class Lazy implements Supplier, Serializable { + + @Nullable + private transient volatile Supplier supplier; + @Nullable + private T value; + + /** + * Creates new instance of Lazy. + * @param supplier Supplier + * @param 泛型标记 + * @return Lazy + */ + public static Lazy of(final Supplier supplier) { + return new Lazy<>(supplier); + } + + private Lazy(final Supplier supplier) { + this.supplier = supplier; + } + + /** + * Returns the value. Value will be computed on first call. + * @return lazy value + */ + @Nullable + @Override + public T get() { + return (supplier == null) ? value : computeValue(); + } + + @Nullable + private synchronized T computeValue() { + final Supplier s = supplier; + if (s != null) { + value = s.get(); + supplier = null; + } + return value; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/NumberUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/NumberUtil.java new file mode 100644 index 0000000..4248fa1 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/NumberUtil.java @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + + +import org.springframework.lang.Nullable; + +/** + * 数字类型工具类 + * + * @author L.cm + */ +public class NumberUtil extends org.springframework.util.NumberUtils { + + //----------------------------------------------------------------------- + + /** + *

Convert a String to an int, returning + * zero if the conversion fails.

+ * + *

If the string is null, zero is returned.

+ * + *
+	 *   NumberUtil.toInt(null) = 0
+	 *   NumberUtil.toInt("")   = 0
+	 *   NumberUtil.toInt("1")  = 1
+	 * 
+ * + * @param str the string to convert, may be null + * @return the int represented by the string, or zero if + * conversion fails + */ + public static int toInt(final String str) { + return toInt(str, -1); + } + + /** + *

Convert a String to an int, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   NumberUtil.toInt(null, 1) = 1
+	 *   NumberUtil.toInt("", 1)   = 1
+	 *   NumberUtil.toInt("1", 0)  = 1
+	 * 
+ * + * @param str the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + */ + public static int toInt(@Nullable final String str, final int defaultValue) { + if (str == null) { + return defaultValue; + } + try { + return Integer.valueOf(str); + } catch (final NumberFormatException nfe) { + return defaultValue; + } + } + + /** + *

Convert a String to a long, returning + * zero if the conversion fails.

+ * + *

If the string is null, zero is returned.

+ * + *
+	 *   NumberUtil.toLong(null) = 0L
+	 *   NumberUtil.toLong("")   = 0L
+	 *   NumberUtil.toLong("1")  = 1L
+	 * 
+ * + * @param str the string to convert, may be null + * @return the long represented by the string, or 0 if + * conversion fails + */ + public static long toLong(final String str) { + return toLong(str, 0L); + } + + /** + *

Convert a String to a long, returning a + * default value if the conversion fails.

+ * + *

If the string is null, the default value is returned.

+ * + *
+	 *   NumberUtil.toLong(null, 1L) = 1L
+	 *   NumberUtil.toLong("", 1L)   = 1L
+	 *   NumberUtil.toLong("1", 0L)  = 1L
+	 * 
+ * + * @param str the string to convert, may be null + * @param defaultValue the default value + * @return the long represented by the string, or the default if conversion fails + */ + public static long toLong(@Nullable final String str, final long defaultValue) { + if (str == null) { + return defaultValue; + } + try { + return Long.valueOf(str); + } catch (final NumberFormatException nfe) { + return defaultValue; + } + } + + /** + *

Convert a String to a Double + * + * @param value + * @return double value + */ + public static Double toDouble(String value) { + return toDouble(value, null); + } + + /** + *

Convert a String to a Double + * + * @param value + * @param defaultValue 默认值 + * @return double value + */ + public static Double toDouble(@Nullable String value, Double defaultValue) { + if (value != null) { + return Double.valueOf(value.trim()); + } + return defaultValue; + } + + /** + *

Convert a String to a Double + * + * @param value + * @return double value + */ + public static Float toFloat(String value) { + return toFloat(value, null); + } + + /** + *

Convert a String to a Double + * + * @param value + * @param defaultValue 默认值 + * @return double value + */ + public static Float toFloat(@Nullable String value, Float defaultValue) { + if (value != null) { + return Float.valueOf(value.trim()); + } + return defaultValue; + } + + /** + * All possible chars for representing a number as a String + */ + private final static char[] DIGITS = { + '0' , '1' , '2' , '3' , '4' , '5' , + '6' , '7' , '8' , '9' , 'a' , 'b' , + 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , + 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , + 'o' , 'p' , 'q' , 'r' , 's' , 't' , + 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , + 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , + 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , + 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , + 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , + 'Y' , 'Z' + }; + + /** + * 将 long 转短字符串 为 62 进制 + * @param i 数字 + * @return 短字符串 + */ + public static String to62String(long i) { + int radix = DIGITS.length; + char[] buf = new char[65]; + int charPos = 64; + i = -i; + while (i <= -radix) { + buf[charPos--] = DIGITS[(int)(-(i % radix))]; + i = i / radix; + } + buf[charPos] = DIGITS[(int)(-i)]; + + return new String(buf, charPos, (65 - charPos)); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/OKHttpUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/OKHttpUtil.java new file mode 100644 index 0000000..42e3706 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/OKHttpUtil.java @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; + +import java.util.Map; + +/** + * Http请求工具类 + */ +@Slf4j +public class OKHttpUtil { + + public static MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + public static MediaType XML = MediaType.parse("application/xml; charset=utf-8"); + + /** + * GET + * + * @param url 请求的url + * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null + * @return + */ + public static String get(String url, Map queries) { + return get(url, null, queries); + } + + /** + * GET + * + * @param url 请求的url + * @param header 请求头 + * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null + * @return + */ + public static String get(String url, Map header, Map queries) { + StringBuffer sb = new StringBuffer(url); + if (queries != null && queries.keySet().size() > 0) { + sb.append("?clientId=blade"); + queries.forEach((k, v) -> sb.append("&" + k + "=" + v)); + } + + Request.Builder builder = new Request.Builder(); + + //添加请求头 + if (header != null && header.keySet().size() > 0) { + header.forEach((k, v) -> builder.addHeader(k, v)); + } + + Request request = builder.url(sb.toString()).build(); + return getBody(request); + } + + /** + * POST + * + * @param url 请求的url + * @param params post form 提交的参数 + * @return + */ + public static String post(String url, Map params) { + return post(url, null, params); + } + + /** + * POST + * + * @param url 请求的url + * @param header 请求头 + * @param params post form 提交的参数 + * @return + */ + public static String post(String url, Map header, Map params) { + FormBody.Builder formBuilder = new FormBody.Builder().add("clientId", "blade"); + //添加参数 + if (params != null && params.keySet().size() > 0) { + params.forEach((k, v) -> formBuilder.add(k, v)); + } + + Request.Builder builder = new Request.Builder(); + //添加请求头 + if (header != null && header.keySet().size() > 0) { + header.forEach((k, v) -> builder.addHeader(k, v)); + } + + Request request = builder.url(url).post(formBuilder.build()).build(); + return getBody(request); + } + + /** + * POST请求发送JSON数据 + * @param url + * @param json + * @return + */ + public static String postJson(String url, String json) { + return postJson(url, null, json); + } + + /** + * POST请求发送JSON数据 + * @param url + * @param header + * @param json + * @return + */ + public static String postJson(String url, Map header, String json) { + return postContent(url, header, json, JSON); + } + + /** + * POST请求发送xml数据 + * @param url + * @param xml + * @return + */ + public static String postXml(String url, String xml) { + return postXml(url, null, xml); + } + + /** + * POST请求发送xml数据 + * @param url + * @param header + * @param xml + * @return + */ + public static String postXml(String url, Map header, String xml) { + return postContent(url, header, xml, XML); + } + + /** + * 发送POST请求 + * @param url + * @param header + * @param content + * @param mediaType + * @return + */ + public static String postContent(String url, Map header, String content, MediaType mediaType) { + RequestBody requestBody = RequestBody.create(mediaType, content); + Request.Builder builder = new Request.Builder(); + //添加请求头 + if (header != null && header.keySet().size() > 0) { + header.forEach((k, v) -> builder.addHeader(k, v)); + } + Request request = builder.url(url).post(requestBody).build(); + return getBody(request); + } + + /** + * 获取body + * + * @param request + * @return + */ + private static String getBody(Request request) { + String responseBody = ""; + Response response = null; + try { + OkHttpClient okHttpClient = new OkHttpClient(); + response = okHttpClient.newCall(request).execute(); + if (response.isSuccessful()) { + return response.body().string(); + } + } catch (Exception e) { + log.error("okhttp3 post error >> ex = {}", e.getMessage()); + } finally { + if (response != null) { + response.close(); + } + } + return responseBody; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ObjectUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ObjectUtil.java new file mode 100644 index 0000000..d003164 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ObjectUtil.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +/** + * 对象工具类 + * + * @author L.cm + */ +public class ObjectUtil extends org.springframework.util.ObjectUtils { + + /** + * 判断元素不为空 + */ + public static boolean isNotEmpty(@Nullable Object obj) { + return !ObjectUtil.isEmpty(obj); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/PathUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/PathUtil.java new file mode 100644 index 0000000..bcd18d2 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/PathUtil.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +import java.io.File; +import java.net.URL; + +/** + * 用来获取各种目录 + * + * @author L.cm + */ +public class PathUtil { + public static final String FILE_PROTOCOL = "file"; + public static final String JAR_PROTOCOL = "jar"; + public static final String ZIP_PROTOCOL = "zip"; + public static final String FILE_PROTOCOL_PREFIX = "file:"; + public static final String JAR_FILE_SEPARATOR = "!/"; + + /** + * 获取jar包运行时的当前目录 + * @return {String} + */ + @Nullable + public static String getJarPath() { + try { + URL url = PathUtil.class.getResource("/").toURI().toURL(); + return PathUtil.toFilePath(url); + } catch (Exception e) { + String path = PathUtil.class.getResource("").getPath(); + return new File(path).getParentFile().getParentFile().getAbsolutePath(); + } + } + + @Nullable + public static String toFilePath(@Nullable URL url) { + if (url == null) { return null; } + String protocol = url.getProtocol(); + String file = URLUtil.decodeURL(url.getPath(), Charsets.UTF_8); + if (FILE_PROTOCOL.equals(protocol)) { + return new File(file).getParentFile().getParentFile().getAbsolutePath(); + } else if (JAR_PROTOCOL.equals(protocol) || ZIP_PROTOCOL.equals(protocol)) { + int ipos = file.indexOf(JAR_FILE_SEPARATOR); + if (ipos > 0) { + file = file.substring(0, ipos); + } + if (file.startsWith(FILE_PROTOCOL_PREFIX)) { + file = file.substring(FILE_PROTOCOL_PREFIX.length()); + } + return new File(file).getParentFile().getAbsolutePath(); + } + return file; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ProtostuffUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ProtostuffUtil.java new file mode 100644 index 0000000..d4a600c --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ProtostuffUtil.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import io.protostuff.LinkedBuffer; +import io.protostuff.ProtostuffIOUtil; +import io.protostuff.Schema; +import io.protostuff.runtime.RuntimeSchema; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Protostuff 工具类 + */ +public class ProtostuffUtil { + + /** + * 避免每次序列化都重新申请Buffer空间 + */ + private static LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); + /** + * 缓存Schema + */ + private static Map, Schema> schemaCache = new ConcurrentHashMap<>(); + + /** + * 序列化方法,把指定对象序列化成字节数组 + * + * @param obj + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static byte[] serialize(T obj) { + Class clazz = (Class) obj.getClass(); + Schema schema = getSchema(clazz); + byte[] data; + try { + data = ProtostuffIOUtil.toByteArray(obj, schema, buffer); + } finally { + buffer.clear(); + } + return data; + } + + /** + * 反序列化方法,将字节数组反序列化成指定Class类型 + * + * @param data + * @param clazz + * @param + * @return + */ + public static T deserialize(byte[] data, Class clazz) { + Schema schema = getSchema(clazz); + T obj = schema.newMessage(); + ProtostuffIOUtil.mergeFrom(data, obj, schema); + return obj; + } + + @SuppressWarnings("unchecked") + private static Schema getSchema(Class clazz) { + Schema schema = (Schema) schemaCache.get(clazz); + if (Objects.isNull(schema)) { + //这个schema通过RuntimeSchema进行懒创建并缓存 + //所以可以一直调用RuntimeSchema.getSchema(),这个方法是线程安全的 + schema = RuntimeSchema.getSchema(clazz); + if (Objects.nonNull(schema)) { + schemaCache.put(clazz, schema); + } + } + return schema; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RandomType.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RandomType.java new file mode 100644 index 0000000..9a15366 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RandomType.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +/** + * 生成的随机数类型 + * + * @author L.cm + */ +public enum RandomType { + /** + * INT STRING ALL + */ + INT, STRING, ALL; +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RegexUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RegexUtil.java new file mode 100644 index 0000000..762ebdd --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RegexUtil.java @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 正则表达式工具 + * + * @author L.cm + */ +public class RegexUtil { + /** + * 用户名 + */ + public static final String USER_NAME = "^[a-zA-Z\\u4E00-\\u9FA5][a-zA-Z0-9_\\u4E00-\\u9FA5]{1,11}$"; + + /** + * 密码 + */ + public static final String USER_PASSWORD = "^.{6,32}$"; + + /** + * 邮箱 + */ + public static final String EMAIL = "^\\w+([-+.]*\\w+)*@([\\da-z](-[\\da-z])?)+(\\.{1,2}[a-z]+)+$"; + + /** + * 手机号 + */ + public static final String PHONE = "^1[3456789]\\d{9}$"; + + /** + * 手机号或者邮箱 + */ + public static final String EMAIL_OR_PHONE = EMAIL + "|" + PHONE; + + /** + * URL路径 + */ + public static final String URL = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})(:[\\d]+)?([\\/\\w\\.-]*)*\\/?$"; + + /** + * 身份证校验,初级校验,具体规则有一套算法 + */ + public static final String ID_CARD = "^\\d{15}$|^\\d{17}([0-9]|X)$"; + + /** + * 域名校验 + */ + public static final String DOMAIN = "^[0-9a-zA-Z]+[0-9a-zA-Z\\.-]*\\.[a-zA-Z]{2,4}$"; + + /** + * + * 编译传入正则表达式和字符串去匹配,忽略大小写 + * @param regex 正则 + * @param beTestString 字符串 + * @return {boolean} + */ + public static boolean match(String regex, String beTestString) { + Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(beTestString); + return matcher.matches(); + } + + /** + * + * 编译传入正则表达式在字符串中寻找,如果匹配到则为true + * @param regex 正则 + * @param beTestString 字符串 + * @return {boolean} + */ + public static boolean find(String regex, String beTestString) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(beTestString); + return matcher.find(); + } + + /** + * 编译传入正则表达式在字符串中寻找,如果找到返回第一个结果 + * 找不到返回null + * @param regex 正则 + * @param beFoundString 字符串 + * @return {boolean} + */ + @Nullable + public static String findResult(String regex, String beFoundString) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(beFoundString); + if (matcher.find()) { + return matcher.group(); + } + return null; + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ResourceUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ResourceUtil.java new file mode 100644 index 0000000..937eff9 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/ResourceUtil.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.util.Assert; + +import java.io.IOException; + +/** + * 资源工具类 + * + * @author L.cm + */ +public class ResourceUtil extends org.springframework.util.ResourceUtils { + public static final String HTTP_REGEX = "^https?:.+$"; + public static final String FTP_URL_PREFIX = "ftp:"; + + /** + * 获取资源 + * + * 支持一下协议: + *

+ * 1. classpath: + * 2. file: + * 3. ftp: + * 4. http: and https: + * 5. classpath*: + * 6. C:/dir1/ and /Users/lcm + *

+ * @param resourceLocation 资源路径 + * @throws IOException IOException + * @return {Resource} + */ + public static Resource getResource(String resourceLocation) throws IOException { + Assert.notNull(resourceLocation, "Resource location must not be null"); + if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { + return new ClassPathResource(resourceLocation); + } + if (resourceLocation.startsWith(FTP_URL_PREFIX)) { + return new UrlResource(resourceLocation); + } + if (resourceLocation.matches(HTTP_REGEX)) { + return new UrlResource(resourceLocation); + } + if (resourceLocation.startsWith(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX)) { + return SpringUtil.getContext().getResource(resourceLocation); + } + return new FileSystemResource(resourceLocation); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SpringUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SpringUtil.java new file mode 100644 index 0000000..a677189 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SpringUtil.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEvent; + +/** + * spring 工具类 + */ +public class SpringUtil implements ApplicationContextAware { + + private static ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException { + SpringUtil.context = context; + } + + public static T getBean(Class clazz) { + if (clazz == null) { + return null; + } + return context.getBean(clazz); + } + + public static T getBean(String beanId) { + if (beanId == null) { + return null; + } + return (T) context.getBean(beanId); + } + + public static T getBean(String beanName, Class clazz) { + if (null == beanName || "".equals(beanName.trim())) { + return null; + } + if (clazz == null) return null; + return (T) context.getBean(beanName, clazz); + } + + public static ApplicationContext getContext() { + if (context == null) return null; + return context; + } + + public static void publishEvent(ApplicationEvent event) { + if (context == null) return; + context.publishEvent(event); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringPool.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringPool.java new file mode 100644 index 0000000..59a568d --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringPool.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +/** + * 静态 String 池 + * + * @author L.cm + */ +public interface StringPool { + + String AMPERSAND = "&"; + String AND = "and"; + String AT = "@"; + String ASTERISK = "*"; + String STAR = ASTERISK; + char SLASH = '/'; + char BACK_SLASH = '\\'; + String COLON = ":"; + String COMMA = ","; + String DASH = "-"; + String DOLLAR = "$"; + String DOT = "."; + String EMPTY = ""; + String EMPTY_JSON = "{}"; + String EQUALS = "="; + String FALSE = "false"; + String HASH = "#"; + String HAT = "^"; + String LEFT_BRACE = "{"; + String LEFT_BRACKET = "("; + String LEFT_CHEV = "<"; + String NEWLINE = "\n"; + String N = "n"; + String NO = "no"; + String NULL = "null"; + String OFF = "off"; + String ON = "on"; + String PERCENT = "%"; + String PIPE = "|"; + String PLUS = "+"; + String QUESTION_MARK = "?"; + String EXCLAMATION_MARK = "!"; + String QUOTE = "\""; + String RETURN = "\r"; + String TAB = "\t"; + String RIGHT_BRACE = "}"; + String RIGHT_BRACKET = ")"; + String RIGHT_CHEV = ">"; + String SEMICOLON = ";"; + String SINGLE_QUOTE = "'"; + String BACKTICK = "`"; + String SPACE = " "; + String TILDA = "~"; + String LEFT_SQ_BRACKET = "["; + String RIGHT_SQ_BRACKET = "]"; + String TRUE = "true"; + String UNDERSCORE = "_"; + String UTF_8 = "UTF-8"; + String GBK = "GBK"; + String ISO_8859_1 = "ISO-8859-1"; + String Y = "y"; + String YES = "yes"; + String ONE = "1"; + String ZERO = "0"; + String DOLLAR_LEFT_BRACE= "${"; + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringUtil.java new file mode 100644 index 0000000..9eeb4e2 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/StringUtil.java @@ -0,0 +1,1336 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springblade.core.tool.support.StrFormatter; +import org.springblade.core.tool.support.StrSpliter; +import org.springframework.util.Assert; +import org.springframework.web.util.HtmlUtils; + +import java.io.StringReader; +import java.io.StringWriter; +import java.text.MessageFormat; +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Stream; + +/** + * 继承自Spring util的工具类,减少jar依赖 + */ +public class StringUtil extends org.springframework.util.StringUtils { + + public static final int INDEX_NOT_FOUND = -1; + /** + * Check whether the given {@code CharSequence} contains actual text. + *

More specifically, this method returns {@code true} if the + * {@code CharSequence} is not {@code null}, its length is greater than + * 0, and it contains at least one non-whitespace character. + *

+     * StringUtil.isBlank(null) = true
+     * StringUtil.isBlank("") = true
+     * StringUtil.isBlank(" ") = true
+     * StringUtil.isBlank("12345") = false
+     * StringUtil.isBlank(" 12345 ") = false
+     * 
+ * + * @param cs the {@code CharSequence} to check (may be {@code null}) + * @return {@code true} if the {@code CharSequence} is not {@code null}, + * its length is greater than 0, and it does not contain whitespace only + * @see Character#isWhitespace + */ + public static boolean isBlank(final CharSequence cs) { + return !StringUtil.hasText(cs); + } + + /** + *

Checks if a CharSequence is not empty (""), not null and not whitespace only.

+ *
+     * StringUtil.isNotBlank(null)	  = false
+     * StringUtil.isNotBlank("")		= false
+     * StringUtil.isNotBlank(" ")	   = false
+     * StringUtil.isNotBlank("bob")	 = true
+     * StringUtil.isNotBlank("  bob  ") = true
+     * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is + * not empty and not null and not whitespace + * @see Character#isWhitespace + */ + public static boolean isNotBlank(final CharSequence cs) { + return StringUtil.hasText(cs); + } + + /** + * 有 任意 一个 Blank + * @param css CharSequence + * @return boolean + */ + public static boolean isAnyBlank(final CharSequence... css) { + if (ObjectUtil.isEmpty(css)) { + return true; + } + return Stream.of(css).anyMatch(StringUtil::isBlank); + } + + /** + * 是否全非 Blank + * @param css CharSequence + * @return boolean + */ + public static boolean isNoneBlank(final CharSequence... css) { + if (ObjectUtil.isEmpty(css)) { + return false; + } + return Stream.of(css).allMatch(StringUtil::isNotBlank); + } + + /** + * 判断一个字符串是否是数字 + * + * @param cs the CharSequence to check, may be null + * @return {boolean} + */ + public static boolean isNumeric(final CharSequence cs) { + if (isBlank(cs)) { + return false; + } + for (int i = cs.length(); --i >= 0; ) { + int chr = cs.charAt(i); + if (chr < 48 || chr > 57) + return false; + } + return true; + } + + /** + * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV). + *

Useful for {@code toString()} implementations. + * + * @param coll the {@code Collection} to convert + * @return the delimited {@code String} + */ + public static String join(Collection coll) { + return StringUtil.collectionToCommaDelimitedString(coll); + } + + /** + * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV). + *

Useful for {@code toString()} implementations. + * + * @param coll the {@code Collection} to convert + * @param delim the delimiter to use (typically a ",") + * @return the delimited {@code String} + */ + public static String join(Collection coll, String delim) { + return StringUtil.collectionToDelimitedString(coll, delim); + } + + /** + * Convert a {@code String} array into a comma delimited {@code String} + * (i.e., CSV). + *

Useful for {@code toString()} implementations. + * + * @param arr the array to display + * @return the delimited {@code String} + */ + public static String join(Object[] arr) { + return StringUtil.arrayToCommaDelimitedString(arr); + } + + /** + * Convert a {@code String} array into a delimited {@code String} (e.g. CSV). + *

Useful for {@code toString()} implementations. + * + * @param arr the array to display + * @param delim the delimiter to use (typically a ",") + * @return the delimited {@code String} + */ + public static String join(Object[] arr, String delim) { + return StringUtil.arrayToDelimitedString(arr, delim); + } + + /** + * 生成uuid + * + * @return UUID + */ + public static String randomUUID() { + ThreadLocalRandom random = ThreadLocalRandom.current(); + return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY); + } + + /** + * 转义HTML用于安全过滤 + * + * @param html html + * @return {String} + */ + public static String escapeHtml(String html) { + return HtmlUtils.htmlEscape(html); + } + + /** + * 清理字符串,清理出某些不可见字符 + * + * @param txt 字符串 + * @return {String} + */ + public static String cleanChars(String txt) { + return txt.replaceAll("[  `·•�\\f\\t\\v\\s]", ""); + } + + // 随机字符串 + private static final String _INT = "0123456789"; + private static final String _STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private static final String _ALL = _INT + _STR; + + /** + * 随机数生成 + * + * @param count 字符长度 + * @return 随机数 + */ + public static String random(int count) { + return StringUtil.random(count, RandomType.ALL); + } + + /** + * 随机数生成 + * + * @param count 字符长度 + * @param randomType 随机数类别 + * @return 随机数 + */ + public static String random(int count, RandomType randomType) { + if (count == 0) { + return ""; + } + Assert.isTrue(count > 0, "Requested random string length " + count + " is less than 0."); + final ThreadLocalRandom random = ThreadLocalRandom.current(); + char[] buffer = new char[count]; + for (int i = 0; i < count; i++) { + if (RandomType.INT == randomType) { + buffer[i] = _INT.charAt(random.nextInt(_INT.length())); + } else if (RandomType.STRING == randomType) { + buffer[i] = _STR.charAt(random.nextInt(_STR.length())); + } else { + buffer[i] = _ALL.charAt(random.nextInt(_ALL.length())); + } + } + return new String(buffer); + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") =》 this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(CharSequence template, Object... params) { + if (null == template) { + return null; + } + if (Func.isEmpty(params) || isBlank(template)) { + return template.toString(); + } + return StrFormatter.format(template.toString(), params); + } + + /** + * 有序的格式化文本,使用{number}做为占位符
+ * 例:
+ * 通常使用:format("this is {0} for {1}", "a", "b") =》 this is a for b
+ * + * @param pattern 文本格式 + * @param arguments 参数 + * @return 格式化后的文本 + */ + public static String indexedFormat(CharSequence pattern, Object... arguments) { + return MessageFormat.format(pattern.toString(), arguments); + } + + /** + * 格式化文本,使用 {varName} 占位
+ * map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue + * + * @param template 文本模板,被替换的部分用 {key} 表示 + * @param map 参数值对 + * @return 格式化后的文本 + */ + public static String format(CharSequence template, Map map) { + if (null == template) { + return null; + } + if (null == map || map.isEmpty()) { + return template.toString(); + } + + String template2 = template.toString(); + for (Map.Entry entry : map.entrySet()) { + template2 = template2.replace("{" + entry.getKey() + "}", Func.toStr(entry.getValue())); + } + return template2; + } + + /** + * 切分字符串,不去除切分后每个元素两边的空白符,不去除空白项 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @return 切分后的集合 + */ + public static List split(CharSequence str, char separator, int limit) { + return split(str, separator, limit, false, false); + } + + /** + * 切分字符串,去除切分后每个元素两边的空白符,去除空白项 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @return 切分后的集合 + * @since 3.1.2 + */ + public static List splitTrim(CharSequence str, char separator) { + return splitTrim(str, separator, -1); + } + + /** + * 切分字符串,去除切分后每个元素两边的空白符,去除空白项 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @return 切分后的集合 + * @since 3.2.0 + */ + public static List splitTrim(CharSequence str, CharSequence separator) { + return splitTrim(str, separator, -1); + } + + /** + * 切分字符串,去除切分后每个元素两边的空白符,去除空白项 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @return 切分后的集合 + * @since 3.1.0 + */ + public static List splitTrim(CharSequence str, char separator, int limit) { + return split(str, separator, limit, true, true); + } + + /** + * 切分字符串,去除切分后每个元素两边的空白符,去除空白项 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @return 切分后的集合 + * @since 3.2.0 + */ + public static List splitTrim(CharSequence str, CharSequence separator, int limit) { + return split(str, separator, limit, true, true); + } + + /** + * 切分字符串,不限制分片数量 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(CharSequence str, char separator, boolean isTrim, boolean ignoreEmpty) { + return split(str, separator, 0, isTrim, ignoreEmpty); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.0.8 + */ + public static List split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) { + if (null == str) { + return new ArrayList<>(0); + } + return StrSpliter.split(str.toString(), separator, limit, isTrim, ignoreEmpty); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符字符 + * @param limit 限制分片数,-1不限制 + * @param isTrim 是否去除切分字符串后每个元素两边的空格 + * @param ignoreEmpty 是否忽略空串 + * @return 切分后的集合 + * @since 3.2.0 + */ + public static List split(CharSequence str, CharSequence separator, int limit, boolean isTrim, boolean ignoreEmpty) { + if (null == str) { + return new ArrayList<>(0); + } + final String separatorStr = (null == separator) ? null : separator.toString(); + return StrSpliter.split(str.toString(), separatorStr, limit, isTrim, ignoreEmpty); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符 + * @return 字符串 + */ + public static String[] split(CharSequence str, CharSequence separator) { + if (str == null) { + return new String[]{}; + } + + final String separatorStr = (null == separator) ? null : separator.toString(); + return StrSpliter.splitToArray(str.toString(), separatorStr, 0, false, false); + } + + /** + * 根据给定长度,将给定字符串截取为多个部分 + * + * @param str 字符串 + * @param len 每一个小节的长度 + * @return 截取后的字符串数组 + * @see StrSpliter#splitByLength(String, int) + */ + public static String[] split(CharSequence str, int len) { + if (null == str) { + return new String[]{}; + } + return StrSpliter.splitByLength(str.toString(), len); + } + + /** + * 指定字符是否在字符串中出现过 + * + * @param str 字符串 + * @param searchChar 被查找的字符 + * @return 是否包含 + * @since 3.1.2 + */ + public static boolean contains(CharSequence str, char searchChar) { + return indexOf(str, searchChar) > -1; + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param testStrs 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + * @since 3.2.0 + */ + public static boolean containsAny(CharSequence str, CharSequence... testStrs) { + return null != getContainsStr(str, testStrs); + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串,如果包含返回找到的第一个字符串 + * + * @param str 指定字符串 + * @param testStrs 需要检查的字符串数组 + * @return 被包含的第一个字符串 + * @since 3.2.0 + */ + public static String getContainsStr(CharSequence str, CharSequence... testStrs) { + if (isEmpty(str) || Func.isEmpty(testStrs)) { + return null; + } + for (CharSequence checkStr : testStrs) { + if (str.toString().contains(checkStr)) { + return checkStr.toString(); + } + } + return null; + } + + /** + * 是否包含特定字符,忽略大小写,如果给定两个参数都为null,返回true + * + * @param str 被检测字符串 + * @param testStr 被测试是否包含的字符串 + * @return 是否包含 + */ + public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr) { + if (null == str) { + // 如果被监测字符串和 + return null == testStr; + } + return str.toString().toLowerCase().contains(testStr.toString().toLowerCase()); + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串
+ * 忽略大小写 + * + * @param str 指定字符串 + * @param testStrs 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + * @since 3.2.0 + */ + public static boolean containsAnyIgnoreCase(CharSequence str, CharSequence... testStrs) { + return null != getContainsStrIgnoreCase(str, testStrs); + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串,如果包含返回找到的第一个字符串
+ * 忽略大小写 + * + * @param str 指定字符串 + * @param testStrs 需要检查的字符串数组 + * @return 被包含的第一个字符串 + * @since 3.2.0 + */ + public static String getContainsStrIgnoreCase(CharSequence str, CharSequence... testStrs) { + if (isEmpty(str) || Func.isEmpty(testStrs)) { + return null; + } + for (CharSequence testStr : testStrs) { + if (containsIgnoreCase(str, testStr)) { + return testStr.toString(); + } + } + return null; + } + + /** + * 改进JDK subString
+ * index从0开始计算,最后一个字符为-1
+ * 如果from和to位置一样,返回 ""
+ * 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length
+ * 如果经过修正的index中from大于to,则互换from和to example:
+ * abcdefgh 2 3 =》 c
+ * abcdefgh 2 -3 =》 cde
+ * + * @param str String + * @param fromIndex 开始的index(包括) + * @param toIndex 结束的index(不包括) + * @return 字串 + */ + public static String sub(CharSequence str, int fromIndex, int toIndex) { + if (isEmpty(str)) { + return StringPool.EMPTY; + } + int len = str.length(); + + if (fromIndex < 0) { + fromIndex = len + fromIndex; + if (fromIndex < 0) { + fromIndex = 0; + } + } else if (fromIndex > len) { + fromIndex = len; + } + + if (toIndex < 0) { + toIndex = len + toIndex; + if (toIndex < 0) { + toIndex = len; + } + } else if (toIndex > len) { + toIndex = len; + } + + if (toIndex < fromIndex) { + int tmp = fromIndex; + fromIndex = toIndex; + toIndex = tmp; + } + + if (fromIndex == toIndex) { + return StringPool.EMPTY; + } + + return str.toString().substring(fromIndex, toIndex); + } + + + + /** + * 截取分隔字符串之前的字符串,不包括分隔字符串
+ * 如果给定的字符串为空串(null或"")或者分隔字符串为null,返回原字符串
+ * 如果分隔字符串为空串"",则返回空串,如果分隔字符串未找到,返回原字符串 + * + * 栗子: + * + *

+     * StringUtil.subBefore(null, *)      = null
+     * StringUtil.subBefore("", *)        = ""
+     * StringUtil.subBefore("abc", "a")   = ""
+     * StringUtil.subBefore("abcba", "b") = "a"
+     * StringUtil.subBefore("abc", "c")   = "ab"
+     * StringUtil.subBefore("abc", "d")   = "abc"
+     * StringUtil.subBefore("abc", "")    = ""
+     * StringUtil.subBefore("abc", null)  = "abc"
+     * 
+ * + * @param string 被查找的字符串 + * @param separator 分隔字符串(不包括) + * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个 + * @return 切割后的字符串 + * @since 3.1.1 + */ + public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) { + if (isEmpty(string) || separator == null) { + return null == string ? null : string.toString(); + } + + final String str = string.toString(); + final String sep = separator.toString(); + if (sep.isEmpty()) { + return StringPool.EMPTY; + } + final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep); + if (pos == INDEX_NOT_FOUND) { + return str; + } + return str.substring(0, pos); + } + + /** + * 截取分隔字符串之后的字符串,不包括分隔字符串
+ * 如果给定的字符串为空串(null或""),返回原字符串
+ * 如果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串 + * + * 栗子: + * + *
+     * StringUtil.subAfter(null, *)      = null
+     * StringUtil.subAfter("", *)        = ""
+     * StringUtil.subAfter(*, null)      = ""
+     * StringUtil.subAfter("abc", "a")   = "bc"
+     * StringUtil.subAfter("abcba", "b") = "cba"
+     * StringUtil.subAfter("abc", "c")   = ""
+     * StringUtil.subAfter("abc", "d")   = ""
+     * StringUtil.subAfter("abc", "")    = "abc"
+     * 
+ * + * @param string 被查找的字符串 + * @param separator 分隔字符串(不包括) + * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个 + * @return 切割后的字符串 + * @since 3.1.1 + */ + public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) { + if (isEmpty(string)) { + return null == string ? null : string.toString(); + } + if (separator == null) { + return StringPool.EMPTY; + } + final String str = string.toString(); + final String sep = separator.toString(); + final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep); + if (pos == INDEX_NOT_FOUND) { + return StringPool.EMPTY; + } + return str.substring(pos + separator.length()); + } + + /** + * 截取指定字符串中间部分,不包括标识字符串
+ * + * 栗子: + * + *
+     * StringUtil.subBetween("wx[b]yz", "[", "]") = "b"
+     * StringUtil.subBetween(null, *, *)          = null
+     * StringUtil.subBetween(*, null, *)          = null
+     * StringUtil.subBetween(*, *, null)          = null
+     * StringUtil.subBetween("", "", "")          = ""
+     * StringUtil.subBetween("", "", "]")         = null
+     * StringUtil.subBetween("", "[", "]")        = null
+     * StringUtil.subBetween("yabcz", "", "")     = ""
+     * StringUtil.subBetween("yabcz", "y", "z")   = "abc"
+     * StringUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
+     * 
+ * + * @param str 被切割的字符串 + * @param before 截取开始的字符串标识 + * @param after 截取到的字符串标识 + * @return 截取后的字符串 + * @since 3.1.1 + */ + public static String subBetween(CharSequence str, CharSequence before, CharSequence after) { + if (str == null || before == null || after == null) { + return null; + } + + final String str2 = str.toString(); + final String before2 = before.toString(); + final String after2 = after.toString(); + + final int start = str2.indexOf(before2); + if (start != INDEX_NOT_FOUND) { + final int end = str2.indexOf(after2, start + before2.length()); + if (end != INDEX_NOT_FOUND) { + return str2.substring(start + before2.length(), end); + } + } + return null; + } + + /** + * 截取指定字符串中间部分,不包括标识字符串
+ * + * 栗子: + * + *
+     * StringUtil.subBetween(null, *)            = null
+     * StringUtil.subBetween("", "")             = ""
+     * StringUtil.subBetween("", "tag")          = null
+     * StringUtil.subBetween("tagabctag", null)  = null
+     * StringUtil.subBetween("tagabctag", "")    = ""
+     * StringUtil.subBetween("tagabctag", "tag") = "abc"
+     * 
+ * + * @param str 被切割的字符串 + * @param beforeAndAfter 截取开始和结束的字符串标识 + * @return 截取后的字符串 + * @since 3.1.1 + */ + public static String subBetween(CharSequence str, CharSequence beforeAndAfter) { + return subBetween(str, beforeAndAfter, beforeAndAfter); + } + + /** + * 去掉指定前缀 + * + * @param str 字符串 + * @param prefix 前缀 + * @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串 + */ + public static String removePrefix(CharSequence str, CharSequence prefix) { + if (isEmpty(str) || isEmpty(prefix)) { + return StringPool.EMPTY; + } + + final String str2 = str.toString(); + if (str2.startsWith(prefix.toString())) { + return subSuf(str2, prefix.length());// 截取后半段 + } + return str2; + } + + /** + * 忽略大小写去掉指定前缀 + * + * @param str 字符串 + * @param prefix 前缀 + * @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串 + */ + public static String removePrefixIgnoreCase(CharSequence str, CharSequence prefix) { + if (isEmpty(str) || isEmpty(prefix)) { + return StringPool.EMPTY; + } + + final String str2 = str.toString(); + if (str2.toLowerCase().startsWith(prefix.toString().toLowerCase())) { + return subSuf(str2, prefix.length());// 截取后半段 + } + return str2; + } + + /** + * 去掉指定后缀 + * + * @param str 字符串 + * @param suffix 后缀 + * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串 + */ + public static String removeSuffix(CharSequence str, CharSequence suffix) { + if (isEmpty(str) || isEmpty(suffix)) { + return StringPool.EMPTY; + } + + final String str2 = str.toString(); + if (str2.endsWith(suffix.toString())) { + return subPre(str2, str2.length() - suffix.length());// 截取前半段 + } + return str2; + } + + /** + * 去掉指定后缀,并小写首字母 + * + * @param str 字符串 + * @param suffix 后缀 + * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串 + */ + public static String removeSufAndLowerFirst(CharSequence str, CharSequence suffix) { + return lowerFirst(removeSuffix(str, suffix)); + } + + /** + * 忽略大小写去掉指定后缀 + * + * @param str 字符串 + * @param suffix 后缀 + * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串 + */ + public static String removeSuffixIgnoreCase(CharSequence str, CharSequence suffix) { + if (isEmpty(str) || isEmpty(suffix)) { + return StringPool.EMPTY; + } + + final String str2 = str.toString(); + if (str2.toLowerCase().endsWith(suffix.toString().toLowerCase())) { + return subPre(str2, str2.length() - suffix.length()); + } + return str2; + } + + /** + * 首字母变小写 + * @param str 字符串 + * @return {String} + */ + public static String lowerFirst(String str) { + char firstChar = str.charAt(0); + if (firstChar >= 'A' && firstChar <= 'Z') { + char[] arr = str.toCharArray(); + arr[0] += ('a' - 'A'); + return new String(arr); + } + return str; + } + + /** + * 首字母变大写 + * @param str 字符串 + * @return {String} + */ + public static String upperFirst(String str) { + char firstChar = str.charAt(0); + if (firstChar >= 'a' && firstChar <= 'z') { + char[] arr = str.toCharArray(); + arr[0] -= ('a' - 'A'); + return new String(arr); + } + return str; + } + + /** + * 切割指定位置之前部分的字符串 + * + * @param string 字符串 + * @param toIndex 切割到的位置(不包括) + * @return 切割后的剩余的前半部分字符串 + */ + public static String subPre(CharSequence string, int toIndex) { + return sub(string, 0, toIndex); + } + + /** + * 切割指定位置之后部分的字符串 + * + * @param string 字符串 + * @param fromIndex 切割开始的位置(包括) + * @return 切割后后剩余的后半部分字符串 + */ + public static String subSuf(CharSequence string, int fromIndex) { + if (isEmpty(string)) { + return null; + } + return sub(string, fromIndex, string.length()); + } + + /** + * 指定范围内查找指定字符 + * + * @param str 字符串 + * @param searchChar 被查找的字符 + * @return 位置 + */ + public static int indexOf(final CharSequence str, char searchChar) { + return indexOf(str, searchChar, 0); + } + + /** + * 指定范围内查找指定字符 + * + * @param str 字符串 + * @param searchChar 被查找的字符 + * @param start 起始位置,如果小于0,从0开始查找 + * @return 位置 + */ + public static int indexOf(final CharSequence str, char searchChar, int start) { + if (str instanceof String) { + return ((String) str).indexOf(searchChar, start); + } else { + return indexOf(str, searchChar, start, -1); + } + } + + /** + * 指定范围内查找指定字符 + * + * @param str 字符串 + * @param searchChar 被查找的字符 + * @param start 起始位置,如果小于0,从0开始查找 + * @param end 终止位置,如果超过str.length()则默认查找到字符串末尾 + * @return 位置 + */ + public static int indexOf(final CharSequence str, char searchChar, int start, int end) { + final int len = str.length(); + if (start < 0 || start > len) { + start = 0; + } + if (end > len || end < 0) { + end = len; + } + for (int i = start; i < end; i++) { + if (str.charAt(i) == searchChar) { + return i; + } + } + return -1; + } + + /** + * 指定范围内查找字符串,忽略大小写
+ * + *
+     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+     * 
+ * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @return 位置 + * @since 3.2.1 + */ + public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) { + return indexOfIgnoreCase(str, searchStr, 0); + } + + /** + * 指定范围内查找字符串 + * + *
+     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+     * 
+ * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @param fromIndex 起始位置 + * @return 位置 + * @since 3.2.1 + */ + public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) { + return indexOf(str, searchStr, fromIndex, true); + } + + /** + * 指定范围内反向查找字符串 + * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @param fromIndex 起始位置 + * @param ignoreCase 是否忽略大小写 + * @return 位置 + * @since 3.2.1 + */ + public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) { + if (str == null || searchStr == null) { + return INDEX_NOT_FOUND; + } + if (fromIndex < 0) { + fromIndex = 0; + } + + final int endLimit = str.length() - searchStr.length() + 1; + if (fromIndex > endLimit) { + return INDEX_NOT_FOUND; + } + if (searchStr.length() == 0) { + return fromIndex; + } + + if (false == ignoreCase) { + // 不忽略大小写调用JDK方法 + return str.toString().indexOf(searchStr.toString(), fromIndex); + } + + for (int i = fromIndex; i < endLimit; i++) { + if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + * 指定范围内查找字符串,忽略大小写
+ * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @return 位置 + * @since 3.2.1 + */ + public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) { + return lastIndexOfIgnoreCase(str, searchStr, str.length()); + } + + /** + * 指定范围内查找字符串,忽略大小写
+ * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @param fromIndex 起始位置,从后往前计数 + * @return 位置 + * @since 3.2.1 + */ + public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) { + return lastIndexOf(str, searchStr, fromIndex, true); + } + + /** + * 指定范围内查找字符串
+ * + * @param str 字符串 + * @param searchStr 需要查找位置的字符串 + * @param fromIndex 起始位置,从后往前计数 + * @param ignoreCase 是否忽略大小写 + * @return 位置 + * @since 3.2.1 + */ + public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase) { + if (str == null || searchStr == null) { + return INDEX_NOT_FOUND; + } + if (fromIndex < 0) { + fromIndex = 0; + } + fromIndex = Math.min(fromIndex, str.length()); + + if (searchStr.length() == 0) { + return fromIndex; + } + + if (false == ignoreCase) { + // 不忽略大小写调用JDK方法 + return str.toString().lastIndexOf(searchStr.toString(), fromIndex); + } + + for (int i = fromIndex; i > 0; i--) { + if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + /** + * 返回字符串 searchStr 在字符串 str 中第 ordinal 次出现的位置。
+ * 如果 str=null 或 searchStr=null 或 ordinal<=0 则返回-1
+ * 此方法来自:Apache-Commons-Lang + *

+ * 栗子(*代表任意字符): + * + *

+     * StringUtil.ordinalIndexOf(null, *, *)          = -1
+     * StringUtil.ordinalIndexOf(*, null, *)          = -1
+     * StringUtil.ordinalIndexOf("", "", *)           = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "a", 1)  = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "a", 2)  = 1
+     * StringUtil.ordinalIndexOf("aabaabaa", "b", 1)  = 2
+     * StringUtil.ordinalIndexOf("aabaabaa", "b", 2)  = 5
+     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+     * StringUtil.ordinalIndexOf("aabaabaa", "", 1)   = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "", 2)   = 0
+     * 
+ * + * @param str 被检查的字符串,可以为null + * @param searchStr 被查找的字符串,可以为null + * @param ordinal 第几次出现的位置 + * @return 查找到的位置 + * @since 3.2.3 + */ + public static int ordinalIndexOf(String str, String searchStr, int ordinal) { + if (str == null || searchStr == null || ordinal <= 0) { + return INDEX_NOT_FOUND; + } + if (searchStr.length() == 0) { + return 0; + } + int found = 0; + int index = INDEX_NOT_FOUND; + do { + index = str.indexOf(searchStr, index + 1); + if (index < 0) { + return index; + } + found++; + } while (found < ordinal); + return index; + } + + /** + * 截取两个字符串的不同部分(长度一致),判断截取的子串是否相同
+ * 任意一个字符串为null返回false + * + * @param str1 第一个字符串 + * @param start1 第一个字符串开始的位置 + * @param str2 第二个字符串 + * @param start2 第二个字符串开始的位置 + * @param length 截取长度 + * @param ignoreCase 是否忽略大小写 + * @return 子串是否相同 + * @since 3.2.1 + */ + public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase) { + if (null == str1 || null == str2) { + return false; + } + + return str1.toString().regionMatches(ignoreCase, start1, str2.toString(), start2, length); + } + + /** + * 比较两个字符串(大小写敏感)。 + * + *
+     * equalsIgnoreCase(null, null)   = true
+     * equalsIgnoreCase(null, "abc")  = false
+     * equalsIgnoreCase("abc", null)  = false
+     * equalsIgnoreCase("abc", "abc") = true
+     * equalsIgnoreCase("abc", "ABC") = true
+     * 
+ * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @return 如果两个字符串相同,或者都是null,则返回true + */ + public static boolean equals(CharSequence str1, CharSequence str2) { + return equals(str1, str2, false); + } + + /** + * 比较两个字符串(大小写不敏感)。 + * + *
+     * equalsIgnoreCase(null, null)   = true
+     * equalsIgnoreCase(null, "abc")  = false
+     * equalsIgnoreCase("abc", null)  = false
+     * equalsIgnoreCase("abc", "abc") = true
+     * equalsIgnoreCase("abc", "ABC") = true
+     * 
+ * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @return 如果两个字符串相同,或者都是null,则返回true + */ + public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) { + return equals(str1, str2, true); + } + + /** + * 比较两个字符串是否相等。 + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param ignoreCase 是否忽略大小写 + * @return 如果两个字符串相同,或者都是null,则返回true + * @since 3.2.0 + */ + public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) { + if (null == str1) { + // 只有两个都为null才判断相等 + return str2 == null; + } + if (null == str2) { + // 字符串2空,字符串1非空,直接false + return false; + } + + if (ignoreCase) { + return str1.toString().equalsIgnoreCase(str2.toString()); + } else { + return str1.equals(str2); + } + } + + /** + * 创建StringBuilder对象 + * + * @return StringBuilder对象 + */ + public static StringBuilder builder() { + return new StringBuilder(); + } + + /** + * 创建StringBuilder对象 + * + * @param capacity 初始大小 + * @return StringBuilder对象 + */ + public static StringBuilder builder(int capacity) { + return new StringBuilder(capacity); + } + + /** + * 创建StringBuilder对象 + * + * @param strs 初始字符串列表 + * @return StringBuilder对象 + */ + public static StringBuilder builder(CharSequence... strs) { + final StringBuilder sb = new StringBuilder(); + for (CharSequence str : strs) { + sb.append(str); + } + return sb; + } + + /** + * 创建StringBuilder对象 + * + * @param strs 初始字符串列表 + * @return StringBuilder对象 + */ + public static StringBuilder appendBuilder(StringBuilder sb, CharSequence... strs) { + for (CharSequence str : strs) { + sb.append(str); + } + return sb; + } + + /** + * 获得StringReader + * + * @param str 字符串 + * @return StringReader + */ + public static StringReader getReader(CharSequence str) { + if (null == str) { + return null; + } + return new StringReader(str.toString()); + } + + /** + * 获得StringWriter + * + * @return StringWriter + */ + public static StringWriter getWriter() { + return new StringWriter(); + } + + /** + * 统计指定内容中包含指定字符串的数量
+ * 参数为 {@code null} 或者 "" 返回 {@code 0}. + * + *
+     * StringUtil.count(null, *)       = 0
+     * StringUtil.count("", *)         = 0
+     * StringUtil.count("abba", null)  = 0
+     * StringUtil.count("abba", "")    = 0
+     * StringUtil.count("abba", "a")   = 2
+     * StringUtil.count("abba", "ab")  = 1
+     * StringUtil.count("abba", "xxx") = 0
+     * 
+ * + * @param content 被查找的字符串 + * @param strForSearch 需要查找的字符串 + * @return 查找到的个数 + */ + public static int count(CharSequence content, CharSequence strForSearch) { + if (Func.hasEmpty(content, strForSearch) || strForSearch.length() > content.length()) { + return 0; + } + + int count = 0; + int idx = 0; + final String content2 = content.toString(); + final String strForSearch2 = strForSearch.toString(); + while ((idx = content2.indexOf(strForSearch2, idx)) > -1) { + count++; + idx += strForSearch.length(); + } + return count; + } + + /** + * 统计指定内容中包含指定字符的数量 + * + * @param content 内容 + * @param charForSearch 被统计的字符 + * @return 包含数量 + */ + public static int count(CharSequence content, char charForSearch) { + int count = 0; + if (isEmpty(content)) { + return 0; + } + int contentLength = content.length(); + for (int i = 0; i < contentLength; i++) { + if (charForSearch == content.charAt(i)) { + count++; + } + } + return count; + } + + +} + diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SuffixFileFilter.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SuffixFileFilter.java new file mode 100644 index 0000000..a8d4387 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/SuffixFileFilter.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.util.Assert; + +import java.io.File; +import java.io.FileFilter; +import java.io.Serializable; + +/** + * 文件后缀过滤器 + */ +public class SuffixFileFilter implements FileFilter, Serializable { + + private static final long serialVersionUID = -3389157631240246157L; + + private final String[] suffixes; + + public SuffixFileFilter(final String suffix) { + Assert.notNull(suffix, "The suffix must not be null"); + this.suffixes = new String[] {suffix}; + } + + public SuffixFileFilter(final String[] suffixes) { + Assert.notNull(suffixes, "The suffix must not be null"); + this.suffixes = new String[suffixes.length]; + System.arraycopy(suffixes, 0, this.suffixes, 0, suffixes.length); + } + + @Override + public boolean accept(File pathname) { + final String name = pathname.getName(); + for (final String suffix : this.suffixes) { + if (checkEndsWith(name, suffix)) { + return true; + } + } + return false; + } + + public boolean checkEndsWith(final String str, final String end) { + final int endLen = end.length(); + return str.regionMatches(true, str.length() - endLen, end, 0, endLen); + } +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/URLUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/URLUtil.java new file mode 100644 index 0000000..a46dec5 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/URLUtil.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; + +/** + * url处理工具类 + */ +public class URLUtil extends org.springframework.web.util.UriUtils { + + /** + * url 编码,同js decodeURIComponent + * + * @param source url + * @param charset 字符集 + * @return 编码后的url + */ + public static String encodeURL(String source, Charset charset) { + return URLUtil.encode(source, charset.name()); + } + + /** + * url 解码 + * + * @param source url + * @param charset 字符集 + * @return 解码url + */ + public static String decodeURL(String source, Charset charset) { + return URLUtil.decode(source, charset.name()); + } + + /** + * 获取url路径 + * @param uriStr + * @return + */ + public static String getPath(String uriStr) { + URI uri; + + try { + uri = new URI(uriStr); + } catch (URISyntaxException var3) { + throw new RuntimeException(var3); + } + + return uri.getPath(); + } + +} diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/WebUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/WebUtil.java new file mode 100644 index 0000000..62a8181 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/WebUtil.java @@ -0,0 +1,270 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tool.jackson.JsonUtil; +import org.springframework.http.MediaType; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.method.HandlerMethod; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; + + +/** + * Miscellaneous utilities for web applications. + * + * @author L.cm + */ +@Slf4j +public class WebUtil extends org.springframework.web.util.WebUtils { + + public static final String USER_AGENT_HEADER = "user-agent"; + + /** + * 判断是否ajax请求 + * spring ajax 返回含有 ResponseBody 或者 RestController注解 + * + * @param handlerMethod HandlerMethod + * @return 是否ajax请求 + */ + public static boolean isBody(HandlerMethod handlerMethod) { + ResponseBody responseBody = ClassUtil.getAnnotation(handlerMethod, ResponseBody.class); + return responseBody != null; + } + + /** + * 读取cookie + * + * @param name cookie name + * @return cookie value + */ + @Nullable + public static String getCookieVal(String name) { + HttpServletRequest request = WebUtil.getRequest(); + Assert.notNull(request, "request from RequestContextHolder is null"); + return getCookieVal(request, name); + } + + /** + * 读取cookie + * + * @param request HttpServletRequest + * @param name cookie name + * @return cookie value + */ + @Nullable + public static String getCookieVal(HttpServletRequest request, String name) { + Cookie cookie = getCookie(request, name); + return cookie != null ? cookie.getValue() : null; + } + + /** + * 清除 某个指定的cookie + * + * @param response HttpServletResponse + * @param key cookie key + */ + public static void removeCookie(HttpServletResponse response, String key) { + setCookie(response, key, null, 0); + } + + /** + * 设置cookie + * + * @param response HttpServletResponse + * @param name cookie name + * @param value cookie value + * @param maxAgeInSeconds maxage + */ + public static void setCookie(HttpServletResponse response, String name, @Nullable String value, int maxAgeInSeconds) { + Cookie cookie = new Cookie(name, value); + cookie.setPath("/"); + cookie.setMaxAge(maxAgeInSeconds); + cookie.setHttpOnly(true); + response.addCookie(cookie); + } + + /** + * 获取 HttpServletRequest + * + * @return {HttpServletRequest} + */ + public static HttpServletRequest getRequest() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + return (requestAttributes == null) ? null : ((ServletRequestAttributes) requestAttributes).getRequest(); + } + + /** + * 返回json + * + * @param response HttpServletResponse + * @param result 结果对象 + */ + public static void renderJson(HttpServletResponse response, Object result) { + renderJson(response, result, MediaType.APPLICATION_JSON_UTF8_VALUE); + } + + /** + * 返回json + * + * @param response HttpServletResponse + * @param result 结果对象 + * @param contentType contentType + */ + public static void renderJson(HttpServletResponse response, Object result, String contentType) { + response.setCharacterEncoding("UTF-8"); + response.setContentType(contentType); + try (PrintWriter out = response.getWriter()) { + out.append(JsonUtil.toJson(result)); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + + /** + * 获取ip + * + * @return {String} + */ + public static String getIP() { + return getIP(WebUtil.getRequest()); + } + + /** + * 获取ip + * + * @param request HttpServletRequest + * @return {String} + */ + @Nullable + public static String getIP(HttpServletRequest request) { + Assert.notNull(request, "HttpServletRequest is null"); + String ip = request.getHeader("X-Requested-For"); + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return StringUtil.isBlank(ip) ? null : ip.split(",")[0]; + } + + + /*** + * 获取 request 中 json 字符串的内容 + * + * @param request + * @throws IOException + */ + public static String getRequestParamString(HttpServletRequest request) { + try { + return getRequestStr(request); + } catch (Exception ex) { + return StringPool.EMPTY; + } + } + + /** + * 获取 request 请求内容 + * + * @param request + * @return + * @throws IOException + */ + public static String getRequestStr(HttpServletRequest request) throws IOException { + String queryString = request.getQueryString(); + if (StringUtil.isNotBlank(queryString)) { + return new String(queryString.getBytes(Charsets.ISO_8859_1), Charsets.UTF_8).replaceAll("&", "&").replaceAll("%22", "\""); + } + return getRequestStr(request, getRequestBytes(request)); + } + + /** + * 获取 request 请求的 byte[] 数组 + * + * @param request + * @return + * @throws IOException + */ + public static byte[] getRequestBytes(HttpServletRequest request) throws IOException { + int contentLength = request.getContentLength(); + if (contentLength < 0) { + return null; + } + byte buffer[] = new byte[contentLength]; + for (int i = 0; i < contentLength; ) { + + int readlen = request.getInputStream().read(buffer, i, contentLength - i); + if (readlen == -1) { + break; + } + i += readlen; + } + return buffer; + } + + /** + * 获取 request 请求内容 + * @param request + * @param buffer + * @return + * @throws IOException + */ + public static String getRequestStr(HttpServletRequest request, byte buffer[]) throws IOException { + String charEncoding = request.getCharacterEncoding(); + if (charEncoding == null) { + charEncoding = StringPool.UTF_8; + } + String str = new String(buffer, charEncoding).trim(); + if (StringUtil.isBlank(str)) { + StringBuilder sb = new StringBuilder(); + Enumeration parameterNames = request.getParameterNames(); + while (parameterNames.hasMoreElements()) { + String key = parameterNames.nextElement(); + String value = request.getParameter(key); + StringUtil.appendBuilder(sb, key, "=", value, "&"); + } + str = StringUtil.removeSuffix(sb.toString(), "&"); + } + return str.replaceAll("&", "&"); + } + + +} + diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/utils/XmlUtil.java b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/XmlUtil.java new file mode 100644 index 0000000..0e9e9e5 --- /dev/null +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/utils/XmlUtil.java @@ -0,0 +1,267 @@ +/** + * Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springblade.core.tool.utils; + +import org.springframework.lang.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +/** + * xpath解析xml + * + *

+ *     文档地址:
+ *     http://www.w3school.com.cn/xpath/index.asp
+ * 
+ * + * @author L.cm + */ +public class XmlUtil { + private final XPath path; + private final Document doc; + + private XmlUtil(InputSource inputSource) throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory dbf = getDocumentBuilderFactory(); + DocumentBuilder db = dbf.newDocumentBuilder(); + doc = db.parse(inputSource); + path = getXPathFactory().newXPath(); + } + + private static XmlUtil create(InputSource inputSource) { + try { + return new XmlUtil(inputSource); + } catch (ParserConfigurationException | SAXException | IOException e) { + throw Exceptions.unchecked(e); + } + } + + public static XmlUtil of(InputStream is) { + InputSource inputSource = new InputSource(is); + return create(inputSource); + } + + public static XmlUtil of(String xmlStr) { + StringReader sr = new StringReader(xmlStr.trim()); + InputSource inputSource = new InputSource(sr); + XmlUtil xmlUtil = create(inputSource); + IOUtil.closeQuietly(sr); + return xmlUtil; + } + + private Object evalXPath(String expression, @Nullable Object item, QName returnType) { + item = null == item ? doc : item; + try { + return path.evaluate(expression, item, returnType); + } catch (XPathExpressionException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 获取String + * + * @param expression 路径 + * @return String + */ + public String getString(String expression) { + return (String) evalXPath(expression, null, XPathConstants.STRING); + } + + /** + * 获取Boolean + * + * @param expression 路径 + * @return String + */ + public Boolean getBoolean(String expression) { + return (Boolean) evalXPath(expression, null, XPathConstants.BOOLEAN); + } + + /** + * 获取Number + * + * @param expression 路径 + * @return {Number} + */ + public Number getNumber(String expression) { + return (Number) evalXPath(expression, null, XPathConstants.NUMBER); + } + + /** + * 获取某个节点 + * + * @param expression 路径 + * @return {Node} + */ + public Node getNode(String expression) { + return (Node) evalXPath(expression, null, XPathConstants.NODE); + } + + /** + * 获取子节点 + * + * @param expression 路径 + * @return NodeList + */ + public NodeList getNodeList(String expression) { + return (NodeList) evalXPath(expression, null, XPathConstants.NODESET); + } + + + /** + * 获取String + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return String + */ + public String getString(Object node, String expression) { + return (String) evalXPath(expression, node, XPathConstants.STRING); + } + + /** + * 获取 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return String + */ + public Boolean getBoolean(Object node, String expression) { + return (Boolean) evalXPath(expression, node, XPathConstants.BOOLEAN); + } + + /** + * 获取 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return {Number} + */ + public Number getNumber(Object node, String expression) { + return (Number) evalXPath(expression, node, XPathConstants.NUMBER); + } + + /** + * 获取某个节点 + * + * @param node 节点 + * @param expression 路径 + * @return {Node} + */ + public Node getNode(Object node, String expression) { + return (Node) evalXPath(expression, node, XPathConstants.NODE); + } + + /** + * 获取子节点 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return NodeList + */ + public NodeList getNodeList(Object node, String expression) { + return (NodeList) evalXPath(expression, node, XPathConstants.NODESET); + } + + /** + * 针对没有嵌套节点的简单处理 + * + * @return map集合 + */ + public Map toMap() { + Element root = doc.getDocumentElement(); + Map params = new HashMap(); + + // 将节点封装成map形式 + NodeList list = root.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + Node node = list.item(i); + if (node instanceof Element) { + params.put(node.getNodeName(), node.getTextContent()); + } + } + return params; + } + + private static volatile boolean preventedXXE = false; + + private static DocumentBuilderFactory getDocumentBuilderFactory() throws ParserConfigurationException { + DocumentBuilderFactory dbf = XmlUtil.XmlHelperHolder.documentBuilderFactory; + if (!preventedXXE) { + preventXXE(dbf); + } + return dbf; + } + + // https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5 + private static void preventXXE(DocumentBuilderFactory dbf) throws ParserConfigurationException { + // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented + // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl + dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + + // If you can't completely disable DTDs, then at least do the following: + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities + + // JDK7+ - http://xml.org/sax/features/external-general-entities + dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); + + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities + + // JDK7+ - http://xml.org/sax/features/external-parameter-entities + dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + + // Disable external DTDs as well + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + + // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" + dbf.setXIncludeAware(false); + dbf.setExpandEntityReferences(false); + preventedXXE = true; + } + + private static XPathFactory getXPathFactory() { + return XmlUtil.XmlHelperHolder.xPathFactory; + } + + /** + * 内部类单例 + */ + private static class XmlHelperHolder { + private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + private static XPathFactory xPathFactory = XPathFactory.newInstance(); + } + +} diff --git a/blade-core-tool/src/main/resources/META-INF/spring-devtools.properties b/blade-core-tool/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..b252d0a --- /dev/null +++ b/blade-core-tool/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.blade-core-tool=/blade-core-tool[\\w-]+\.jar diff --git a/blade-core-tool/src/main/resources/META-INF/spring.factories b/blade-core-tool/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..e9d7490 --- /dev/null +++ b/blade-core-tool/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springblade.core.tool.config.ToolConfiguration,\ + org.springblade.core.tool.config.JacksonConfiguration,\ + org.springblade.core.tool.config.MessageConfiguration diff --git a/pic/jx.png b/pic/jx.png new file mode 100644 index 0000000000000000000000000000000000000000..4557523e79ee5e9a4816cd42d14282c7378c0456 GIT binary patch literal 73163 zcmbrkWl$Z>8$F1-ySqbhy-09(cXxLU1PJa9!R_Mi9vp&STrO@G=S2eqvi$zLTeaW! z!_;*3boJ9c-7|fjb55+fsvJ5B2?`Vx6uN@Ev?df3EaZO|66|M9U@+b4=MCCRQ%(}9 zVUFzVvz)1}tS$5J-#;uYEJQ@ak9pXC|K7Q~@7_N?K3lSs$^N^kzPr1Fg@ygX#`gF9 z?cXTQ#}tB~py12P3l$X=F%hwnk`jBd+|||9$946`IKsy&t+=@O#{lus(NRlF3unje z*x2a%roi&@GJEsI$1>i>BBH;)e?-I&J3G7IzkmO`EMu-Z(9zNP_wS*&xQIG;rN6)b z@#!%$Bjf$wzmFD%-QC^y9rfJY+}hgOgoOCFe(3v;f6vc<{{21e?Cd0r8YE7f7VLXG zJ3D(nu>1G2w!Xgpaq!*L)a2pcpOe@3kJHTePLzKSV{UG4AGhsq^@Jkr=awBljEs!3 zl}5{V9|MrT%KbOOx$1Azf>u^muLB(0+uI+#)WGdOEM?Li2ZQtT^Y4RbZ`10Pl@;JW z2XQM;PE&WUK$7=GyT3DJ++|83At4q67h79fr7P|KUABNgAjtcbPRDNS)Wu6TQO+VT zdMaz;av^XaZtbYos$rO|Og4CEWp;M;Gn(~>4r63u}7!rfn@C+E53P_G5 zcd}LWk~fu$1;xb2F;peIU!OiK?uvfxbU<$fZS3%GeJkic2}pY&6HDlC=wCGrs=r{t z>+(1pPb3v^1^@pnG*O43c6kJOx0ciVLI!tj8+gllr*6IrThBZ%xw`#I_cuNrzoMu& z%T!&Dlt?Jg9+GTi!Vlgqcn-jrPuvQYd9-Y|^Cg9C?QFGdicj#Uq!Y8i)r+qlwU|rX z65a1}$&yjw$RXe znLQl83UO~JfN8Je^>f!CM<+dI{FTXo@GIzZaIyF*W|B#%JDGdI-)?=L#7x}odnXdN z3iSE#sv>>J!9hl4i&_hK>ARw?;Oo)A67esrq?~>?n8V^`i7yNVq@8c;C4|cK5xd-d z&kc={x2U8#rhcFEW3SsaiM(a?HZ37k>d_4`wSO7OSmtNe$$VQ{ZdreM)K?X zXIx2hmVKvVW72_?x zQO=OavA_IbbC+^nhrWpFdWjuEuByuSI)GnRGBmH|G*I8@i_7+sDR^E$pAp37fSb~O zQHq&!dnoIY|9jG-uoOA*aZ6Wc$cI`GTSkfqcqrQ_Y5XA`#)jjGaB^f7jS#LWHqU)=lHpe{ZWo_TBUp5S8IAAdo?*C=3$4PPfN zk?_UVxpS)S;9{i;iVsktW7zYodyx6og+*JzG{pN&ypey{OTaV!^!l@XTt5nErzP0C z7<0s6CLJ7b9DN49UaG>;s8$+Ov7g1ZDrP)k&Ooq}5hycY5Yyb<#aO`ZmieCc zNI@8QiMtLHxc`PobR>6PNs z1^G{RWkezi>G#Os^CVaL(r9>wQf`dT%{Nr%ks=^^?*BKFO+}P>iN>o~`0bDsst4W; z)IH+ftA^?}U}FPyUOW@J)YRHhComuv9ft#iUh_Eitz5-;?uf&0MWQ0d(ez)u2!JBr zhFOSxJNU-Y*zMJ;CUvya%L~P-O0_V*UM^MLD}WFPTP^HvR#@1Dhu0az7YmLO&cPnaY)LJ<~Cu(*d>^zX`OO z`TA08-o8=8^xZ3CuKnQ;-8xpjaxg!VjNl; zR6Uo*;IT|B8K0LyZyRjYF&o6Q3iun5bwbfT^X z(+9E@KhHvn0(TJgq8n|4^fUeCPkjxvCah~2MH+DMPg-6tuVBb!7&+{I^6`?^s{)rC zolo-9;vE3Eg8H4|9cz`uAhzddT+o`}&vRG<;9OjQT^M|LX^IP7^PWvR|~* z7$~*`nll6PT4|6}2A@soOIyXvZ{4rov`cudyfVCc&84FO%a`C_gf43LE;ijjgAtqz zO4y(%R;Yr2>CjfWK$pxB7$R_&3C5Xtw4wAdGPvBW<&{+%d_Q@B-NUkAAOPJ%3DEyt z0{Tj^*ln_qpl}x3Fge}*5nf;E{ARQQvNHS@VnG--RTNfw}%z1V9*VESoOHKyf6s_QiEOa0tu#`7336f z4LH7rW%8qhjXmbk+RQXcfUM`FpAA0eJkNRc)>W$)BW$O9N!_f6DG(AZEIX9_SUu)> z7In?$mHZ1Po{D(dQLfhTf&&QI2S(AewGQ%$ZY?)!Gg@tusy1!TN$vbu;8$PJKK{Tfo_;&h0cb zANh1bKA-Eh!&c0~#!4G& z+sW*=N$j=Iuc}c}3LE(A)XfN=<#1-Qt%77QK2LO7R^Q7oLjRk;_^Iz%j45xJ7f&&F z)WrlhcHYcKdsx!R5K8X)Z*Vh<4}LK_vCm;j?qAV8PKj=z!@`NH1O4v^o_^RQLkvpC zC3ydgiz}74P4X2;;UQ~M296#wp63*T4_)e-w6fyKT{S!rYO%Fx`&thNb^IIb!u40yhKXCQgq0}Lt7EW$PABKZN+?q2 zZiUr0Iv%p37BxpXSkYsVo>xU@rWU22xWVC^a?&1OK}z9ND3aAJE)!JbmV1`NyuTBT z&i}-j`_XNgr(%mKuC=&=G?pnu+b2tTX_zcp2;1rJ5Mlaj9Q!o@-ztqwxdI9hj%2g;Q)tIN#QYcO40Y)5))llVf{*0yMbo%FDi_u`|DQ}pYd(ef`6tRW|2#N&xo*IBL>AX^zESah@ zZ=Js&eWHja=3^vM$-1ZPIvN1fgJPrq4h`O$fHkvd+EXsLEPk5WkKc8TM?40iV7h!i z#jVjGKEJ~$)f$!R^>VB*N`$`AR_XIX4d`Sw{4+WECCR1y@4$buVTDM3(!b;oH*Xog zVHIrgp)V46Z<)J^lo~0ACD}t!t`;X2TH6TfPb8A!!rBb2`8?*+J;Pv=%RrMi>nH4e zMe_QEs+6OK+Dw-D343DYlt^317+JSNTz3PPs)OpP`$IEwiCRY_=w8qTT-V?LH5}Hf z-yE8Ek)aCI?SN2#@{nAf1(5ThR8JN9!PB;8V>M54>)}(?V6T5N-KehOQ%y5ZXj+(H zMd|<3mb^SDxW%)ZJFdQwI;J@5XR`ZY)~Xwo<*3(BY^!(}@$bR<)KM^yL8aTkR8}l3 z?oC`1EycJBfglBoO<;cZ95DZs>U4bE=ln=yBYpihhoG$#*O-!c0rAPjveImRf>UEF zbA+qp6dUtGJ(8+E=_fgMWa@Bc@YdS%6`LHs1ZdfK<2aLq5Eo z5TM(H*^rZ4p49mINXHM6N)eK!Sxlr~zz+4mTBe(8@a@ zY%KcqWu{P7$G#H-y)J02+N(`l&ibo>n^}_|edaIYNi! zR8+s+)3I@NDih-l$qPX75w1^wZu)(&pDZgw0jPz)3jL`HH%kAXx+ThtP`la$OgzeM zr8P=s8kh4LdfE38j8Y6n!wnZ_od2P5iI7fpwI!di&A34%Bh|}Mqy=L7w_7F}z*yyi z#H2lDN203J7H`p8Ckexfi57M+Z@O0D!0r_W8(1z_p}h7Ae$cSzn`}3fsImgG_v(`S zIQ@4N@(6^2OxoY-t6BY9Xy-_W;9oeX@q|e^!tL(IMs+!a%V)VR(D)tThT?S$G>)O!;IWRB+U-8t zDyUL{B#+QzdMMB91_T7!-;=IPT9wf^b&3Cyy;IDF{#lvccq+gS*)H;13zVsb#1F9= zOl`DJdgiB?xaFUhs+W5!H6N3lBe=m)$D0_Sp&&flA1BE6aCyTTU1iDbS&hzw$t50-Z%axHRJ z^ToMoAQjUze=9eGh|%OT#Lp24PtzYqm@l4qE;xbB(uPN>q+*`Gn&yG7!7uWgN75V& z0Kh6E3&-4Anu&e}GUi;06peoiu;Qd|a7eyiSsGEkEkbvXm!dK1-LAFU#E)c4VoRNN72n$X z{Wz$*&zkp*P`@a>y|`<;PeKwUX`(5%+Tw#j;wCap!>2D0#z{<|CDj7+foXPW;m6sR z_7<@0n3RQd6n8K~XcRtHI_TK5R*NmjDS(leE*ff0P6A(GDM zl!OrVY^)*sWaQ1`!!SFZ(%9HPOtL=8$byff)05>>(QDT$%lzf$Gc^YBmlM?wl7%pf zYE5GM(>?6XV$km6;hn!p_#~(i2rUMqQz^%+P145k7Z|g=lJ4HVOc28|1=#Tz!5ke& zr-b}<_o;~|B(YH1alne7i|a0jgXw@+tOz~y;W2sI?v?4gUsG3^ahVE+Z;?klY!fK% z*whD!?W1AU%jjACc>viXVfCSAUv_;Z{>>ucu9g4&m($TO!E&lh4vJAlRd{vdsBR!1 z_ncWQg8IQn8;SeS_?s+XFTiv=!RO0dS&BkPYLyxAQVSf>LK=jB+6hAFyEf)6eZi^g@){Z!-Yv8GPAnl$$a+fXOI7@)zn^mdK9ZF)ooyFu zJG3M#LOKsfkf=nXmQ@zlBDogj%Y^}jx%-ZDAp}*a3Z8nrhk(Q)dUW+K)u@Z7ElTy8 z_Cxpv6t5}vw0}psA$HMQBsuNT!CkXa(K#UV2@&|jN%`P;6z}#vs+fct&ds|fUr2yT z$XKdt+oxuEEvkDfPRPyUj}T{lvJ2A^%Q{?C+fCQP@MkbeJdWN{UEQVik?S`m>a z*u=MIV0)0!{1eI=H-b$3v6Hp9aX*GcAvT%pT(kvDf2I%`8#GVG$aa@<5Mr4LTXjU( zn&r7$b5x~s9Xujg2$pkREHfac_bNduWs84OE&ClVH%Rjg8SZiMh!GJN^gEiW+;<7I zwFzJM#9oK2L`(MU$R_($mJHJ_1QR;yB^(-LJ(bxgHL@8R3BwBs!_dr(FFC|E!tZ2-u|V+lbUC`Hzu)dl$1YotBja=qf0iAl zrafaR>GRvb+?APmyIV5|Mms_i*ViSKM+>*XuZm_*h#7l(ub}IR`AB(}IF}PW{Q!J5 z2x4Qkw1IgMv4L5PGM58V)X@;C6q~W7a{b5sTV$)fq5@l-awrxRXv$@oid_K0pM!GFKE;D?^b?q7cFXVC2@V zfp6}rQNw;eehc23{DJN?x*JI!7<$<`4GwpNq2;;O?%{}0X62sj4Y&OI_CW(E9*>{^ zV|Hybt?P`>6QGw*(7Io~yV{zATO;5--B1*sF&V0eSDMUawY;!_Q$#SNXbF zy_~&z@ypeOZ7_>04R%BKA~H-OIm@*5O~jY06_OUny9Ez&PJOc(9y#$1|@z8zSw!P$>dDb1#mi%m|Rk zHDh+vf2BwU-GJ6=pvX7qtsvv0-_LQiZeBEll(ni>ruLQ1AXVAfTpn{8GmY++xm*u3 zv9)z=)8BH{6m9PY_{nIlWyB3!&%IfXqV{L|i1b;1dmNbdul||tape>B=S4_B_B!5D zbQ3B6DaG!r0J)WPk-6LJ(XwkCcLenF@Le^H|kRFQl$t2(@LS>ACyi zBo7XnS9I-LU5^(Ss_h@_$EW2=xvY zvklo#>)zoEOv=BOl9Q#7o!lFz`Wa7vNw)2)UNYJ-Q!nV|x`-hp0(tPxv zR`NI?uFQ8fwba%n3YDOBDji)zy+^RB_(HyUGjWuAx@Cp-;$0axXE!AQ^NSPm%$z##<4kgw$_$-3N#DMNAe24t9g=3dBqTwxrx z_O#uhF3|Sf={1^N_yGQ!$B@~s{Ll(s6dZ$Uvzs`tGnL*iiM!eu(s#c-` zzrYRrYn1lJ{z)V1Bz}XH_`~jeA0l1uj8?$%zU{yC7I|0t;Fzmo;)V7sE>xj5<6y$F z1GWSsNCt|xcYf6^Y$+-)g7va(;ddn_BW)H@<;#yb^ zw{{9@@jxppjgybmSVoyTDGFb~lruYdT?IdDgD`Ce92zpY%VUqoR z;ZK%&0da}z5d4^zsSNI1DD{qAB}8vYJKo40wrjq}J!(|NGE=(g6lrNUG>r#zE6e=@ zt4sG^rz*g_$BO69TmD^hPreuCO>1z34Msg0=)gI;HR|nY{aZESamWh)Ak*(+pk9}&WTMAwvik(H!?y*);{35A05^zzkOhm5lP=gV zKmm!g?9EhhBf#GbGhNz?EpdXg*)R+Ul-#j*>E{r2o2@9}Sg$(RRj?p72 zPlt1(!F(gnKr)%HbL8c%xse=mj_Fq|OPi_{I`Ke(*??q|9l=Il!dh?4ai790hf$r) zzX7#UQz`ueB&*7pw*#q+Q*+((XIpWk+}&$TzZu1g*UrLB#ox>3nEJ1LazTclsYq;e z4kUS_O5G*vC}R1mlcx?7$#?_502-@++d)?RtZZ)1$L~Er90e&s^bqv?h`&zOBsUss z=b!n6SO@iN7|RgjFe=yXCVp9|w(17z|blp74FN4PYJTsCP9SkpM^s$D^J2H~T!;#`h~ z-5CZ&W+@6=6BG>sV~Uy`8*&LD`FcdM>aG#3sBjl6`pSj$E=wv_Pw05>65}bXcS?iU z7#hp+z0-{~(YRt4h+Xb;DV4}o+4UaA28qdb^vrI51*RuacnFecNNGS992)l%)aDX=teVmsf7eBT;}aYl^pE;yEdzzhC^i zt3j7FT- zmuW1@+Y%{4+q6{OP9?ABbo3sj00Nxs`(ht;s<0uS{mhVBAmA~bOIK>)1&@^N64aW* z&#qmknjK2&SVsI4=F$)*=D{^ETZ)66$+#_QlHNx)R23HV__Jy*7a9`4*(n7djaQc@ zO=zL~3tjlT<+X}PfSvVfj>rgh<_V|5_QKaH$o&lkjp@eC8P;Otqta^%Md5F{VzSDl zgvrF)0C7K-^*J0^NLT*5bulg6=IS@N_%#vc!*5F#PU&NLD9fLdY`uz!G-LNch;9R% z$R0|_(CovI_hCBod(=)p3B4anmQ{p=<62>TG%Pth3kgQg^{D2-jEb8ia=L#jY)Nel zE!+B{;5YH9TkNT@uH}_B;sGBS zTz_Wm-68wIG_l%WY4>}HM(a9@7Tn=JMs=x=IeXy9=pC&H=QhT;# z*Xk@F?#6PorvhG-ow&tet8ley4llP(jd#a(?3-H-Aje;{tGrA4k9(7!Al}7`Cp!l| zB4Sw-15SU)yjP#Mqm1y?2N7ZpbnS$N4cy_bg?w{kN!wXIqArjTUmO0p=(TA@-A)nG z_lozLupu4xplU|kJ^{aFsr|cZ;My)~bV0!~G%5Ta(poMW?uCW97J-T5FL+zm&+$%*vnoz6s)Kv*f(O}YKas!1H= z(-Gt97WbLgDU#a#UDhENJ%{?9NxRUWG1lgaO$Kr&1{}3j9{>VS7I!RwIHQM(d8^J=ZM=du7Md4 zY9;-IvE36cP|#nHaLeH8aP45<#eHEQD;O%hl29{>-KFKD_OAfS#p{ES%duWE3o89y z(W+ef>4G8Hg37CeVk-i+r(gMqcy7rbSJCGY4IyOrw2u5A?Xp1O3llAw1XznIlrDqF zVn&b`IqCsC%@1_}55Ewt#MNg~vg{)*flR>SsI47ZeRA3N^`?|yPbFp?^{g*;i&z~~ zC+HR@!P1msLm|$$1c_9p3=iC3OPMR}EIFuO#Hy@_X{)8SDNKYRAo>9?~4(r;H6MZM{$~Bk(#cH+;rKz4? z*6<{i7mY4Tu(P%z{o9D*Ye#lJdI6KivFJ*S`?OkY75(_?kV(IQWJHOk(gr&NF!#$9 zG&H%U(Lja(eCLl4HxikLS&blE0Tx<9)ycfLxACcq=ak5pLRmQW)2939qFIpn22lcy z!f2H{V)TPC>W!nC(iSId+MebOh=-VWJ1{oOqlc61LWPN4Xm9)+G)Q`}2mXoH0z+;2 zgWx}VFgwUnBe20xhOdDpJ%3U118shiduCfI=W$v>hL}1&!waAIlA&i1i)dd({Xc@+ z3U}XRlwyJZL;=%su*Z`_tv5`%Ik#oiry-A5Q%gW{fU>?EUxWhMU0|DwkjW_@!63Nb zVcw(gqD*42N*_)E*+kmTfvVGaj`>`P%1{%-Lbvk+q||-6Gng+T;Hl(=YjNn?f0l|4 z5+RY47GDkQ{Len_aGJ0HhMcW!<{|8}DcJF}8_%Rq{wE5g^Frk&_*}JC+5JDcA2dm+ z9RV=gYeO{I?a0Si6^6TxJ3y4FmMlBDkcVd4gPn%~!zvDmOQ=rVR2mriCMf&^s(FDQ zvLI?vv*IoJ@5DZ2mR*WgxyBf`rp02(M!6k^4x6P$ohU-OS(YTRu7i0f0%t0iZY5S0 z{tye*hg_Kcj1JP3AMHDAENs;h0*I15O$En&!}4#N-c8l*wbfORzE_5R%eAv_(ZinX zYn8IfZ!@kVd03eO_)u;KK7?r$@!W63>*ev(OhsaDwRGK$p+@)&A&Q+g~oG&e&%(qA2fZjMP;Xd z?d3zL{K5a-q4T)QtLY`c=KggZDpMa{VKfa(dreQ_(z^eTA#*AZD;biF7$|{45iFZ1 zYysC0@E;CPxYqBtySXIRed6+<3(5+L~)b&di zf!5jkT}5G4V$kBV& zv>oX=FkRt0rXU8Kdk!uvA*j`z%Xy3QK^2z(Ks+p zftAbjdhJz6(Yo;Qr#$dq+JmSp2pG@jQ7lXHVTMj$u49FlJ1UQ&&dWNsProBM3Ak=l zEj-MX+m>&;mKo?h+fKvTYzzPvw~Y!SaayRtrk0m!RCD~kf{PUsIi*ik1`@_jRUlb? zXIw5Mmu%B@v-lLi6prz&Gh?^!osB-T!NFM#-%&QY6@8ADGMG9YbP)kqd5sBb6-+d>mKJC%zio`nw zS2s)f{x-E_OM_oebP+Td^P%+qslzb*Bz+}ffX)CY)^b|GxlnqQa9_yN{Hi>ew~*Mz zu-k|ow`u^_gG9~i#)e~pa$@icsmjcu->EXT{3(dpqbL!@krV~8JcY>LM`fGq9pvpj zAW&lOcHo=zIJ+S27hs?kWK?e$WA!_#JGr=ngi(R6-olO2VfcZ#--T*aS$4MI zT#W4U^hybFAd;+SOi&n*WjQ4K_0U!1X6~$Yf7~lCDNO>m1KCX0$Y-7E*Ac7@8|+Rv zt%v|^K2m%e9d_nTPm!4bKiQNy`Q7tLOA72)s=g79!(sAsYjzXMKC8a!k@1)lSq6o-6O3XZmp%
lj!;5W;3xGZCexG8~)IVL5N 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 K4NTTD;(q|sa|xIL literal 0 HcmV?d00001 diff --git a/pic/springblade-admin1.png b/pic/springblade-admin1.png new file mode 100644 index 0000000000000000000000000000000000000000..be362acd879915a91dec1006512a2873d508a019 GIT binary patch literal 96045 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 z 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 oztHzz9~OPMNB{r; literal 0 HcmV?d00001 diff --git a/pic/springblade-admin2.png b/pic/springblade-admin2.png new file mode 100644 index 0000000000000000000000000000000000000000..cbfca541184dad759e239e2bb8d39c43a36065d4 GIT binary patch literal 53720 zcmeEuWmHw&7N{UdNlQp02uLd_t*CTKcSv`4c$7v!LAtxU8v*H*&LiC&hdytkf`0e& z&l~U08+Y7)d+fFMT64}dd(O4|q$Pz=kqMA*-MWP;BK+d@ty>5>w{G2bMT7<3z_(xI z-nvD0OXS5fIY*d{X^%oRMK`kJ@Q2vNMQ|_PepqCC#U9>6OW>QMpcA*N`?|cyeaM_v zLsdKAxfY(7*+%25GUfU4$n2L{Wg-$;cM3Du#m0-uBPDc4vU>947rw+Rdw;Hy~kw=rOmy54}RkHMZThix=fXLgTc^R#Vn$e;-8 zUl_8=3q)6DQ51kL;2B*Ha9%@jOH+R9!Y6(Rc9Zyhlt2RmVYFF?O z5Ui%x#6n^58fGJA&cxR5;Pv);8-vdW{CIJhaz^g_2cKOrlOLimwv?yLLs_OBlo-Z_ z6^N<=9x2&7ZVz)zk7**`diS0`Jd>{ zO4IA!g=%$0>zuF%L3bw5H@&2}Te(Bu6IH5uoVy;gaG*WmZW zJqi*{TQB57-=0o9{ZBCHL*I_Kbioyjb0K*;wOC9Y4y6u~BXx3F1OUh5r=x~Qq7{8nh zWsa8P4cHuHRgZuaP;MDjJ*NB8j|kGk`becg<=8Xwii}5XOM>*G@!hPaU$bKUE<-^) zcMPR3^xU>|t3~2su%#n(3wbzy{BT{6r)%r7t>ms%}`r?KO8MX5NhGvjt*>KvS9Ou=`@!39%CO!=ow&Ex00g>`G27HB;< zXt?$c9;>ao(_V$OFSKENrKX7<+L(lNFnHGK){uXVN^1k#8*Sok)Ir}*qj;%VrM&cx z*qD)i{EKlDAAq(!mUT^fCeCfa!|P1w9?!}z)i<-gSP|un<{QPG_d@9Wv*LT;B1WQE zOc*s2+M-`%f<4v-gh)M(!Ul3^7u4|7`&Jlgk{cRBrm4NCP*OBGO(JfAG+>P8G_ZvT zC<~3JRlSwNIDOCYcAM9m{IR2Y-|TwMsXCMB;stp+wUH~I^K06>DR53!8n%V^8PR(}vR4%t@8B7zACe`ovf6Mls0rA$)j~RMy}52E3NdG}9pp zf6(A=aY^o>ET{ZwVQs^)rubZ1A6=lEl*r!I<-LvPFU8w`7o;eeU}T17&Bi)YD`6;9s@r-aY&(I+USAawS`E1yx4^(obp3&WZ-5<}GS6t&x-8-j}J7h9qBNopQ8f+16{9%{;;xC^nR zo)x5Odd3ZCwwNB|H*R7WzJ1GTb^DGo-Wkf>6Y(mrf5u(@Lx;GmmZZ+Y(--acJiap! zHaXu@W;}M7+0B_9N`Us*K=-KkwO9SX&g-psmzQlxN_?K0=Y1)Mbf@)vhZ#Z^A8d+E z%Fn;-2WzqnJ-{Z9J3;u0oN{m3g_N%9++TIB+n~r5e1RdPyx6C9>Z9EGSS?16c>geW z+`23L{BmV7&bW{0;@qdYq{VB&P{9cfa*lwaPMT$@FlAd#+ zQp!$ocvW%h7*hL(497Z4>hg#hA;OZ_tZ?oXZ?$V$P~3%5OP! z-BEDd7OBBVLgvn0H6imAwTElWRh-=vGtd+dNK>Etd7tKGmnBa(C)$3%KD6dAM8eCt z+F?Iu_f^%*asuhrfSGo&(H_BEmW6h`(QEs$u%JN{F1rH1;)GQbNCe-fypEW!pYk5X zh7+8EQzvCcLq)n}!cJmsGier-2k#FIsDbTA!Et3yUm5yr72rv#EsM`>6hubCp3kQd zujbOmbvw^Mlc*>9h&G%)PR~_MsP}klOK=NK1+j9^5Ln49d@huIHhLUxKlbdG!z1t> zE}6%wdcj=SrcC4Mz9^kTE}htv^Wu00U~q4(DHkN8PjnPyM0Jlqf{9Hk%1+mMv>yf( z7=(Tj{My!=3wE`O-5?qh-AY!tXJNpfpCX0vhB&CiLnN6eWK|`VLQZYsOX?Sx4ABS3 zbhx=4>I3@tnKG}%B5k=E*{c%=U$K(q8CE;CzY+>P^-s(_LLydWZhy9E z+ghuhT`H9KaytM0g!=a>ovqL!B3$1#BUrdS*l#UPsFQ)%$7>Z00|kBBkNm(5wkDi} z)-BpevxRdn+Rt&3snLs344Px-cEIQj44qK-qlLkaH(MlUF$T>KaAuFUDxjj59uW=I z#nMuJ=COI*Az^vsAz#TQBK2GaD@T(_}rQbajd695agv&bC-~RnnR$z2G~AGO^WADF@m54kX_wF2y_R05xidE{=H|r+T8B5#ARy^e|LfA zxe#@*>v!m+_qIh|3R1&yoOjszZ5R^{Bw?x*UayoYZ8){x%gC`W zov}A^be_5#5%zM?xxXhM63*!v^7`fYsZ^SYzU|y2#&Vv>990hILNLzmI|u4`VH30> zeG^rm8T9+7@8-F6dHpeeg-7}-WSvMB^{y9dp?Sl3p=}{wy;F2mORJyL#TUdd3J^iv zT$Re$mG6;Hs3J!itK4VbGvu->EqtMLyK)~{MT~cv-7J?YaGU>dC1qEKOh$7sjOQD3 z`Yw2F%o}ifetj1|S^Xk1j zUPxfp?uM(uf2sk=uCppHl%|^8WQdKUo#x!(GnOzcz1%ryL>grtMPZ=Z-jIrw6T!A-2!zvD_1@cB@I4M zv2+#6meBsCR~oyKDY2PHeOy;M92u>K26RRI)|2V2?CImTq8Z3P<;oY5iSjscGKA%s zV(>mKaM|_V7~08u5oY@mQ=%t!hfc$mLPfP|pDQ*$_7ki8%$MV-x3UklkD@)FH=F3P z9gT#J>+79byy%$gZ{E5;co7h6OGS{dqK{JG^{zX3{eh1irY*%`dd`l{b|^AY^<1f7 zVilkdz4j(b7EnA(Uf9o4~}y$ z*DP9?7A6MIq|W1NSS7X@gAkS8N-G35^H8n!d9H`&v8A)$7IH1k#x$0-v!p z+?*Wc)XUk;xTR|O5*}`eZh9@}n2|72*YNSIFs{0~_H?`%SZf`?LdfflDvUSJ%y*-W zct$cMTFctHwEpcS7Gsrpr5^LE`+l5f5qymWZrTQ6K??#IgjE{!j@cakSfM$J%Y(kt z1YW~9T!&#pp%eDVho)Ygvh9xJ{_(K$q`v#*o0?pAk)PZj?b)o+A84LPFh9?~XQFiA zR;=VxpQ8Dpn-2!o3?@Lb5+|B*=Tyq$DAb1(x(L4L(eU-Sd~a}h+-WxJ*nmSFB6fLx zV58k?CH&CmQFC3`LU8QUo#B49%XY-cIC!K9lSg-J%USg7lBybS=iFb@E$@BSVO=>| zYgZZkRgmp74#AL)QU*oLG!eutwMiM9!c13r?%eqPCPDE_mi#I!2NRFTLtdKrv{`~I zCS>euG9F+fI?ZXGl^q%cJ?t|Q6aBjHH@eKyHo!8+2tG2Yn8ro+Orx%Mx1PiZkc@qL zbT}AeVZtQ!Nwt%#TZPy4ut%F=Dz(h?QNT*oo96Pp&XQnK^Xb~WIsd`&(WTpZ!5wtR9t^s!VoKW^S8Kb^icz=X*ahlcmEx!V3ff4}Um zTTRf6xb0U?NXG->Y9SBnH)Wi+6fq-VfuQCQJ|#J0S)&y6Q1gPiVRwe((jWql0J$$0 zB>=_erO$pBDqg4OwDiV26OsFg>51)p?s?zkML<%Lsl!1az1LXXv4EV+=(maikSVI? zLuG^q#^lh>@Q%&E`8xFg{ADHrZ5K#{xv63(H8zwWFBnvkSVlW#poSplvR-UrC7K&mSW&*Z|fNQ5(9pku$|I7nLC}g_u zpd~}|R7FWS`M}hkS=S$rez3qVH$<00oG(zJ%1=1+LWnbw`#gO_8AscQn|I9Wp( zwh7bf@a~p}wlES#F}rXM8ZqTfJuQS&L-Ee}S4JvPvC;G@h>fP%fwZM$)nBF6!ZY`i z_WD~8!+aK&_bWbs=C?UOuUYQZ*L&W%d$J5An+#-^vRDA%-3apPU3AWxF|SM0u_{srC}m?9k%W6;8eWV z^2Q@lGT%&-5N|6~nz6vWJ7t#KW!pU$!wE4NfAoPWlF8+fJ+EMp+B~s_`C|;qh8hJPMcJ>*C*`-7J6eKp$|GSZm53P(g{k=X*YY z`ru#myka+FN?_uYFBr&w9nHr3NR>aM7I1_7pAVUzfFM8cjv&pSFRzUgMy3Xk#&))0 z_;>moKq~PS;AyZC+)cVc@Xv=tXAsVEUqV5>{2za3RtfAqJ(;SqVX8a$=8Z~dOp>?r zb8kSkjpyg*dJ*d7){C8%mS6pGPGrlGFlca?V=6y?efF0}D#NrTbUwFo(i=9Bu~BoR%o8zk{BxN^sANY|WyRa9>Joxz`Ol&u`aT4i|X8*?gjY z;Q@}|@R)N`7uo>!mmAPSCLENo4}K-$fLCRWO|o92_0ZNl8Mzws5Q==5cDBbGY}V;o=K}g}YG3TLyqjsI=IvdhWd7{7tS`Se*4t8fl!WnVjn7$Ds&P z8Hc6l4~4iEL%#;5gib({}hYVlNz=}AVCOW zx>}i4<+~Z7`GxS^9ShB~XDQ^i@dBFw$C~iJfTg^_w_l2E!ET%LV?2+g(1B}}t(`B0 z6wh=ocEvKXMcwX&i6B>nEMHwdv_a@-tH-!6LZxPZ5Yj3pO*CG^&+2sg9WO;kb({B~ zD$Zno(ez3|3CzR0vqBezbUZyOJLTqD!Kk;^7ywb&-o+&TL60j&20eqVA>ks>@CivZ z16KV=J#$i|KJX9-a3db_UCcSmcZTF7(?LxAaYKa*f`gZ3>&W*Bkr#tY-*;erMX0Z| z02?HCw5x7kloDB~w((yPuiyCs>Iy9i)^OTL+4aXBklnsCe9u~R_D&%03Ta-RcN8~B zGYcnP2vphLv8q`~pSGId?7*%lX{q7E4XHF?@-R@N)KCK~nBm@TqarIzl_rQ)#&w|) zMr6)iIOqq4lsm0pH|@coiXuSZW&nXZBq1HR4%ZMd@YNIJ*n{?3jKYu8C1luQj)-_q zrFljQ=C7bX>AKM2=d!HftRm2$QC;_fXpW_B5h7Xnp3%t66b1PG)DC=q-}-)e_-|ft_pUZ zdd*y^O)>M{JHp1UsSlXJ^MNWRBv?T0cZBv68qN+^#)KF{P~w-8aJWH*?04aQ z^D>;il-8hx%u#vWgBR8IEvxSnroOqG1&?5((IK~GeEUihv@u<;SBcbW6ymsER|BCG zQ}e9qKw;E*?9%Q00zkkUNzHoQU|#%N!^J8;(mL951j*&`L)4UhbyyZ^z-rkDW()pi z`gZ~@pt-_f2d~+kx7A03tL&Sr^e-QK&g{C0ggouD+GLT;w4p$@sU?3JqE zVs84aDwx9?cP~1Mv1&qmMg!#|0&Yx*zM9tX2Z$8px9VaQ|9)K0;6NmNR=ZBl;wOs& zz0uwWSK5>*5c@YR(p4L+u?KnGldsDIa@2s5up3eNy|gr_F`ZW^cq=QBSmH*(cLxDR zxP&F#`R~^1C14+!V0#|^Ug$S`7?H$4OfY_5jQ6_!b2IDJL*oOuR6jh>64oF5@%v|B zUDn-=4{7oL_~)8&wJ-qz2@tSBx)J_AAM}L;q8;s9UrYU-?vGgt5do-PCRSZ1`)>sJ z$3qEF=j7pjlSTbkjFdbZvtO#s{|R!q@OLjf4W;C0d9fd6e2vL+F|4rz2JX5SKyid$ z7!xZ}1XwkSNFnZq-jND0{3KHA?S3)8uww3k#f^(x8o=iM6PX(vT5$odE=C&uuYg7B z1JfIk@D}~%&l}rLCZJ^sj20ou{}a_;6M>9?iR1sb?2q01ACYg^=D(1ol-TT1X>SlD zV}1_{Xkx@VWT*tYexXk_U||5s(^n*OLV!^5)llRbgyJ#BIPRqz-?%oB4`KMVd%qd3 zpx;%o2f;fk9Mm*g?7MJ}8}S-HOgZR2R^|71 zD2%|6d`@buzM-^T8rDzuIh8!{w~~tF1AQdmbJ$XA$Mk`UVoQOK{UWbmi>Ai-)Vy!0TfR2+~TDw6ozR~QKpRTx=|F-WEhvaY*C*-pT`;ny~MtwPI_fTw4C8X%BVu% zitMP<9f)4m)5GdxGojSHx-l^6ugFrpLq~^R&`bZ&$o;0Ek7SY>J^KAFuqi<6Nbph` z>t7X+XMi#6ktA+c&qfx&Nxw@Ff66&dQW_ z1LF;jzytFezy|zp*&j^vKO+BjBL2rxzxBxf1n5Q;{lBS;LgUuc6mGb1$?uC1ntY@U z;rU2xzg#WsdrFuMjP=KJkJk_GYl#a){CE%Yho?HcpEy^@CZy#A#EKE4n(Kp-IgONSwf^Q0J6d1z@M@dJE!Xf z3A`@$#!WahKeaFhif6_44iz7oci*k~m8$R``jtMS@i+k{oX&a^ONkM1`W8b*w>~3z zl45GQY?eJjQK|f)XA^f}XE$BWS&RB^1vUiVy5g6{1Edeo`&y@`^g6KfSK5Agd94-E z^QB)iX)Jqs4VUOo+xUX4*3E}w*NSVNrIFJ)|0fb%51B6w-Y)v9)xd>|0UEn%q3owG z{HMAGHUgvqL<^%j_;8PLVBhqnR@Ei9Us1|q5Z%vv+8Zdb~O6O z9b+0G%x`{%`FazssYYxsTV3}$uW|=Db$d2I%|WNT3&DGd@+VOWJz-~BA}|z(S!e;n zl5#so_3ws75&)BvI*ow-ZZ@$N*+GYATKPv&=u;m^_kJ7k%~U^CF& zt;G%|9BMl?7^HIKkEDMS9ve%EEy-C<@U4K*&wzDhqg55i)KnYD&PJ;LRNPwjaL+~U z&t@pnE|5rX+egG({*lg;fa|8p?+`$IvjmSeRkR3Xulig$?0$c6?OAA@0w2cLKgQl2 zLNu*|^e@}zo0Wa*cqtU`czV#g@)qwWg_&JoO&r{}R(dN{Hyh|g`H@=MBpWzgcti{ujQDNhsRdWMiUf*ykNsC>p{n;Wvl`|;w|c%Af1`^xDI z*1^~fd)&fy&9DY4kJ@452qs=7MOLeyUSAZ>N-c$f#pJ-1;9m$#b#O6l1;5!(%L!qku zc%H(g!XUWPkAzRQd`R1trvc8ol1h0b`HZ^Jo+1rl@YeY+A(W%U2v1t8btA1zIrFnW z2}W=OuejVsO@R64Ts^ZByirHdpkzH-HKRgw6Q>)N0#Sb;iF=%;3W#R3red&V#D$+Y zj}w#XUR#0bTpy6R5y5I*{TzQZG<#c%NJxg(ar#V>F0S;evczdZx*&kLCI5Fise>RzO z5Bhy_S8$+Wrl#gXaBczut}L@#5OxXlFKBtXU?23f+S;tPes^~vTOl&^bB`z*b;H@* zYFR`BORmL$Xdfj*1jz^E{a;~v_PsGX*>m@V`bh_l>HS?YH*To_FOJiZ^s*|uhu^RV zgx-#%&-wW0E4bpf7nq?Tkkqvn;QQk`# zXJ&?Z&0oxK3|Cx65h6tp2RZk0{@&d9{CV$n93M?jCNZ@zFbZ)-tewx!lOY>;hbbbE zk>LIyN|T5|FE;K%y#27XU=RV_``zaJK(oPKL80hNHJa0BJ1YZ%5Gr~8U0YYP)i0^9 zuj#%<*$)k@ud{zq&GU74VLPZ=hyR=VvPGJhqFwJPbAM6cjSl;W2XxwNG_!*iF_dcd z-_#tDAkhik8wnmeEaF^@iSNm?tzA!w1G)egvhxGx67W?K_>~>!)Q?d{EG@+@$=Ofj znZi>BCw>J_caRP|QY;FHKe;oHRkNK-a$a6oXPOUgxm1uKS{$!-) z9I67_Nc3bF^{<-NH^xh-C1V}?TxLoHj52=4A0RFy*Zml9?VLZ|RRD*xYm(aUdI#T6 zO#8<+O4EU?_-+qnQ@kUWjsnCdOvc3bS~LA4=CQj6sPy?vU%$VOh5^P`@l_uAwJy5W z2tPg^k^vY#DCGgwUq|JDU`p+NnfHH~-Jdf^3jy|vE66|c@1s$GB>@gq++?TzFa~c0 zhye#?os(AQ@1uHvCHXHzHan)#|3JQ?vE`S=zl$pjZdSa@II_JF83D-|vHB&vS@5-f zOl5_q22y}eanvdo{8s`qziZ6K?4%V<`~o`*`G}`x`6Z{I{&d2mAdcUo{tH&MnkeB)2bQee#JE99%4cyrW}pEo{| z;9+Z~`VqVv77B#Spjv>n-w@qNfN34DVfeuWnHpNJ6JWA~ff8Z3A^@$^MH!z2tTtB& z(Jm`$q|z0e1Fm6*l;1qd@m=QnB!VBP2!z3gp5B$#>z;T}xB={S7atsKBo$~!5?f>N zUeS-g03SyL5%>k^rQMAV98zqg*jVFcfAG6R@`qC-01wQBLuT^suR?GLl=Skq$9(^C z5(fAl=c*|CHW%ryLNEj%R$2ds;>lk}<;VaLfhnf?>mEsK0wQu66xjavQ4k;^@a@rm zO2!TF0&Z6#@;_t&;{5mRtimt{>nBXILVVC0^o`18%d@6H2fkX1v+6>dwf^`?QrG-p zW775rkzj`OyhqhkwkMxZ%>ps(-8l+A`MrGjq%AdJw@Sfpq5N!VYa+J7w@USqyP^cI z-u~#Y2RAq(NPc5{fcEIIgUn@gX~k;K{Uh!So6%C0IAm@g?lx<|Fz(2a_{$nCy14Qh zi(u(zhHM`Dsq(nN4tR8^Z1t>MgS0a&15s)pP-JywDwWB(1VJks0eCHssE72i@Of{r)+$MtC%XKp@tsISys^vXJ6R+w% zf%y7yrjY_?EM^Bu^Cdp{fmmPH%eQMR_*_5MaZ3^i5sfd;>}W3@5%1TL>JaFS(2Y#E zj!sRf!z3MR=PO#zpHuiqK3qM9+Z>CS|LiKsJlIPdGtz^VQ%Pq;nj+PMo_f->aQo;y z4!uvWA%AReO?N%CMeZ1pHzIXhikQnbx2!JCT8geau?dyfjU>3M^&y8(NE$+kSV-XU zJmkBAwI;n+0A3k4S+=YXNffv|PrlLsP_UsKJUkUlr*)E*nZjJk-jpn*53eQnl^JIQ-L){CiH1OkSui@Gm{r4J2pUS{B#wU4CT4KZw z9;ZW>!xb`T;}L>z(h*oK#Pti?HYe$w`Awk*pKYJiTvVS;L0V1lxQ`k)2QsQR5DK<( zY9Ow+H;xL0-ZomJDB0>%2??CRg^O!V9|fDbY;_nk1*^Q*h}m{N?hW*5us4;CN{=O! z%*`y)7R(WQdg{l%0Ap}IJZijuIH|G^HUZns3LeawLG+#;*iCNNmmGeN7>wB*O6ubq zW9!kGK4KM8OLs87tO_KYh#Jh*1w6VOALBF&hw5ws=L`?IjCiMFyXL%#nSQrE&ne>< zpPqSvU)xGalU6T2e55oH=euFqZZE{(4gO$yEPN)E^sOnyhpjUrjGSb;V%^^lR&wRe z3Ua^XAlwMhJWTIb(xUEBG{}l}(E}&SSA688*u(h9oc>_x$*~R4VTDRs#S%>-ojZ2< z0rBn$$Z{tz;=HMJKg*nw5PVB$?seoX&_fKMm<}r^j}^%XvKyWGcm^`9)+rDy1-c{J zy#B*v7Pr2aAc^-Qv00$i{%|d!mNs|*M?cFZh&Q|orLfh*M5QK=Z`uli~$D4xn z(-8I#KTL>TPQ0{$1kzp>%}v;WlIWyr>7Sv2Yxt)9sO||hko$RL_Ig)I&CaTdi3aWH zmC-x9)jahQc5eNMF5Nspun~$nu*Ceh%EJc$b|c;@x$S?E|x<#)Hixr8Kv@bizv+Qo8#d-0H68 zd@-J~*6ef<3Y8RsC}Ma#uFavCdiI$(d1&8Um~$v+@P|Zebfp}sP4Jxxq~yjoG2QR1 zbYlDPr}0YW0po@Y2~5=7#yv0Y z9FAODM8n}gwUVK1;1_9>v3ToBRE|Um8`rHS6_N^exN94D4}T|rV$C53*xlEA7tD~V zhx#+Fqi$GVOPrezT~%mmKHUL3qLa*oUwREEe|EjCb}uFX5hF78ZJ8gnK^7IP9i}f| zKMy`UcKqPup=hNzB6;;{X)B@tjCFrz@f=r5ahvIi3%P?fh|Ri+m#JlfT~GB|WO$sr zf)!~B^|{;TnEF8Smrcd<68Y*@b8C7Cwo=FVLDQZ*eDj`}&18z*ygg69vQ*81mV#6c zTV|O1bccFjT z!3s7O1v;#g7sEB=@OudllI?cSYID%?%^G9Gwjs^=xHgC0x;6*&HB*=|gACHApu$oy zlxfFV#Wd~elg&3%#Pu-YP29q71>^yM0&wAgxN-(+gC|1C!YE5{l;Fn7ktQABiyO2q6DLtz-i9fh}DO$C~EIRrffJpy6v&yysLJTGZ=b(9(^6BHKAxa zzQg$-at;nrT&^)08+%diJ}4Ubh166aU%UHJf7zzpn-cy!e=J48d~uneEcd2p(y3TgO2WF<~Dw0t~5GY}LY4j?TqtkIFe%eSo?%Np&;-EpO zyVo#M_4gEcaSl%$%885=tBzaF{p^}t2?aDsjJ%Pr%9LAaW71Nt58yw8wkeX z;E9bXBkfUkW>!z8IHkJ~#wya05;?cOy`rrg0C%m5Hhc`OB+$yuwUM5^Th*^2Y4>Ikq;VVXSS5!Zb z5j%G0{B9%0*GeOEu6uk~F)EItTcLTza{in{gODQnHBZC*5pQ1cS88Ot(>t7l4j+3l zBcK1M_9iqHdWk1;ffh^_e)mXbn<$C>Oyo9>{n;)g0Tik6v-lEVUR~Lpt3Yl@R4cac zR@s`b7NQ)L)_`AUCfm>2^?w8|Ag-&lw3S@T-$y&I($Xm-82?ByT*q%~SBdvF8BFZI zj?!WS0on(ZKbo!nSUNKWh?IzhUW)%cEiDcNXitn$|DJdb0wl?f2dOBa!Zv0}Fn79KlQW{{rgvMQUx zVdSTME@%b_&XR2gb597jT^+$kcFG;+c3wGmVmlcNv?%aiksoOjl2&+69VT_W`&Rhu zURT(MHxAsZ@BtgP&Q2_sJp+e_1WM_;oYCYQVRb~DpOu48gH|mg3=YQ(Q5L4C4$VHA zvA~BE^w@(#D~8Ueho7yUZPv=R;DUk#F4<|ToKEW>*%}wV)S?H4SeT2row(RM=NI~b zlX=y|#w_r?7RbNfhSvzzH0X=xwVG>bd?z34>a+zZw*X(d*nknC?z4pI4DRzN4IB__ z`vpQx#6{$Xy+Vr6nQbp99TldW2Am6##KVt&d+!Q8n`AD9?tOwxjxEaxDlnh;`iBEll6S&R0jmvIDh$Xqokijfx3Ar>jVirrq-5_+qA4HMes zL|l?N=JqO8?&?xYibdlRWgF0AAM5Telb{mM+2MI&Z6xl@HDkEv)s)ckk%ED_NzDf9 zAZ&cfLMuT7ud-*0u@ubpjc+Z?X9U`o%sydr2iR!bBbbr|vGRw_@CaWznw43xs z6OB&VK(=o3edK}tRz2aV`f%+$3aS<56Y;2}4hg;BHlohQObMdJ9dPOa4xSyhFB!UM zFeI`kEsb*ayTxMmn%~IZBT;Q3C_kCX~Ox=XU^ddT) z_~)QY@Kh~Ga@G<#O5i=vE^of`ef{(Ua!bM|n{_cy%3UCCkLachIwfUzV|ftT3F`8+9wk7{{^6snc{NrP~Ak6dr`>IBUM6}62>#!6qO zHQOs3#=WrI#0h1~2O9cJ;%+nARenzfo(aZ=lctNSj5L(t;@i-))z*%%is7l5&0vP- z2N>rIC+_DAA6E>Vc%{xEI?r6v`irr!kbR_oM&y=ScWE+Ut+OgLaepP6Q5+=DaK(@r zT05SA{|J<$IeoN48xK%Q_akkT6*y0==v0)*)mHdk{V6u<^M$3Kh7O6fja>4M9%8m%7_*&^zcwJxvVWsz;UR|QBWj>R=Bn$@2lQqS z2}yRd`u8#v2_#&B8!@JS2)KMIK<@Zk@)|{#4&FEqI_I_K z%R+_j&K}Q86c#u#ZPuqvY-yaNLhbDSBdNiN@))hK?!bb)$q;7gTlm?iv`X#9cOBEN zwfjd(tC~~sTn7RMiJ~lX%?kWBi>K&T2L|pP;MgN378|0HnWRg>@%vjacP^MnEkDV6 zZC9Ldpm4&y!t^DD{m4tt4oxQ+eSLbwA$rltuJnEE_6hZaR#KD-)CzXx_XD^UvaGXUy9e1X)(N*K*+Zw{FBO-duBpzmKK1+_;kIfuu$r;%*} zNzJ_w+I1DZgxpI8&;fGwp?jULl@y3j!|YG5po zdvFH#{g4kXuB=CLFD-?D)+)S0EWd~Qs_FnN=n<}P{j1(MZpb$=CbO}^73vU)qPP7& zdod1>yZiby?Z@@58Xnb^igdmT6Yt*FqGa^?F)ok?*LreSIwuIxTR;ymx0(M9g9PfXk#9C-F6?>o%v-~MsK7d+q=!}|VerMN024N`wh^F|>|q9)g* zm*sJzpw;>1N(z)+QEEihhk;5m z4)rzIjjs_MJ*Qu1W`|xQd`+Vtl`z?>vj%K}4}bRC{!twJ@in~{;AQ=P_-~=H@q_Cg zv>!0L!CkRtY*b8)7`t=uLDi72Ul$sS8@gMZ7;t$sL>KT|$xc=45kqD`Vwm zcfx_d(6Pf%o`>#7TedpVRagmr5*9gcz*1qRhmf(pIo$?(R7P(#n)B!M+RPSqv z62|`61ZD#_%ERC*`Vmm}$5w2ck`#$sz2CA>zdmFue%1M99d2y=wh@J?*79g$d{on; z4#sWx<&O!Or(v&Zv%ratN@IChzAgRnS@?*^;}s!(75oXPk;ClU8z}>|BC#&o*v#Ki z@S$eFSbC7B*}%8p+ZV@8Ex}`?{!^Sl9VnixyH{s^(kq{0`}@48gS_$Si2Ve_-Yw7U7Q+%KEGbjgo5t|4d_OdId*J4oUB=3z-ZSlT# zlT-QK)qd6P^@xBziLpdL(7jhpU$5s^|49H=`v_HU{uXaYT=DOV?-I!{E>5n(x!+pk zclgh$0KicsSTO&$K@49Y=P-@%*CC+kh}9~^M|1gxF25(m0P40IB!4fxrd%l?-gB<& zc8-63Wuyc7tMI`Q00#)CR%SUX{1QW9>>7l>yatZf83MF=h2C(}q4STgv~Xbm zm@ZvKt1XE5kgL9br05M=sK_XI^Wf$} z&de7;iY<)UgERt+{*R*8suq@*&JxP<&DyQD=-L``-6*rbu|G!0m|6z3bB!8 zL96K3tO8_8^|2Kn<`Mq}R*V7zH?IB3*ACcwbwc6kdSy2p-R%o#zz=s*&E?2;_PUr7 zf;DkU(|%R`wOm0syX$iSOe782r=uS=<2n7xA;K3fl)+BuRL-c-KD+SjH-y{{;k#k;}@^cmeb@*=(%XP^iJI|JzhA(M! z07T~x?`i(Q)7KnZC=R&OR~KEbVz%p(dj+ogsigjzjPkqN)E}3`YT*O(Xn+2E(@#jo z3=hj~ztNt2cd~$Jgdw@);`Ap>c^{ta{8#j{0g^5_OTCfxndn72LEQq*61yt#l6QSgn`W) z*>zJ*9;HT)kLL<}zT!3QXS;mxMd}sTS&&pJd)RfN_vX*&M}XtU(xzTOhl%*8d($O& zA!g#Re}Fe;4(G%3o{aM zwv{?56Akty$T7r(Tu6)a6r%NU0k$i1=sGOTGYB(rR}JoPyVS+ zw5x@eUmZe7xckRkv`-dnng)t_Mu9Nj(+g4qL>E{^DL$a*|7tIvE~CkMYe z6UUWIxUd(CE8l0+$Mbo8GOtcC%CBH>L$~XPl&iwMEsG)sKK;&n3+i>u;6jY1Pj!Lz_$6Q|zZN|vpfv45vwXp-spJfx~*$I_!iO;vfxV_kl`omi5?W@$C4 z*rTR3MK-ZOFkvr_&g{3-{>w^J0XJIkkP8oE2*XPPjlzy4aWWr5-o`0%W7Zh;4fL)j zsmq+~V3e17uYj4;SU1u>EEOsf|=SV-Thdem*Tk~EVuxA^cIUyIDL z<-{;Lq13n4(qcz%ON+MypJn0wp=Rw@Ldcz@XOa*CftY5`Df?I=GHnycT+_kVJ zZzTL$lyIqmV$9d7D*wiJupOsxZvJ87_b#>qGE`$G#GvKnGsl;f7BzjU%ghhuB4@cG>%pZZnqA6eq?otq66)<#or~TPhv* zmRKJVb`}tuKl@HT|9{wf%djZBw_jLB5D-BS5R?>2Nu?zf1SAEd8v~@fVVqlO2}KYk z6%?dHIwb{!p}V`g1_sz`MB;vK@8^B@hrN$|?EUA{#mrpmTGv`<{LWm@6xQTlu-YXJ zS^QXBydM+N1uy1!I-v47+zIo;G=k!|r3L9a zLaDA+6o-D=3N+8sy;o=@MH+#Ir?@LL(eT3N?ccNlYFWZSrA^JK?M>J%7zb?oqh+na zegDqf0WFqRU0G_OJbTmdj6SG=cT>l}oY=e{)s1&7=M^~>#DjjAYD)Dtl8#Z((W${x#UwjJL^c>(_=OL zCEcu!mAgOvdoa;ncV3>6T25Ep09R~M@Q6@*{jCsCnqk*Lvi7VVfAnK=R@>eO+*+C4 zR^1`q+m3Ced~}0p*UDZlJ(mt~*~MtqGA~MUgEp8fl~`>%)z2~ugav&x+FoTS@=8hg z!oomhxHuJD#>gBaVtj~$Xd&0GN5b*E7Y47NP1)~oWCz_8q4uI^3BRbOycHW+->Q-d zP>=-Z+p~{EDAqH}#9Bi}OlgaoqJ>;Xt9-YLr-a)24mNMsv<9>Zyre-vC|C7!f#Uen@@Tmy(F zw~N@4w+2tXfmGq4E%5Xn^?m%QDS~&K^Pt#lk)KVjUu^V>Mb#~6G{X6+-mwU^xW<3^h~s}e7fLYl1}UcEk^BQ7 zT8z35Z;E+Z=#7Z!G4g#bsyqA_GVqkc>a?^l{s3Tfn}jy>k7i#p9k9}>4UX#pj^M>F zGffVKoqB!des!ifnZ$3^QV1ka5g+Kt^V_65eQ~@fM}C3RUp^Oo2c|^geac8VHDNAL zl$`(UdRp13&ra^121du?XvUwb#J*ssm}q)$yep?cSB+1eGLrzPDS6BVajJTmU{GN(F2nV@RY8Vm>? z?x6#-0r+3tD#-@%J%-=XrwwiU9F{c@VZ6~>@yc7GkN3q<_VvHKd9r^jK&cl82d|+k z!8j=H2l7=fAMQ{%1V*bYhyjyltU}%;Je!1U96~mZ_UP@}t@s>TS}11rLU{?z%IzHm zVash#odVRnlaGcDAtAjbNq*I1y+snI@!$oViv7Pw-XF@B`A3`AGJHByHuRu}nh9{^ zKf64HX;DA+%f_!zsvZfY!0zi|I%RZ71OI}I2KlkKgqnjJ^4WK|^@Va99qbqbJY=@I zlhgPt;D|Z?MyTksfQ+@%SMYI<<-zHT8=wP68maa#+5Qh=O+*o6NsSoSAL%Vo9Z;j8 zRpUQ^73yVUbx{m@^-fS#>;QMhdVd*qO^}PR4x5yle#BG!nwq?f9?K8YQ6*%W6?; zIRX(mK)}h^Vt0=pSpt@~gg)?Ob;C7a7oppgo}~j@3I|#Lt#jn`{$tr;hyPv5m2;h+ z2ZG=w#eRff0~?Z;{}P@{;Q$w2V))U_i9w2{+J!X!Bl8dq5<)WFh_OZa-Yxl5zY1c| z5cOxh)GX%To_93k%YZD48F@(lNIm+h=q$HyGGG5ng&y``xc#G0p2)U#e|e1n)nJ~x zPG@H(rUS?g>zNZKlo!nUsLWMHrkA}?T2RE3&|%k9Gu2wTQZ~@x5S5i}48w@DO<3D6 zs9XqJGphWUD9S97RhNm3dT^mYAu4r~wabEOA~1( zP&HF3U+-3-p3dcC#}i=7Y*a~b^7Ujrbb4BRBR!sekd#4df0)uO)DvjKvF0c&NRki` zXXC0FRkd6`$!if=HU)cBAa1ScvZiBe>*yKP3XJwQDhsj++9$R&XK{;mwI@M-nny+zYZly#%#;MO;L&T|_3UaxMgfwPH4Ae@@~`_T_wPP^{gllo zbkzHLypI7slJmu@$(UMFa)MWa9mXz92yBOJ3^TcVQC1c&qI747tObf{&;>XrSp z!DY<{mVACyJ z9-c1MD)fFl*EgF@+IxAt$B5yg@QAzDfK2r+zW;?U3cQ80IrK$#Rt1aDN_?Xe}HWO-DlQD_^Re#11Vy1A6PQcH7cNeIeXl#g7- z&G2;TjU$WN&j#z}Cok&aqNH{NZ}WGe|W?cs7M4-}-Q@QMeOVy)d%mRpNkI zSv{MLy-<2<{ZDo-McxTTg z!Xu%R%XsLiIU0q;8yoZFIi!BXt>37#9~``B2{j@cLW?jJl(c`;Ug%fTs2*bbtl>Cb z2a5kqFkbqq%_TcP$k>|+w$1t4@eR#LNG1FH8pQh6_-`ea-)+-GpIGHv8Br;dS=dp` z!@+VS9Hctc1EMN7JYZ5ANvK;=8L5s`DJk@7t3J!X-D zg5`dp*1k!mWDGwkv9~nwlWSqiIu4(SBIbzs3^n_1zjKe!w(c39SZ=goP5zSVHnfhc zZ{F?U4Py16GjfIp05`^be579ULN00>x6q+rZpI4IH7Ch&n*n_Wl5W^O3_>i zWDOqjVL%Ey$enaD>h^$z^ofXHrxhLMgY-0VI;MM)6;6h}G#Pb&3pM77DHCsuZhI{NK|oXil72aCvs%7~q(TMWXs za}&F2@X3&99ivFNRWAPB=Zn)Zl8$KsLxN8GO`JK9kz0eDaS0L3GiKBCZI~0)z1m_0 zMo~GQufi-eOj-L_{Xags^VHI4VXzzCrN0^dV{jv4YO~KmN$JX4ZjF(QYy!y0P4;5z zcaAy5B?M7jCtW3@q4!fyFRMMZanx>OF;-Z1!EpJ@Yu z3oIf50RdZ>**d={KbQ8P1<`f_)pn&Nvc}R(koNU2P?n-O+_jHTOaJ6M7I`-1lgKPB ze%bQ~`6>}f7pXr&Ama1+GgarURgU3;%5>wq)zybD?hjuS-f0QipNH?yS8y|`W4X;L$Lv(=A**8! z5HajZW-KhrYS0Zekqu=L``yh2Ptyk(_}dX>hzP2^7Ap6ZY7&1UvH(c-k{-{~5UJ&l#MwY(mYqld8v9|Q?{Ah$uZ z3T$nIrD(vRb}O$($HT*uj}dkUMt^ffQ&W@n0v~3$zszBX1V6Ogx(V&mRi7q&QrYs3 zsu%xOZGH1R7GW(P^Uj~A@*Vx9FXq3cKpPVAU3rwSemV_<7;AoEVPR=$ir9O>2Irm& ze`Yru$pzn>0U9myxF0-fS~=3623RFXT==@qG+?Y{4Qv;P7Cdaxj`^zv5+=~eS12g9 zMcRNNw%=<};JfO;uhqTS_MpINye}Ybj73} z@BU5%_%b0^i@8J9*72(*9V&QikESxhiD$UCiyo48w36`d+b`k%Y6St5ap=4aqE>VK2ZPm>3--b%dex!I{+VUenD&YS*G)g-sKMk%`| z9?+w{FQ7tQnlDMmrW%&n8&QG;#@g%keS4T~3GHU<@zA}MDe?=P4|sElMHCMxdGIpe zS0l^~GnKM8%q;3>Imk>0wG)MfEXh|5O;c2pGAD&~-k|&kGDJYZ{C(_KqWn?>G(-~v zh8N6d?s?S&R7-QK<}mp_Dajql`|KEGo%@jgbMb%<{2T?vCC+ce7kIIZ2Gi2;vK1QF zHhET&?q0>+WshS%T(4~rf}rP$0TvgSY+=NzqPIGj9NZ`hk&h~{+4b~KFr53ie}U$K zCKkoqa7&cwJ4>N_t49a3JvQmmo|2rO8!%1jWW1mHh0f*4>ECEJYP1_?qPW_jIu`F~ z9oTEb5}HKu-l0JcqKNf!_#T1y9M!&h%0r^Fx=$D`Khj8PzfntYZ@@p3E9|^4BG~UU zWi=M&y!iEo=L?o9${cwnw{g8hT_B5ck%N(BH(?z(f`x0ViwjnPZ}<93Zxz}jdZQ$h zEmd$bu^%gDykJI18*5-*6D8Mu1CW^Aglx%{PI995+I|3zV>(q@#_Go~i8W@`yzk0N?wQU4-PdU0w9_6?SaZo&Q{@s*+*>AG1z$Oa*UGoCB;iU1$vm*&e zy)&H8iIkO%$9)lt^S2}An9f^FOW=MqfBqzFRmy)|Q^+}b)VSL`r6BWRfd|S~RWB@W z3Sm$P)BSoL+bl$MUu1QAWz72`)#759-jrn zEOoJaGGEB#M99CDRQZ~!syw6qjFVlb>4W)@OK`$&FjRwgW}%6j^Yu)|RQVEqtci+>Dwws$;~;tW^Ov}#z5xSDQJfn; z>KaG*^W%#!;?)TK-wdKCW$+>|3KIZ1Er#H@8G`1C96$|EbdolJi zw5m;0>&CYS38E)K;8U%)naMn09Cm{D`c#J)-j=Lt?8bk&b=+Y!j0jI zfSIj9Pko!*3Spaso3uJ6Tn{gKSj<1oG_=(IIT52e+4|ub#kN6oZb!KL{Q+ZSjrgX7 z#&&^lkGThYKBMBbXK(%Du~GmR$tcnHIjs;Vjo_5>uSQKVD9-WD?30Yi-x~gjFuHu6 zP>o0iE$9Bu*8xt1YLG-WY5xMVQEx?kXxKb0b@QXfSGQNcrPWlLj$}JBR46!cUhk)R z0!0c1P!P-4v9^DGdD7~YBJOP5yTV& z2|~DV%`G2&yLFqsq9=z+F)_#L8lUgi1_ zi`zFz|D~A=e%x~o>sQ&I6i#^pPT(A=EYL$7|59N^Edf9SsnNZd6BT=MCpBPxjuriX z>jU!&213lRy_^jPWi!J zU}F(p{I^y+RgBcK-lGl{$$2@1kU$q|#W>uJ*mTkT3m!;@6>#d} z#zvRkLF>EH_B;c`Av?ghu?08Ul`Wkr$>gJnRyEtujU66gAmL{7?K9iMkXooGztcPJ zLvvAygm1siF>yrB(nZ;aK*R&79?rM1@feBX$qa1BHCZ=cx!^Mi?>{T2zo15i%_0Zb z^4Z%P(s#;3#hHF)-9-6>${ny+=A=I@pXW@!fyBE71V|4aRotPT(qans_7V%{6ST%5 zw45L!YoA4Th@45oQ)}#_#ZRL=--TcB#yDcKT^%)d{UVGC|4O9vC#2`7^*J*6@U@t+ zho4vuNsl936bpY!)Qw#H$uDno`Ey7cj&D|QCewW4)@8KL_>D-w@-|%R9{C{^Nk1UlQZ}bB;{=Q?lbk&B5Y@1vt*trKm}mF>?l zjKxGFp8R$NcQR*i?jw5B_j(^WRPvYKL?b>FFlTXC=E(JjEldN;U4Z22noHl1yX1u2 zUWpi7{~|Y=S$dddF^;jn%6_oAeXa>D@TkWxM@G3)6WX~&(Bn5ntz3?w6Wkj>unknv zI_UFjDeGweJ41;S=VijuGOY*sg{d>OEy{<{$P}63?Wr?!vjq;=DKbE(=&be*aKM%? zt@!I9N4@Md9e+t>(N)OE%XnB{4X<&Wb^_i0vSYsskRuku zy?37ovEXb71v{a(YrmDXvi=Tv>99LPphj`F=}{1cnP{1|^scswq;xx)lrt6m9-+ zoO5xghYvxvXe0os)=mD0o&5i+sIpU| zTciA!{Om5rN!q7r7Y0N5FaNEx@F=kQ0&R8I{r))cSrqz3PrdTTU94gPyEs)mebST| z#)TogmFeg%xw%%s&_-T%d=gG44ZstZ9Re&0${F-X%W~^HO6DHLFkj5wlj2v4?`!Ka z3%$urFLC?Kz~S2`Up9t*u@uRg6=sdw|FjjF{k+BajjoK2g#YaEa+9h9vevh1{7k=G zZ@I6_B#*2ca=OWVX6!Is$M?M16n{DM(%$=7tzqA$G=n1_Wv&9aZ+EiY$B@9OuW#^j zp^`@cqcnL#|MX$}Tm5snYRp+IqI8>?#G~}23}LWy8$G7Za~P%jbII1Dg3`z)$5Pv; z_3=V7wr;ay}>QlP&W67s$tQ4B~1?ziVTB(4)T$o{i(EC zBVGG+$5s4pOJ9xr%PQnlhUa})uoWNI)^)+VJqDR5 zxFM=0eqtCwC>vCS`mI!mLFN5Of z(*EKses-6vh;|`KHSxh4UFRj&T2}WC&avoFHv9elrM;)BQ+@kAjvkHUAEs8HG(MuNvWUNP@z1?mMO@l5z65$L)l&)2liR`~G-rSj} z=XIUJto5$I$ySqCDj-}PbXK_hf-+!#6rLSH1%6)k*84*Ou^e96woE7)R;ju6`ir48 zxuLb|W2PSxGKZDkI;~GGQBu{@)Qp{*M0D^+^6E9zI`K8P_?IbCPBW*wxi@jlAeom^ zZ~tr~bUs9|w=r_J$cG!dG|yHG!6hURb@l7Alc6Gryi`t=#`iHid_Be!Hb+*66$>n+ z_C_iP8YBv$7gFu3=S+uFvmYW-SCPMjT*Rl_4^Vm!-DN;{ejl-U-%4CP)@@0kKuK~n zpmZ@pOq*}qV=Bl^;d0sD2k7d?*g$dCeIZL%_(gd?xet^9daiO~C7+v@BB0CQ)0L93 zGJpf`v&c&_5V7ge zi*RW;%*HDJf`#G~brBq*vh7Otr)osdsi3!0aYH>)9y~-%k5{wfZ7?<#>X;sICxist z4mnD~Dz`z`mMbQg%)vLlOj?$P-O@jVe7{m%8loo9=!_}PTDa*N6QM0r+&f5oa}?<} zS(npt_M+xt{*pc;Y}D5Q2abl9&ba@%jI=&mK|r2ohq3M`lgO9=pWXuYT2`MQtlrST zHEl)mSyP|NKz4#AJUQU>C}6D|=_nK`y7_f#nFlwdd1=~w2x-r%B3rZ>QHE^jareE* zF5a}rtiIp$E^Jk8!);q)FV@fB>@7~{NE za{a4}lou^b%F26we48eRMw$JD(J}v)w)%KL5b$R_rpxdtA6G5=Xe{>DiOU)Ly?aE% zh(fJn!M6>4O$Ei4ae4fZT`4Y-hN8`SfA*(}qob--AlYHB zt9|Q8o4Md%5pI2X^BN?Rw{`i*DULpPl25q2E}(tcjG8@cKr!Ei!F&GvglRQJV8ji$ z#e>KMDhc1U2+DV3HF9)XZJOT79^8ngi_m4sim1>z5kO60SbFM6URH1%_@>f|lx_)4xc`;InThjariLR z*U*ile=9QlsPejLmv}J{Rn?8%re99^>geGVrFJRZBSZ7I4mpoDbq2!|_ei& z;c6~+JVVB0pIkhqMb$5 zw+{f(J{OI)@aJz+!MCOpU5DPoWBvI1qLUR2{D0wNx4p3DWuZLrWrg<-Wv(px7x;*P zzb|?Awqd}H-%yBLuRLUX1-B#k0|0s^oEF7@SbC7aj1`$O-*Zhg_8xWdMMS%@Ldj;Y zDZt4jF@nymZ)AR#nB)74IxPx2uReC#!6U1k39)@XHqCSxpztD5@8mCE7V4sbZ2&Bm z4vym>yN)0IR6de#<%!$rj>>)Da7UpU*f_?jns2R<6`qxw822x7gk8f312LM% zF**127f^H%1EJ`qg)PexdhmR$-T7U9&LRdp$hU|(j+mAjKOMNi{T(gV|J*(KEEd3h z|JFUZiW%U(rT*zFemqS-!-=$j zp`if1XeavL7VqeVM}cQ7@c)^Og@vp*$bo(Bz6?89uRJICkN%@2Bv zjD8jTSV*>+Hbg;n7)>{u<6xSXRc7`zN+Vb0Wt&rjKrj#7=cpZ_6U)sb(sf-;aROaz zLoOUw14tT;vuwlN3oG#aJs-8HsMSB^aJA8mrS~3y=e1Z&v5Q`DB!s`Ojx-n(lk`)ZYVPQigEMG?BdY&wPYv0$VvOZZiX(u zI|EYzMp?SFDmXQiMUFZW{|P(eR`&FAoPgtEP*dPo)dUIjbFQD-%aQrn)xkU5jLP*! zoH{TsVtWt)=f%5QwOFvSOGKjAUB)+2H-?XJCDhQ&EdO!^DW^01^ZkpUe&>h9)x>;@ zWn3QckC3(LCP_RtZBiB6=n|Jlj!U0+NwPOWpX9IhcbJf-D0xyqDsk2|1~(+Dv(>h? z(!J8WB;l=n)c1zS4oI$2hOI$D>a&0RSaXbKI*8%!Bs~8_!*W4h{wjR}E=iF*nO}5| zdTzO5o2GfXx>VCp5(o2uY4~*`ac1I}oSVPgfFEL*diE_mBqaf~KTiSc3 z`+9t{28i}*84}8e`|uBQ*mp*!vPoA);x@?>aBTy`CMhA3a;7rGO+%Xcs;>oW$@#Bq zR-=Okyyhc&j;P#;9L3X505I_Lgvh0 zC-jD;ni#mEcQQ6Va)x&lg&lYfUTkQq(VWGuyT}$9p)DZTIJZ=YJ{jHlOfsrWj!tzy zZwoa+gf>PGf`ik*jFgNj%&jwOUG)91g^+WO*=;{;0g5l?Y}IOoPF&_gr`oEjE0M zx4C7|-TLnvHt~G@H5O20n>B%M*IYF#FK00utcF;HEx3%fen~}Jekpsl9%0UKt=WCa zXY`)7Q{Ck>2I1mWCo@9fT7klhqGksAHyPYNa&YX}msTkHg521mFML{qeq1qdzNGMT zkw?4mrnQ>TMZ8`Sw{bML?T&W7RCoFcM4x_02cP6bXB0swx7XmJ2l}E5$InIlCGk6YhA65uQZRl;51!>h+OIWwk{e55#`QjAM7`c`kD= zs=afNbVL_t3g&aRg}S@qx;jko7{FeqdmO6LZmu_MJn;{ zD61<>^ItIM={Y^!>Yb=_>>(~N!}k%7H3dXb-E`nt{AH)o#)l!SqB5kjcMe-e$ToTX zB9GeEV_n&DM4zF>>(HcwISL2(m6ngynz@CPus*5_Vro(PDNjndr1jTOuoYozjE30bVyQ=T(!iGH2BGCweEKw$I9->ru1lm zmJ&4uY(69^FKy^*sPJWxD{k8oMWgiv^B)>k9Zdr*A4jHso5$GszAc7G|-e7pa=To9y)MN7))LeN#2g59$>avDOI7qjNPzihn}+Fiese_%DZ?n$=m zP2%)4=3ZkuoLR@>A?;Jx`^w_v`GP`T*;s>nLWQ;qI|CfArj`WPDyk)UYx~+dLIc=X zit7aMsv%^dssmnV(~HvR6;pTNucD)!o9lF|qRMo39#)P_1R`8Db`hB@g*lFUlLa%< zTKB0`r1kH>!X|{$QkUWkYY!?CM+^#b5_C3R-t9?Mt?WRwwRz3IE=)|aRP%@M>|pUh z=i-Q-MSDSojKo(OK@&Wy+7}-QUu{2C48k&d^(#Gy=S%i&X?=>nr@aQU8UOAhr2gPk z7Quw0gTrJ}^?$MmK+44bOIZX~HW^`D;?G5sAX}D;I%Tet^$R3y(Mg0{6ju`_u0-Gj zNCYi{MDMxpfEm=_ou(-i4Yrrx_ugQ+)eVe@R;9Wk9o?^qH)*x7SD{GDZAo;Yeauc3Ib$#6n90`Q&;RyDtC2~tsD3D9gIH4&PT{>u+4z{0 zfj8wzP)TxRMN?r=WSouHWNnsBU}vp>az8&V4h2i4+LteGu_HsQrYVt6`kg-i^~~{S z??c1)(4vRg4)wOm5v74**+MKvO@Wu~Cny-t6V2T719p2Wa9+#X4hDPx+d6V#eCPXn zPPqkciu$INssj+la_UyO!kugxN}NomP$pR+(lL8z+GOE zELT@3bd_E`H+EBEA}`~^yXkN10bVts>&P{kkyjVSwf#eLp#A+__ZK8|$ny<74MUVq_*yf%Zv zHxd`|KFpc2(b!+dsEEKAFqd=d%Xg!zm-`HS-=~7qK5xwWzK$Tt$inRkJ8ZS{PUOi}-955sK_x42E&ITV zo{s6eD`B%eMiKJxNhgl=^}=F|=9}E0T!(cKL$5;FTSIFw#nWheZ*On4r_yZT*UKse zW&58;mD=tAl(H52Cg=>T03&O-elegXBz96P2#+$7|KR8PYyp0k`=py|j&zr@-NZlOv-qI!fr8RNRL)`Q8jT?=%yClla`=a z_}2u-KK27#wd_|GC3XiH;!cX3vp$G`ny&E6B$ec0**V`Kj_FGiB3(&pIBMxvFQywe zuv;;V3Ax-+e?(Ty71p*9hMC-1Uz=WEZ|M-w8#evT&zj?llA%jHVyUGew;=K%qyc|g z9k8GYD^-b)&}Qe4b3>_c#m&sfmedB`Y}+&>J!YGNM~=Pu=J$*@ZA5B(fthW#CLp1c zk}aN*jV+C*dn=|ZMP=;2D}suZpqmG6i+(Wo3O6O>HP$P*rUm(+QFeQ3 zpjceXV%r}3W~1<(ysg!}WTUm@JC*()S`d8+5*tCTBKh{9pk&Y^zr<)RH10EHZ~p~Y zYXDI#??9ix4@>L_)>m3x=|h6N2z+SnXa%oBJ0|yj>}0?qhCx6_M{DnrTZT#O4@(8> zBByJEx#DDgm+vD2&})mT_k1d&Ycucus3}Ch-Dz9mhpH=L)TVC z+p|qv_3BD(+pf8bUfBhLB~2e#!dq{0dn+)GY*q$LjZf@)smXu7D)6ZDs)lN4_f2;S z?_L*M_3>qa`MbJCBN*u>K9iS?r=0~fvS z5h$c%R9o}hPI$Wd@>0`tcuA!DdXjr<7905nJYwRe>H7*%kzWj#Y8yh+#Mb*fo{;(h za0QVN@c{7>Cb|iEgj`%7cR1rZqS-XxIBVt7Yn}LYQSPz1HrMAnVVaLpx%%AoOEHu0tHboFApJV~#COIsLsXMEP)v#6j) z9V14Lv&Ce>Eq&W)ew8V#GF;-)P1<;Q8f8x6E0um`1U{m%PlSww=J>`ldH?z<@CgUk z78u?8ZixGK&)1kEx;x3wZbH3*y+}4Lfh$O;!+!yK+xu^qM$k z)yD9zchqEJ$S+X76nHP2{8iSRudx*1n(+sGt9K{-XKSbuOK!odr#ide_6&U}-}c-x zw%ZnZ-?K8K2DfKvG2tF#ekbPhWT%-|Saa_UW6&d&TdtKjb}3VVViO)N^Q@*-1p~Jv zM{dq;PWMh!dMDN^FFG+sUG!Rbv9aE3(KaVl+a4*D=elQApT#-s#hy8bfNL%IYb3j{ zWbl?Qdnl!C8~#8(dKc0jI5WrhaL(_y@^-;6@TMzMNVIDk@EiX?}1c= z7cXA4B`C!3S<|e07#SI*-9$x6{#fHA$8hf73zhzp=6dKbxpv>Pi){L8Vs5 zjxFf$Nycl@e(5mqh6d51A12ptpl`Q2^7hIAHLiO;P8!QBx_p1%BegA?{i^AeqrRG2 z)Zphh^eyI@zx{mys{-C) zLcKFyRGy+fvy(UbX}GlGU+z!zWiz=KMti^VufONF8+#ldJ&y87$(5^hf94shA&%Re5EF97z1PpLaG}hU8@kgLlhy&bpODZ)?bucZ8 z`^*azh9UR#0;1gv+AuTU>>mt#mrhcd(T4;bR8IRJEa|5{W26BwH3B)WG+Gdzidqd!3;n1JJ=TvJm8N$;JP0t;YfiP zpVR|Hr9^@BYbCLI|8c4t=e_*`7M1SN4cYC)=lS8_k{zuy7g*`GNXNK9nOLMI8x+yS z@EK0JN)k{lQ!9LL{P&QZjQG(xYay^^Z#P$-&k9?sw!XzlHn{Hf^+zFU>fl)5)%z>N z;>XSNMC@4pO&j-_ZcULnzwQ~zF+1toda}=N!E;gJ#UoEWN&^)Skg@GIx^nDBuM`V4 zBqw#Of!2Aks&J8mP0hcKsRT9--Zvz|=Il}JB)*SotlJBp)y>xwO=ArcjJAw#Fnvrn ziZ@a%qrNU|87a{oKO~+GEO4hA+2QG)sPNM$WN1TYNQKa8Bk!O~)9>Ud?cgcO5!SyG zXi&@bfM7ed%xTARh|AU2nl30x0@g(do%l{N*zP1X+KJ`1xm3E-LQ-mI>h*})lw^B; z$OB4|BMV zS>)&<9)y=7D_F>`|1oZ&33f;88TrwVkJk@%A$lHo4UV$0PXaN&$B9)D4bKm)`QxZq z|6dQ4&!w~mfxVCDo12^Ua-eF|dw}NVkhv_=yBoJ&BAt5-uftW_m6`w9J5iL{8Z1l| z$@7s~ng{+PUVN6X-&n%Gtk1YmGBqXN=xR<#5&W-01`XnivKDCw&BOos75K#XvK6;= zw*N!OS)7+L?rWF*{e9kb!-`im8<$*%c1`5m4xoxM8UGX+!7l+PTxv55evR|?Y<_Jq zw|L@>^p8FQ-kDPyT_(bgi`r2W{s)E8hQG7*Pc1Sv8h8tI`W}32F6`pH1L?8L8M zF{XUp1fAmEVxl|U?&EM3M3uny-j~b!Uc<~mR=E(OM5dtoc+-(J;+Qo~?d=mZ-Y7=X z?qg0o^)AmvZNNZvas_CAjMK-mP|Ip}p6c#;+1O6_XQG>yNsp1B$x~hK$WPj$Ag&3=bg} zv|J}57}~TZ>x!$L#Ugow@JK$6(9pdqEFK6520AEdHDHnER}A|X6U2iTid>y16Zo|} z>ZRp3AU^Ich@P&4mAJA4Om`bLAvmZsSC&c7R`8731IF$=N$!;PVpr)`cr0Q4^^Az- z$7DBtuPrqMw&47X0PPDKisQ;#(S;ATMRu~w^qiZG!^=lwN;ZRp52|@t0>0?o)4D7= z&ud(OW#)@gXe-yNomFbnjbt9<9yg7R)d8p)Zh1kIb-M)`=_7IhTA&HQ?6xOu5$z1>H7&Te(p!q1*-yrkubullCGI; z8CkZ^egHDB^zx`I`Br<%c4sB^w*9=$%E;}EmqEvr=9CZP;!>K!aa4Q8=19wZ#6eNm zNv}0(Zb0$vPy3zXE;H)QD{G&BSQ^i`jSp#vWJdQ zN86Q5$XM18A+iBP#4{n0^dHcvjrCK^Aex0DUHKANEnRS})moR0^@gnF?*|)TJdG>N zX3C+QxbhU*mDO{?n$4h2sh|FORQV=W{u^W0$yTZ3sU2M$x9s@I6s#vLX!LP%e&p7t z9-NRhQ-70Gw}UMxw8ZZK$uP@wn2vS^hK{~JmcG4bxjUIIs~_tH3Ta^G_#p53z}uWu z;>iWeWK^n#z8sjZ>0e#o94S%CzD7cm@BKF`>fT!sXh3w@^{e6 zF}O!hOah0}BcMmhd9Va~yzY>KXcqzSC`s}$6~6r>I)+ik?75wkzLON%nQn8m`Nyme z8hn7j)7$s0@Q3KDAW^7`WQt(C=dCc!$J}66lnP6D`v-x09|UU|xChRW6^Zh{(Hd;p z6^a1jCEDO$#S1Ki)__g&%EOJCSClKP)*AKw-(yY3VA<^FihzVG&uZ{UDzcR~? zU+MQnEXdB)9{HDkbpHeer^JuwJ-}ua|I&HyD|qz;fK30XFHqF%2ULb<<>`{!6P2U{ zD(B?QYXXk@6P}Wk;An5aKfkN&qiaRQa->sSLVHEpFe?G9uXI`dB(9?OpPXyw?9- z$tvOy5sW0de*Fg~2PVc1;7($VQm^b4g^kJ+$Sk=&Y6OS9&$f~&T|0bo1`BMp_W5eU z>I2(8t%hn_ck}B@vRYrC*sBN~zwmLLmKIHL*-Pd!dTo9Ek8g^-kSd0{VvicBcAC9s zHx3v?)D<#+cfL;%i$x0R3iC2rI&LNN(P8!MyqisHQ#_(}7%Qr8$7mfl7eog_g&f8- z^*)%v+|M|cU!=O!L9<>%mAt8khasT0@-cu;AyF=8gQUv2g;AjXP+qZK`thg{G3DoH zu-CMNl+QFjmd?*b*{EgB=VMe1;R}3J5gnPW^TUS3HiVIsJtA4Q|25Q zBluR~+FkhCnxAGAs)6O)3zs>yF6H@SB}S?>Z_%+UY3E&;NA~fnfkYv0Sb`E+#wjlG(V!Oht5lda z*cX^gn*|NC4~Hx7MCBryerW|IbHDj4SDL!)10TA-|D69WX5bnPVrd_wVZil|e=rI7 z^DriP^wA5fw~vY@7HVqNE@YRHampMcTxt$x&>JP2Ug_wU#~Y5i2nH1h)^|h96aV(< z5m$zT{GVv<*LVNMGQWQbdx=tHAI!u~B>2&7D4m-E5}{IjiH>OD=w*NDdRkDf9eGM! z|9$wUfC7xWAbQ+%i zK`@JIfDE1b)8_4|g$|AcBx|E=QU1>ff=?L1hP^x8vHuhqQS*afgSOCM|LMwFRKCbuNSwVfY6KV@w?DN-1S9 z`BvZ)_#><@7Y7s&207*jm^!-2yGvBrS|hhdABZU$>GtgoZk4*^SnkdK5j7q$g^#X2 ztWTWC@%<06N(BDe8SB(s+o`6GGy4-$2kHN<-Gp}n7X>Txk+xG~b zikhI>ww%^^qQ#KpK!REUo0HT-^<%M*3r+&=3qnC{@%<#~M)xJg%LerxYlSI@TY%yk_82UNlME4)x^4}yn zJ>iQ`n$xqceqjFp%ZPpXd=1ZYfF>#8(2PxtXH+*^XJY(=y>=UP0%40P;Au_7@Qbx- zFKIv3;qpk-nG*p+kf$l>CPCu)mvcU1cUdp(g@_eihY=zdY`{l>^IAn z*8n_i+5dJ1)D-=F_kT@2j0q^QhW3XfFg}b`(||Q*|FQXxM|FtF_*Qrs=T+>F6kM(n zNS9_#=!nGvw#*speYB2I(fz{AZd|gXu63cxCVimM05%h7wvc02go9PCeI_*y3yv4* zeDQmvT8e-O+#+VRCB|ujbqRW~+rX3?#NNC{K1@}z5^w-FbtH?(_9D}`EI(erq4VfY zbO4J#U4{0~)Knrk&-%8(oz!ga_@B(nlF)U@Ja7hZLCkJ}Gfw>w<8m};^1fTTv|GB@S5~r;SXF?&zpikw zE(S0!JF4=iSXCZ^PCq{7jy*74huU|p=ArBDs>tW0fKK@*xVXw|D%Xg7oE zkN2+6`>|;ekj4ojdoxtKnN%{W`UPj9TSY^AfsVyvsg~|@Hpz0?JO}d)QCp~!>kirz zgg3@S_Qx7h9kfhAiApM`sWutI@L&}g?-P*nd4vQ`UBI58bn*KSvosv>qWMILPHpy^ zS+T_o&R$4It>|mJDXfS4I=l@zRR#={2MkrbfLp}|le@%sYt{9!m)zCV!@^-Sh%)SY z%xKV0j?}v2BbCq~?*WIaWB!3iu<)fc^%)NK8{=^=M2mvnLnp1J79A$-gAZrzBXcTs zY@io3ph>oELYo|Y^ZwWO;&fJ#w$BsKed0tvhw`@luW1D%U(?M5I>G33LtI^5tGA*- zFTLykbG`IBZ+G&Q3o2}J9QM*n4K>V*WHsA*mdHqUATc(*^D0xDV?2GK^PFyes43f} zBBNAQmGPn{-iFU76!SL9z?WYaI;C?u`gM|2eRUuKkO`Ic+}1!A(pzump8bqrxZE>o zk{nmjjYoX;0!4)BtBJpydxS5BPAJ{8bw6J-+1VLWgEslT$XkQ$2PX-01X1#nneYH^ z65oOBFvq9L9_cNd_@P=uL^t-Tq@rxrTzLXqjG)CxK~VdM3MMod4O`S)Ac7)9CB$F| zva}$WLXpLVOSqFzDE2vj!L9k}ok1z1O)_Oy9n55h3xdTrh62a4V+pYtZ~;Nc`0Q0t$K~nzC>i><~)|x-2=6n*Fc@(&;<7I*A+&$ z&U;;29cf9ijD1~SjCfKZ^)gsyxF@yBIL;-PC zC8)=NR>G+Ft9)3s5#UvSF(5fg-tWRw1M428A3S4U;H@^r)Pff+4S60}RpS-=ru4ih z#Z7{YVNz#|!x93DKE7i;i($V%w_Wj{eU<9_ty{6lvvWx5i~!RS+?chQs>N!iKgyPT z^PiWAQF|Ez!d+?wj^%Cs)ck3RKA_aY;_HH|;=4@B3V!$J?_o6UaHS3%&l{Q4%r~O6 zAdMu0)S2{ILRS8~CRIMg0n{4ouiwNxNglM{|H17VNAe&)3)3Bip8Yv1zUl8)6-kj9pfP6)cd0|`kcmiv@k|sYzI1H6M`&Lrdl)DMj1lk zjld(-e(dtEJc^07e6C0ooNd`UdT_{aZMbXx1(fedtaT&m$-|OZgzWiT*Rqg(6A#pZ z0e|WVvNHweomJTWS29y|eSID`@{Wj~=W9?A`4BMHzz6sMILgi6RT4Q5* z2MTp9{)n}0B8?w$FVX~exnyK)%;WI*jxnBW+nj&{cSEhKce#9lEi#It2mTV_nM(5F z-%d)KYx7O?rX-Fg~;&S94I@e@tL#@WZ!AecdVHC74Q%?8Zk=p92l8h>Kwj z#vZ<>xH$DX$4OjgX_TH5+l8+;nAD(m(iQ(yJp9X0&41p6-~0Lc%E zTxR80POnb2*App!%J|g_*SB&UnBKIWN5FV#=ebj`%(PDDteS&F`?Wp<;X`B-0V6If zDCiLhaZ1AUUAunj`Lf*p4qFn|&{Gr_(A)^UVrDvW;)l$XpFAN28~THSH~B2dcY5(Sj};NULc}VNJlFo* zv0#Gu@71wM+wa?q!pU_isi~>1IZYFp8>%};|2Vef>E^=Sr?<{-EWh{||C-RUXHhrJ zPzpG3G&HfW&6RV9#t7SjRgtsmDb|!koka)d`C)Ug_fD7(7DzpRQ z*Z%thf1A?v8?djlkMH;5EjEXXa#z49DPnXUnDzi*+O3KJXZT-r65J8_l6j;qcA2RM zG?Xk)XRgG7CG~fauV#=hzFWGn@*)o)iIu|u1$s)S3Seq?vnfJ=~ScU7y&6a5a8Y|(^;qnG%ExYm&sVY z#5zd1Hv#O0prw!?Znh14N{eN05_AFuBIRmA^iSUG3g8Eb zm|;Sn!}GaAuqHnYxdX(ve;QsPrlz9YPhPOYdMrid5-JSDMlx^Z-GmBOtwl zl+Z&Ulu*N2`0Tx(XCv>=bIv!$_YVFrvevrq+3s1cIoEpkOj+i}wR_htT)1#UPF7Ow z!Ua6r3l}cE$HxJFiIegfxp0B@f}G^z=k6ERCJB-$HBy+d*CKJBJW+h2h+p*n&Ql^T ze0f|3{4cCHtZ(o`^9r@d4T=go2ah@3$qn2Be2ynIipW(tPvY_jSc2&qbAv^3a03`| z6oQH8l}xDb+yc);ofOs7Sm%0qdU~1ze>L#qt2~1_$|=H&UNs*Rr<1XRRRkC@_Dx!e z*B370;NlaV`G*uz&_0wKihxTd&`<>P1Ip%)(6^~4|eT2@S+YYA~bM1yhCG1Py^o$ z=pwY;Kh7pk^SbZx^>SCa8;N@5q{I5#<<0Us*jKkRlt_qN3xmBv^^cVp9!S1!Ai{ls ztmynKE^di!SGZSJvL98R$5H3IPYxeWSGGWf(4vb{J!+w?BVNvUN)ram)dHcn&geY7 zq@lu3(B-6sZ;esH$mVM8Y$km~{jVPhG=k!&-4#788(-(ir{Zf3@=PFIgh+t!|8qJil0 zeEA)^^zT>85*jG5%TI}Ax({xb%$?M1tOWU@J4cvzA8E4E>}|$$4z@7rrLMKmI=()_ zHd}6204mP}Mt7 z@ncSEn;(@Vf#+h6d9Mq!5ov#l%O15xD`~w-%6+%~NU*7iKAf|4;zw^rY&-an6D%L#>K@*>^ z{C0m0%-5b5hUV6Ay%`?YSfoNSA$Qg5C(@F$q_+C(zW->o@V@}5AS05oTV3uI!s)_a z(|AXJvQSE~G8DPAk!ml@jMJ1vqjQ*qn$%Wja->5YGTGNHp1=-<;Ky*3{z3B>O3XCH zcFjU!ODneD32TYmgvMmvS^+JpPp74QFP z7V&v~yQed`5uaM=R6tIVLcNoNt71uPA{INfLeOX-Cvqk^74NNNMjoaF*06?RUDpt& zh4>TaM;?(NWhG5Aa88^!*Szt>9^?Gp*CPE=!RiW&0rpiHrKi(X=&gQ*`)fyQe5AQ) z=9}v^pEg!Pjz#nOyUT|u4MLJIPMMRx&C^Kn>T~QwYOL?BlF<5_{)B~LvZp`X~&yNTb9NaM#3Cil@1<6SK z>(6LA!zc+tR;kGyW-7r)!%qpQPg z?*=hYS0Sc~PPI@>5~&{InyEDEi)no3BnRk$vVr4sN4b5sIPLt{!s^119|w$?YzT_q z$7+cZq9ArMsZhF;OXWr-Sn*(aU|A%a3Vi%(U+suu*xTLahJ^i9q9xvo4)e-Ms&mUv zAUZ*8VXCdVb2X-ZgNM_Jcu^To*gz42=&}GWDxYs39kl9bDBXs_(**qhCr!uH60f9k z@@oX1SnfVuKg2g|3$Jc`$J0~$YnzAFWh?Gx+?#E$T^V$3W{vWTt7i2uiwr9*4fnj9 z?q8Ml2O}*#RAuUq7SmB_iQDoZhn6n5sEKbDGQ9F+TFZM$JUTO%%eC-e=0^LbYC-8| zp%An)nYiC8xWKx|i+)g=@QRZmd!@S1-X(z_?u(cCY&Df*sW+NYzN=+I2zoCvrNzta z<9GaiZnh?S+7|s_kR$a~OG14%w=WUUfQ3LcBR1k!H8sJv38~P#$xl_%NWvxSBgXRa z>%92NVdmHm$<3h<8hFf-|yHv`KW*H82>R1m)o^|zf%rYu@z_=O)t?j0TI6ikU#-)vo z_UE>+io^1*DeSN$SOm}%HCw-~Nig0goHgmn%wFWn$g7#P9SCpSxB~ZRKd|UlY+-`# z3Z8sdI#L=(Hr# z6RBdV0V0E&cJL53Nm;0*%$cZKEUVV%za!`v@j|T38aEqYK+kIU54ycVNds$-M^$`R zc5|Z5a=v3*D~G^`U&WD@MU)!`JKy^)YIg%Q$F?j~;`t@?=B><_nr#`w*-H+(7ONdkf29LTR*4$U5j)wOhiuLu-X`yfaP z?mVgEM>E^@bk`JRy_nXkX3ULM)5z3d)nV&Ucv6~7nndke6}@YW*dff>QK+V!^{UVn z@-Xrsdt<*rr$S*rt6CYOL@7|r5@$CJXVcVfrQm;9P#l3mkaDZo6^6MPA#d6v`%a9- z(z>;ld#Fnoj{2urKuTIFtqNtaw_#Tsvd6yOm7l{r$#N`;ms!7Txcmn7m+Pa&VWshV zR3PTjF(9g@k7_L1bK0mF*D9Oc8JW`ai%T`=X7W;msjm4@jKr;R6J zuA7_&PczdFUg@65W)!T?K*GwG%86UO396JXg4+}YGffRI&A5Ef@iOYh!MC&tO-dh4 zAkt67GfGC}lqByLoM6SFQe9E3`(KKZ?|wtf-e(`3a)05PR%cyQEp`JpVTkWJU+r3~ zilK*mg&6OUSmt9SRsRn|P!#M?-Z;IAgU!G?KB543r_`YQK3px1%zJ+&2+NC8PA*O~ zTyW^So-nO@ILS+Slw&BwZ1C==;YN@zfBlQ7Su-paA?r}XyO+0rYi>So81w9@s8pXXk!pp3CiH_; z>mKX|rAP17X!(X-OYStIWbHW;n7+0-YTDG+7Ykydd&G|6)pL=D#qkD?%#@}B89AJr|n?ssYH8iR^8rK?=`Pq;`=sK7d?Bc%)cgUU+d9#EHQ zg18Q!N>LonJ$a^o)gS&uBW0WKu86PYx)mrEO^df3cn5vKo?KFL>tdOVPLGU6c*4)9> zd8)E+$JIU=lANJmiIwPJ^7K^lbodas?Bz?vO0#H^eSL-kVn_6T_%nt1=p7M#S|IJ4 z7a+jJP+R45rq-jtQQdT|&7bGmOrmV(b)pH6_SzlRAagCvh52J7tkhwo9d$|fp0xM( zU~3$=iv;ZC%)>bgtiRlTG2JN;^@YP`VKm4o?Uj{U+(nP%{ytO+`h`}I)-W!-|MG`UT}Um%a{33v=|3$<99Y@eOFZ=V2MO$mJf8wXb-`--kLlkdIn5h}fL zoyX{Ub~~mKzy6nu=E&%2PMH1_mu#)ZNjQ3ERqH`N;g`GW*zfCc>a#^_a!rZWEZZk# z8w5{2p-EQLloy`g(vR)bLqlPV3C2n%v7BLF_>xMp_nf=TvWAs2k-_}7At7F{{L&RGqCUes-G+H|5rrmhe_itzJ6*3B7mhCg$hmx(BE zFOd~O8|2q)A54W`FEBIdK{qs(FJ#vCIyRQ>(Q4G#2(2SrUZv8o7pYGPTJ>!werCI@ zr!-S6TKB60FXDqZ)5k|XMGRensvQrb7C1S?(2VWPjq|2%AlI?v(WpZ@ocd)eM5k4R zyaEb*^8ArSPTA&Eq~qs#u!z`U`(4Z1(AdM-J^N#G*Z7QTt@8WiO*Q_<93KQMX7~0a z^$a6z%=@Q#J;f8#%I)>{Yn-#5E}MD=rDCDWl{@;37(3TzjKrzfscpB^YT765ttn2( zI1SZbo<&*c$t}88yJhD%22z4SAaD>)nPVkEjIYfyD&R zlr<k+%_V2MD^w#k!;uK=)iq)hvRiJKaV)hxK#1;ub&0G6<_U zI(m9cnfgt*Aq=PXp&c@8K_ieMYU;}DcUQKi%dgzf?pIb~qJWcIv5==lj1bhjtBwB- zu<3Up+d%`LHkr2e`W+8sFsH86ua-mbT}6*VqPg(}KtuXSV^Rgb2@aEx$u?h0eMZOaWz zv;xP{s$|wqCsgGSQK{Ui>+vg4%>kX}Scg|F;_efCn{AO`AJ+CHZ_XryvHJIt0 zvEkelaMnTb5Y z=g2&`(Xw(S+nlSJic92(Z9^XrU2l})ev684)^taT>P(_ip0FwHC8}obn0`H6&+C%u z$w>1ri^xB!VFe?M$8-<1+2 zv3i-V$e|)aP))BXcm8qmuTN>29_-X?K2%LJH}C)ah7$^p@h#*TEpyZm`slcS(~EF; zD!a)4#`W<3Ag&SgF*7qLrH`oz>sCZR$iX@d}3tpkD?AF6J zqg*=M@I;hXqwrXVrCMLCM)Y5_*Bw0&!MYG|-_1~MCg&_oxhl+%&8CJvkS9I*Rj z4^%#s_Q!faS9dw-+T45)A**5sSwIZ+uJ`q;Xn%^c`ws1FZfOAh!Dr z5c_bC3U6ezju4mJ@|b$NdPn*MVPfPaj(FE>TW_}$$86A3;21$l~W zc0)7l&zQ|$rhdl<091O@E`iQl`L%=y0996Qtu6fp(wx0V+E9YhV|!78@GmaT;G;jg zac0|)q9O;<=Me_5e5cZ7b*L8=K>bf{{=QcNc1=5SqL3%U@LbAY5(1R(e!#0cOVw{; zfQJFfSAQ)1iQ1krKK2v<#y|^?InSrO@RV|4o&%}BsrgG>r+YzmPcV&{@Wn_Khd(0B0;{g^6@J)rZcZ)14E-6 zA9oEMo;xXb3o%#fmnNqi3I;i&fh(tNxO*q|fQj1qCerY2yAQ zfJ;bD%D{Inm%xp(*N&U;_A5mM9NZi}W)VU^ZTEn)a7q*!e$}oKeplW}rVN8?b&`DkB3Z5r5Jdt;_nz^0lmmJ25XkyOp4n9CQ-wkNG zrz1CI?rFrB*CL^*ilKgYw%7Gq0uMNiZoe|`-GUgC?hVqnqtfIS6jgQ;!6%}f@r;X7 zw}s@$IF;*t6rdj?PFDKm(8s(V^sdiI;|r>|M(O{ILGP8Jm`-#%UT;DKn=xKDtJmY_ zYb%+W-;(t|&90){)17htR*gRyX zz0+0k=2Tu}VqT12cqUm%jUaVs^wtn>%CftrWBYzPdyz8uWTxZR9HQN_M7BD5jZRa* z??ej`vx^%_&Pd*)SQwglXH%OBvNZ2A`V|_|+n6{XPxwM5S~j7i3dK*;_UI9(yq22R z-v<3}Z*}`}1*=$z65vi+aCjatj@u_qfjO~Cl!iI$D~62I%F*_IRmH1^?O)?$?LL)Z z7iI|=^|Y9Buu5nQPYgVS#X8!6K&j3eg;sUCrVtV7?Nhp1I$uP_=->pO-_Zz->L25Y z5kmO0OnX+|y}zcC!xUb;<6)7hXqdRXX_F=-?uyj7oQn7j= z$~>Mq&?JFrjze}!`MOaQDt{iy6N4&}d)lyx+U(iBc0()8aVRgwEe^=Gx{k%B6dP*n zlClPWCNRh`XkrgdPV#yXcmLtzeyb&21n5OBb$bX{;rNpWm$gMv3aK&3e4ZbZF^kt$ zm$QmOvM!{2DKK!a7v4WSa`niPp2Ds;>V`!wA_7)4lAzI%aN+88Rz%XF29kwws7)_8 zX_-Bb)*2gQF$OydWrO_5G_>d5q6nZ)iJZ0 zdCHdak%IT(pj`e6yBNBbq`7en*`^L;+EucOs-8_D3+f6VS+Ofe&X8AN>dMAESfP;J z66Sy)I&@Cir;b{Ky-9w)l0kz}&eN-|85)gn*j*dZV$wsDFExKT8%>rRAr5+#c1TB@ z@Bc&V{R$3Rm$#uL^xR;9d&|L$6Xy>$e~bDh0}x1LTgA@5N+h#;@85>_-}V5J20~xB z^V<1&%0&mWqO+R(7gPVc;s1*C{|BQ_yORS|7qqeuU`wI z?|fh|U^r8%{LUVMHg+(5Bwf8a36P7+;_xVoVkW*r$)=n(bwUFN;{E>!$36r$!x#>) z(}&Z$E}JLsm6I}6c+j{+{@14XM0XB>f+g};i1++6emw`E>eY%>l7tq1e%+Bj!B#6C zr=dvtV@`2Sao+KlKP5CKuk4_2KBp>vWy}*a-%2K6HD)=Y2K;KlmK(SJUW;u>s4%yB z%B_!et#C|74{YPTaZ`%qFNo-G2}o#N1%mgWGX)z&li-Noq)jHdt}JIX%YvrYCb{(X zxG3^-s;PpW5AXXc(s?V=b%ehA*hGJ?)FEq8TTf$+s`4CPL%p3bxo9$%N8*<3rovU7 z!`X|4_qL>RZj>En@w_!C61qqGbV{A#Ou&|KJIxvvYbp33L-_j6uH1q8mQKr~hKAr# z>H$oaMVdi*z7S5X#^!)yhC%`v&PX$f)NyWurNgvTPC4^i;Q?hbVU0-cC+#~euX+>m z%&vuRmwWVD?yOyzQZ_`go^`o3kAa%t6xP3bJ*{D8ajKZkYvR@V%)Vt}gj)ULEV?(# z9;C!pXJx748-_6Cl+4?r_hebjVYk1%I{bCYd65OVU|Uui6W0Po#i{EbrRJg?9UQ(W zpnS@5_Ou(s#X@shc^?vgO_4u4Hu5JJ)W( zO>5R}-P3gqh?gJEZ6toNuBHz-Kvh@e9L%(8&Q3H}SoibD zL@(s-bbKFdcQl0BgC_O2hn~<1ai%)V%3N#K2--c#Ofb|9aj*p_VVR_|s@7>3sXlDXBJcSa(Hd6dUXT_?7!@W9gEToDepSj!T#`Ewx?Nzbj&B#(?Vh* z(%V)_BUs?pElf<5AdP9}0}kqYGQP;BNpu|_g(dZz2{QA!4=Pa?q+)UE<5*X4V-A%* zO!P}yT5F5wIB}@_xjrkG-Re+*?YI!t`LP6|N)CWc1340S=NIlnK=$%mYk#}1zby!O z7$~WB9{&8NZ~uE8K;?ptdMc6K=N9fp1E(m9&o$@sR=$X1%MM6ps6WH$j1T*3_d6~? z;h~xajHI2lfzzWPp$7znp}Kw{0GCkwRY_Q638h}X`A;H+m5fjzbJwx=VL=xlC7i#7 zWa@WYTHSIpeqf5<{8)DKhorjo9B?|GlzAx(^_;aW}i|u)me?54MoB zfXr?}(+U4c`F|dNX?Tk7q)>p)wFC)~Q~dNh+tQ_fEco|2V_JYO|38xDVgnK9Cp7p( zOQH~qv~kDbA{vi{QT7x8UV6YkNZ_vt8Xq1TR=3_13CsEIn7_09%5~KC;1e^!5n1Q* zJ=q7EtarFyG0{mF2?7~R&{K^hTzm$%0`I+IfAR=}U~9XYt>EEx9@oQZEC@c6fVo9I zV`(y_yWyf@Q)4|yUo`1wXPq>7?^J99_)UFpzu$D!(9D=!es;Ouc_xd-=cN6q?F-u0 z6T4$+t(%uFswZ54xZVZ~h{{4L4d3~7L%*pvBYLPnPsE7qI^+UmhGgW$iWyDy9WgLF zkO0w=Z-|d4H@18rbKl>72>xN}dBr950t7(Jb{_%h&JIor@mpk=YMHNVx$K#f1U zF2QHMGlrU;1Q;RAV>kT#aq43Lxxv_HUb%?VMPSzXzQ4%ySj;8say$2ijbs`qdrr{n6tNxAKg%q$5*cQ!7c@nw(_w&F?c_1gNgwBrV<{t6&B^tS0Du@Sm{5FUV+AmXuo&bcmyTqRd7a}rHA#!T_}b!nHp$UJeGo9xw|-}Hm2eCdx3#;L z{V8%ndydchut-yEqiy9%PBQc`-yd8@3tqgjGV*Vfbm;;ln0(q7rj5EpWCF@NmM9#S8BNe*v^z0Cy8I&<(S>gjJ>I)kS9ka)oiErndB;s*Em4a2v;y= zkW{RYnB4}ROnsp*iTuCSL3N*KnazaJ@%oE(YM#Y)As!la+z7%czo}!wg6fkQK2_sQ zNKx!Bx>jJ2Si*v!st0V*Q`Ad*#~Nof;dneC!Pj1+WE|s*YP8nMyu2^%U|&wsOOR=S`bHlLvDI9Pk3cXf-W+eVs9i@#&iKDyVVM71)+I>PNSx zSp9+}Pr>fWVlHdFM>Fa2K{T44YC$Cr>>USE@}r^NN+p+mLFO5rwM@OMRWeQMI3y7> zh=yiW>|4Vgg?QW7^pYDGA~f*G)0)cS4L>&bjd0Y5$wZfBQ>32e4hKg$C>GGZ%kQt7hx{p$^GLBosxTB9$-6aV2W&ri}4g$Td}V&N9F?LAuF` zsjH!j!%O&K+z`@AvC^%4%gDkSfsb&NeginBB~FBD3){?tzNBg3)wOUnhE;`}8fLcR z7Jux0ylI~derVN;k+mRZjXJbidw&Vzvs=xsI+JOdz?=5Vr0?jdig;$(TcJh^tz$u< zU3MA8)z$0AaXnt&?`|FB^$%b*1d0;f=V65FIyyen;lsA6Twfj6-Uv|DETG5jN4VY= zY9_9%da+4I{J7s-x4F%S$9Csu^!#O~9I)HsrPXMIj!V_{J9Bc6EGKKsz?#MDsjaEw zJFoYfq1WBL?);!X@GvOd2y@G!3SC-^v^O9xdQZ${DCk!-Y2H<}&@%4$)^uuPOh)U( zt~nQPD|&&St{67EnPQ$63xB%~<8H(-4b%#TI&aRx{f6$^vvf(7)K+ipsOBxc5Y^4} zaaQC$J;T=xXiciz#H)?kWe63D@P?JoJCIN`wc(iZYVoymN5L|vt< zLcdfjuBEaf>RC=J7a#!wnj;ruUgG0Q>lj%dx6*pLph5=w$*4uVDhDIu$Y=!y8^@9~ zLDfbl0Unduz22sdKOSzmbt^>QJw(Qfx}zH68SKL;kb_>^Wr+;L9r>_ZLMxKj*In?| zVO#SlpPwjQC>wc_f%G6CU*Deio)_qoVxJ)vyITO;!76Q$bF{76Rw4B&8Dvrg1tJGz zq?ddwn7)q3c$=Vv%n6SgHQ?fu5{Cv`MY9RMbS<@#vNYZ;PD1goA_x|Hgcfe#Sv-xPb$nQQ zgoa$pKUxlHwcrq)YigXnzfkvyKUnmqG#(gEC5ty@E%Q5}a>7~lJ288Ne6L0%bn}D5 zi0YfRu5VulBO4ZSQs3RvQJ$~SfEwtO*O1-@PC@#2T%fyKe3g$9$5h8?&@{3;@i@XP z&1`70a;nVL7?A)8e5&h($!G`5ELukmV~;E%*Ny^X$RA+H=zDo~KSmv`)t9%2)q=nC zCr$1*d@o5Y?>1deh0-sPb@JQS?r4>Wy)hJY-Q#%-Ly$u7`*mHn?}$n!g#|1&mo$qyVKpIwy?~V67Afqvo81~+ zd3(;s(j&i5X;(YCs94+W`%a{i@9|ZFXpLrG64;NlRDDD36+NqB4MRGCwmEB-Z&Ob) zEU8xpSFgN>c#b85Ts_w?7e8`rf-B9p-h$L(4(UsiISwKa?IKFzyn4q5c(rEk4ckHX z9yU(5UK5yJbp`clCfScvS>{lAY4+tjt@7y#H2YR&rrmXEDUrhOt|5IarD2SjK5o<; zV+v`!eBxp0OvU(6Q)tCH3+i5<4yyv^@G^pYmxSEgskyL7eCDl(kYzIW&1#Qk_0g{i zoO8lF8kMF237bn%L&%R$P9ykBNW*plGFem&wZd(XbM$f<7gjej?`9?*p=ofKMFEAg zsEnWpp*?w0V<9ivAw1Nzn^8*bWu{Yp1C0#wg>WyYp>pO?cv)O!{NUH|&06K^P1$1C z)mTPUC#Ut?nwz5NPHZFIa-S2sLPY9G6Jco~**#QFp4=mAcqDbw^A>GEE+xES>t8O1 zdBvX^2srC+A5zSVb-TV8yjNky1RP&sNg&01`k;^NG${(vpm0s{dw$()=E!n*qStK1 z?U*FVO;`IWw4iF`0MAViT|dR0w}&*@G9`XzV@v5VNunZc-x@hBR&O_o_U69~Q%rLF zLA<$nQtr{jo)?d_#je)q*&A*S4A3j20STd9Ys}PfAa5*%DssgOYxyKsS~ekcHD1D`Dn5RY0p8~$Q!z{}N>Ba|(tGsc4R$AKZ9C zFPz!DK3KpdvBi`+D*83ji|=NR2Y;9evj^AX`In3b@cwNd)}pk}%9b!$U2JC)M^G&y z%;1^_yJy71%TY|teGA)E_3K09vpYkriaV6*qb#*yGI3>nG}EWyJ-r;~uy&5n@5Elb z3ah{xS~3vav(U~#S9tI}O+_K2h1FMJa{xmV2PTn@-L>f4WesvpgB?c94`9;tYc$z_ z4Um{#^*&x}YkOVI1M6KUx07Ebfc>CFqPM3ghV@-gjiz2q#^bNL0^~HAY>)7UyF=bP z>km!24~KlG<4@t=-4fwnb2VCCTkbzng>PbO60d~9osDtxReW2ww|(y?#CmD?{n~H0 z;pHrztQeOJ6I`zt)?yZNm9kbX*ykSv(8PuhWE&?iZjg_#O1eMp5GRZ;TG#CUuYIW7 zcrE{}@tu?4NN(js?Fa*D-FY*3DuP-APbE$G>+OYn7D{xCtZx)UD-|%A9$^qI6+<6< z6k!?}rcb5?c5+f#&9VZiP}tdmU7TD+N;~_w9BMiQsR?d=oyYwkU_G3Z`n5rnYE`Yj zwRT^poMG8OE%&|eJHAhGLpKvamRl{`0-uAk#Q1i8u~9jdb`mR?t90ZoQZzRwMUe^V zXe&=AYcbm^`iv^aL5J7x^=;LY(OZO@D?}%WKhB>?DKmF@n>AdZ3-{=YHIR=&w4S;b z73GdR_#v)}D=7UDfL*OdX}V;A10ac7eA-)PRX?ni)jbmH$MmpY9@vf?`LOoE^Pj7E zuQ|4T+bl)R74+t%%yw1{cR%@tA4Aq{^LvyjkeSP8^AJ!NHZj*% ze?yGG0+jGVNY7pS1^X+{Z~M*4(f9;}76@TbuCIZ4y zAN0cXaOa01b*7K-6WMY(1WU7KdA2%ea$K$);G1urWLXTDZOyc$wq@ zr*<;qW^m+moY!D$L!R=IoD)ur>linS-PnDQ+0^ z8n%;94OKX?X7P959`c&ju6|P#%eR+Wh?3>E-|Gu-Ta2Tw+vp?Rx45&_H)Jb0uvfyj zYA=h*belg^7TT2=o}grnGBrlO&@xEiREdB}l`r&+I;GXkaz{n)<;v!~2W4lg&ROE6 z`P$qDJ3Nk#6+1L6${cwziF7V_dEes6q%bI8)vjvm-TYVHaS8D5oHbZFT%vD^bNGNKF0Fp5ib8(o&3j!MpG5=oyv~AZ#&ao9yPB7M~~VV$-#-0VnQ%F1y)IH$QpNnV`TVM_0Y7` z_JoJ?cmm}m{rMe1^Rw!&pbr=cv39nP#O(&SXQKO*GUprxblyv4C0TKNogRD;Q6RGM zAVNJ$`WK=<=Lp-Lv+n1<^H?3-*_6wI0hI}-%9Q7-sQ{qJ&uRbyNfD`(mNsI$Dw#O9 z=!qVZ>go4>WHTBvTDXVrq=tAUD-*kvCQddb;H)Wn;Irf zDfHw$v7m21aZ#v7d!2uqL*N(w%&pA3MlrH-s=Cg}3nA>4WS{2UTFqni9i-H*E$njK z{rQf*>0_ofM=mv}oy1jWwuvNSX;kZnE=5*A?M0AFV9n0zA$4whn5fT6ckj{xQ=gZG zMWl8#MS5CJ>)S6+wQ zs5q|7D$wg*foT%bk%bd*PA-2%^V7cQZ^SvieA~pm*Z>LIxETHv5z?^sQJu!q21!CeA6sh@%wAeG6XJ3(K75 z$SIr>6)bOyjGV=ktn^H_u(W4v^lRHMI?l6mKF{F<(PTwITMheIW;{dF3USAG6~>B zq*j5#y+WpN=kM)n{s(OaKVeT(o&OoZ{CAi(#$*Sf@|_M)WZA=}H~n zih%ykBWm`(0|RxyvM=I1CI5geHG45(Ry6U806_x6hz*U;_*ImDb%_@OZJ!+xZOV}A3pCx@7V+xU3#I7J_Yyujhh+&mYG zymdddT8z=;!8MAjiYcZ2j}N;Ji!=zEbLYoVxw^B(-`^rJQ>H_?(_#mEsMO#GU_QS# zYngj4O{WtAWdRLU1(&KXKG$>BVFLP&APBo&#kQEorXPJt3aId;Ii!->;~A=>fK!gA z733qUaxHYqA~;EtQz1eb^>gxQZe`WZ5M2{6#}awez}!{|4X+}eaH(XQ-hPfm-7mQ% z^rj7Jq47C}FQ|N`zwOqmlYAZ)4EO4?QR183kN&Iz$Ey!fqan;Q$oA+;N>xR+5ojfL z=mxwN6Fj_I-|L})VDO;2-3Xzz*A;8J{V5>~q;87&N~OKqy(~9_8WK2aw=+=U z)$Q@7H_)cmse6+L;Yn%o3C>O7J9JErnb6?Nok^*lySp&ot;SGJ&^>Vi_ z=j$zwa2j#3>55Y%gr6AjS4t0_2mrFnZ`f|O*V`E2o7U0X=QXtzVJ)n|ew*xYD=nNH z4p}6AD7I{?a1-PXALYr3oc4w7kyC8)UTXykRW#c)x~b5qlLnsu=A-L|-h#N#B%%@_ zz*{ty!~jTO>pPV2-ZP@=?11{zdhD;`?6_NW7>)ZK^ud&a_nyC;GeExd-N+-C46EYS zeI9HTzFIap)$4V)k}BZlX-A_$mLRjzKecweHd~!O()lF0$Pj?*P(oe_{+Kkk`Pt)H zLz||4=CDglsIu>m58);-+sbzu?EttqwfW@GPa>?#IhQT+h3*s}aZYat0lus7Kx~l*sLJ>i z8;2nDsO#v3-*gP=b}*T2cdGQjQe&?+<`PD|*eb=^Yd0MH9)(A0nA6V}5sX zAibn_AeV1sh)7uU;D&sfALUFV(}`<8tsv-6d#{eVH$qP1-9Ne`ckV;jVr!SbTHr>> z$WB-SYP|vM()-L!`M+)hR`AEAi={jfeklkz<;lJnV+ z&~n{@ILx)|h~)!sy6GbIZXHKDAR>2>UsC_*JOvs8{k$0g*DGiC{R<8cdjU{YBI~clP4-cS<74BfeEVpM6eO|4{Ya z9UoU%;+Na1zhq z;jjK4v9zYGZTQ&9V3}Mx|3Q2tb5|hc%$%CqylpNC!=j4~AZg%}3=Tn?hdt9ic)d3` z@qzuWLmQwyw$-b{gyJMxan!gir4mO{W^jnUP#6u0liAdxekVmD=yU*Jsp%dWWQO?V zg9u6s-{q`?(wB~#s~g*2;tCer20H~RMjssil)eYv{g;$~tFb{Am|2L7E!zTu*98dj z$}=quV9#wPqWiSRCbS$#Bo0s2vq*I+TXmR>>F%#t}3yVEMRinqAjDu@lC;jZh@ zKZm!arGfEjv*eTj3G%Cwdwh|!xJCUM<~l7}9otNp)EVo;5qJ2Y`LI&X+CoLUzg9{EJY^7E@G41^Qs>8pY z;)({6VEV5}ecT#V3GE6Bi^&iF2GRd*P=CKUeTuT3-R-9dKp&aERm9l~zi*{_0HFQG zBvyj|JZJw|;0Ol*$Fh=0UH!bZiIyY)rfw!bfBHxF{!|1K1b~3`g1|C8ojm=Mw$%)D%uXx^lj#nE_ElVytA( z<>=)nfGPrRzJGUZ{vnD}QQrnc-5|%ua4tu{$6hF_13o04FO2^T`JT&>?kQDI6qU{w z#-&qF{7UV{yK^~W2dJ{UpPhZaFd%>+sRX|UN}g*xWPlI(zf!#tow&eU+qZz_xmtve zz^GzMeI#`X$h4#&qt5(lZG0&3W)Pf}7$x>L>YY~t#BQYL7cP(_luOKK2+po$ z34H^Gwl>O1EMn87g=hOYI^3FDyg0xPL!V6^R~Y2G^;#0ly;tLj3&Hs9`x7MWCV!rg zMWnCrvrc~HC@6cr1qx@Nnd+ZRtdmo-%(sw1nX^tVeeJi-%l_CRso~|tm-UBvaj^le zgODIk`YMs^WjcwP;@grDz}H+z1(LnoqfZBVI&Ak&M+<}T6I`38LZ?aaB;W7VBI=N2 zDH>wJt}k}--oO+RIKr2#5Z8NUm#>G4y-(#FtF8Gti!Mqq84F4~gb2^995q>5XJIAX z4m<2rK@}bCrWXQ;C9hZCX72ISqBix7?~``n8I)YE=k1>QwXxCyj5MDi^m+_1D9H8A zDqdodAd|a)MP_GqmVt0=>Y1(?&_r=kh?>l@@TQ^&Lr~LF|?jdIaRuzRTUK+WTAm>xpxcXX>S>|<0YmBZb%92*LptIkyLzk z0*&a7FW}#Pr#)0G&vfJ{zjdKAgk{G>UW%Basu@F{=&C4o9dIpe1emn7<@wuZbN zHth~$pS0@G#}zvkHP|t7jqgdu$)crlc690M_~{0hzXbqYWAeIkqLxC#oQZE`uA=uy z;#PM{WJRpMX`S_U4YH@<{B5Zd(ULTz99{?KU28LoD$?cP(C(&dv)r!w5c|1YZ3hQ- zJYUA_nocCQE(cH6WG=cb=AAYfG8mJ2hjBemc_!F5xbO0KmLj=jePmyTmIUnQ2cX;H_l+@dBifjG0|5V#8YU-73OF+ZQaP?l4(b5Ul`xq3^ug#~ar&CFk1sz)^QQ z8L(Bu+r6mJZZTL+F(oHBF*Y7V&SMs9+S;63w{qKc_i5~qqG>x*3nsWmrVTXPPEM+3 zc{{Q6k8y@O%D_Nfkh<15ZjEj_ORHpoEUg6O!<#iSd~v>P z$?}sUUPEeh+gts50>k@m4q*kibH$D(oS=uZagm|5)QC+B>yXecUIzL2v;;AE3`3ZI zM|EtBC>m_j#(y>z8EFHNCMZs84!1_ns8>hFcUn}+G5*H>rDfYqI^(Cy72c!uCbRQm zKRP~*=lfEBT+eVUsbae6z4zKtci#4g;O2yrLM5tG!Gyl0;xq4S`Sn@(?8Q_DYD?vi z#yjLg1aSg%^3kEQs>&JNWAgEO~(zyCI4V|aS)jxD4^*yv+` zjMszYv@fn0L4d_zDRxg6E|=nRT(fpX(OoQD;Id#FhL#P4%RO?8%u6f60}r z26#astPl?UW6b6B_Vh_W*5f{b+h-@6|H?TsSb=a*gY7=QdT|A+7dy<|KJl}r^jkV% zg$=G5UY-`fkgCnqqum)k)4cDVztOXQMK%aGQ!$2`r&T}A1$Z?$;;)wtBWN-&{xLK8 zo3V!U({JPPrd&D`X#QgJCn=C(7;tx8`Q!YYasqh_%n%VKc0rfTeTFSkIyCA=qEsxf3_3tSsVZD|7)HAxf*NsDDAl%alHhn zdfYGc{*0~tr5S_!K(0pGZ}a|Kj_#BJ@g#kj^6UWD@1g)w2+Vq|hgkBOhqbtCSrRYmxymN(-&U*T(9+Siy(dTmH4}3?C`u`pELXb5k zv4CYrgyN?9tnZ6pSFt&%9)(g!%Rq^otBMoGjn=zKFaUrH663P3{6t~(33^#~&vn&? zIpgn8{qxrESAlHhp5D7JkxqeYhwX{mT3i!09qXRt(l%w_!iSVoq#ku$isTgAh?{E( zr)ZklzrWePA1~sIM8^A%(Eij**RZdgVrTtFhL&Cle4?;UDHdpPjJB_tv$C=zr~QE4hF z&QKx(224W%DGCu40)!+$=#Ye(1k%on1@K<)hx_TA-<8 z>$W~sBznL79MW&_eWl7Yrf0Z3IeTzgWZGG##FPh-{r{8H;SSOnBA>?yXsc;-Uvc{|_1z?*+2V7Zb-n9>^4T>8V-_mx;Ip-0u|hcox_& z*J3KK?SU5I?V~aXP13uWMiPK|Q*ZnSxxh<%zEY=NG$&BQ*@@B`Jj}t684w2ws{UjT zwR9ncGLI}D4%1v6rZ-z*VAgSt*|sr&=7x;!T$#CZ=y^GpI9AU?^_o+yL_=Un19&ka zvA`MRht&ONA|_QT^0LQq8P==b8a?b{Zr`){Dy4-ua02&gv{pavW4u?@vkQ2-M*2<$ zz(IZ!pTmI1YIMGNqxFLX#Z%|H_NluSl`l0<3vF_yBPbH7h$kyZiXN)b%Or|N-x2y6cAB#x_52Mb`xG%Zn&zi9S>8!{o5?F@IW#R05I6`8)eOE z@xL^wQ-qZU$O?7x@MVhl9p(DSD&@k7t6*`vQo?JN(?(DxhQe?4MYedSV5GemET}38 zDivl*S~5An^59wMD9|VpBS0qWsrK8Q^`+%Ah!MdCd$5(&Ua3wzC8Gcin?|$jOC)HI z;FYA*k}>zw`>{)+Pvk`TnXgh~Ir~q9`6_{;H4J0OOj|Dr$HXP0eik!$7EP;x1I&oU zA(yQcF)|5DW_gja{7-BECzU1cNw(W{4$!-mZ#XaMT(E2e9Ls(+nE&nwdHe~aF4Yv` zu*CLF=N~W-=QIHzNmtMV|0oK6vskZd!he~@jWS%O_|WG}qU5nK1zh4;E2dZuAH(NS z*f?2X+UWY6JC0|^R1kQR%m?`#cUv;!RhWs&42wJ)!CdxSIal9u%56+D0m~jKo3CmC ztaS9m=2Nv$*(CK$-TlzEz^Y26F)zy?596p5%J3UyMD!qx{cLC?Miuqo_0>pl{^K!4 zfY4nVJ4M?g?HG)c;0$hoe(#b6H_IZ2?lpob6SA7B)D!PAUrt`Z!&2=J)537NEV!F_ z>Z~UIPzL}HhK1;@ooDlc7rz8Pes~syuj}*(6y&|#yz$hU(MCrPE&RYW&CY!vyL!rB zPsRlLS&*d@xT>o@^=YNyBc0WMjeOXn>b=bQRHAN@MNqR_nrG31_2)ru!YYC^6rb+n zA$j_4DYLr_6Tx61B0K(;y&Ts~&0wVojB@Tk{l^l+(1c>MbgoK{H85LOP8?*ooCQw<^*Z{i2AITmZv zp7=P557%o$NaG(TC{7(52R6H3WA#}opi(P8&#B^)wLu40dA7zJGHr*iKeeui*F6eK zz(yh0FHzFk%VpdL$_@}2#ILo5zo_Am3jqAl+IscM7quL_JifUJ$r2`lEkYWLlRPpv z6vt~`+-F1+YDl{{da6(NRRORf?gAbL-g<2oG+$o>;Gk_gPVD+}eru>6A3j3pCFx6x ziQX#H=i%)fhxwhGzr!GavYPH@^L+?u*6Peyg)gUY0I^V1GByhszC!LVf&ln3z_)pm zA7QhTJ1ZfJu1^E+KN8HrGjE&w@D?a-H~QcEV&K4`Dc3nzJW?g&<0*AfvSh%h-}uO; z%EZ)6jC7J{K`#MxQX$C}6u5WfS+k~+iL=IS&7xyS-T??Hq~5IebhcH`U9SxERDUk? z5Z}bSt5V&=VzMi_(B}O8E!-(ClA@WYe&A7%TVk#%dBxeIp2wN+XcF>TH2j6vB>kmO z`#t^d7TDO*Yol%o%z>>55AD__S1kM?&v3n3yhjON{LT_}5pe>l%Rg;V$O*Cz~%27oR$2z(O zR#seH$v#){FrPd%u=&{2uG^w5@3EYmbTXeA^v)17s)reEp`uN;?A4?08qA%xZPH09 zhWP-0#J~KCiZjAXgpu)NT3)3949dDZwEQHl&t@E&6;Db~hvW|(r0`1E*uZOk7b=73 ziVL@Fy@tSts{ly}eiRA6W!Zh66T|d4_b?KNhjG1r7;X6$pp??{(er86c;&s1cRsRM z?w06u-e>usn(jqZ>$&WG*UzQ;znrYLwF(-mGws#KWYv>JTv0ueyd#I``TC+8l3{F1 z9QY?kIz*KkAhzh^V9h1KsI;TU8=`n5WRssCWyl*cn1f%gF3N&VWjX0fs&$h0fKHR;`Ufo>=LM`g}VN+`^vrbOUG|pA5gRz;WUXz$3REMv~omO zM#J<^wa%g_V85K5-Vt|*W57XgOdbp`?J=d?GYj@Hk-7nzJWeYtKHS$0dt2YpF4e>k z)~Ml|Ov8CVk=(XZb+0a0E@=rXNZ%;1X+{DwHNBQ=1$+`Onm3I@7HzV9HVBb+LafFg zs&@NsW$&d-HRA3VIIk$^kGHKl)w?f2&3iLsG>K`OekLQLClP`28W|IkqMltUYge@C z=G+0q4snT@&dc#iWF1ZvL=q;#9OmA%5Hox9@Y{xE2`k5T2F1=_zg;v9VZbtBm9EZe zdT%@;Bt$b$69fxqLl zBl~>a$L^!dg3~s^-lgR^V4t-BD>cypScpdnM%RATz)YrK*6iPLsyhgzJy@Let9C(| znf?%C{|3c{hKB_U+6cv+^v7KD9QetCbS5volgXrqnmY(oR$peqN%L-hH%Zf*#`6*Y z;cPY9`WGz&3cNbHUT`%{TNS!qxuVL7Utq9ZQy*l%v*XhJU*Ci(`=WeX`;ok9uw?L$ zrt{rG0@Il5{}_sm4-TuIrvy4oJi;Uin3|i-A8j@77mlzg{9>HvXxj9eQ>W#;c zeQxoPn^Uf5YMGAWTFQmOg}%&E$$%qeEuNTg z`%S@+01*3x3Ci+E9Jdl6pR%*xw-qq;oVQVhhk02^R;>^44R4HTuE|fJ*oD52${X(O zsNbop45D4%wS|_LK{L$lf0?a#U;SA`hsq$`kawa^a~%W%|IBgv^&nz+TB;R(lEdg|!Dc(YOS-U1#1#nyB_=}58q5BZ6LF@)F=MVLVIhJeYK zq~{6l4ulyr4bh_acyq!D6F$d(knNkRn&H3N_qYN?W2$x6BI$cTO|rqVoeQ-S;`I*R zUDohXD2{p@QoTaSc4?=8B9rX9^Xx|6&iW;K_8BMuqQ$10j8d(#)~uUgW#D8RJOzv7LRq~G3Fn)qx@+$zG_d4!>*Q4xY`oYRR_`3scQ zDmql5;s8ITNOnfJDm zk?BHz)C8nrdd5s=P2Mf9U5qggzk9_7$a^0#aRvgKmJ6;AskCHGHg(1Y@#C8Zzu=Q5 zi}d@9&0BBbVaRK1jAtw`zyenLZu|eBr^;k3rbJThoPnGVc8On!zSR7-{S*^Ojy`$7 z_r$M9A3Rd*_@FI3v1;+dO>xz|QeTvI_txENE3Vc4zR&ve@5TDYN4yUZs&5G{x8ADI zm_IK&KdVGA^u8X8^x?FWHu0xKD2JQ(qI=N!r8uf_)+Jn~#h&lpDWF%|6oR@+`_q2T z;n^*!zG=SA=g?1?Hc$9Gv(dH?yPs2ddWv1u=^BL_X93h4ZL$@A0Tcn>rT5czAFKqr zWOv;;c@E;4{q0?tHP*s3edSNv{jhkRS&-h_-2Fd=P45kLY%@~pul}^%zDpNCr7OLf zeoi^|sNK+|9_rou({@94TVva-xWh4)Jm^7J6XfDlI{C?vHD;)tk zlORo7OvQ}YRZ6uN@pHux`Ir6a9zg=5z-+2e4(=6|y{ii_pt{O+qvJVt;>qjzCt5<(?ZqO%vdFrlj9GL>D-_7BLegR!N4D-`z|kGFL)|VnED)x zMCGj2dH#FMYo&)0GvS&vhBo5aK^Rn+aBsrSl_$L7UU^CZ`Kqiv_Jb58{!i<-U*tz`Y*R(w(_JZ+3A2dYirlQX;*ZtMxk<2plIC_GAJ8npmM3&?Ky(^wGYgjbDrEWPI6TF? zOoA~EU-pYRBrfsZ(?1)VWbI~+bu~Rc9oP7O>xCKx%$>G0=Ir?9Zr}$7I<`hDx6ED!=H2%=z2V`g0@MH zKQBD72~a}sE-jhc{h5uY<6?~kS-Q`e{yCnge30^$l#8o;Ps$aKT)WCmh}=%f5sw_! z$+4>(pv%1wxvM4jC*@AFoc@q=JpWcA>%8GgjqkAlUn#g4ITa$OLgZA4oC=XsA#y52 zPKC&+5IGehr$XdZh@1+MQz3FHL{5dssgQpw6(XlUzJ__pqqF28X!1Bac`%_oVp1Oa zDi83LM={GowdL{X@}PTpW`R6?;$NN!16LbE|MJUf=ly$sKW;5giuv~>#RMQrF9Hcw zZ9XxWsos_N2qpKKdSG8Nq~LL7P?QX~IqZdd@-Hz)OWHyw1{#g{d1ro}g?0B(S+t=~ z@Qa^UWOiE(hMWL0TN`TzQ)fCk_n~lc_02Q# zp(@B%^{ZgX1^DYc{J2-Gua!lC(?lsAnQKEoX;TE5y*8A{IXfHJQK2z}!41d1XI-|b z#T3dW=ooX-c=r>i1uSHzv+QKdvyVHd?&6bv6h34U<7n)8UQ3Fq!I zeO=N~ifq65#1TD}U<$d8AZnTMYwwNdG9oPgZb)Y$&S$%!k1>urReo3ZeR(DaaN;9d*-UU%6e%2KnqLt00Jg#P|c*9b%&~X znDeJ>W7*}#y)0=Zl~vjX4Uu_4Cr6GEZ1g6SGh|JFrWdS4T403j(uNn(ShbJoE#wzL zllN+LX=wor4?Za%oK<^q3_%t*^+Og?4w1RF|G=iGF!B>$rELSDe(OKICDl7;eKHk3 zP#GUDZ47=&>KrJE}8^Dz)7AFjxcpGhrl*c!(#mB?qF$eK8(hkfM5%GZsW)>$u^e zq3lLY`ca%|p1@Y!5z^`Ij;dS0h}Fu|su-}MVMogwvp2pq<$vC2*%meY2QM*;Vit%- z$m(|FNu}2Pm$Kg={x2o-A~s!Z=Aw1+>_r;p*xY+MlU;QpUc{YqNhboH1{)< zZTaYuDW9m$0xISc1rWQ>51D;`O*Z5^7?oviGM~Ec_t%~6Gd3RYWQ|27ye56iB!51s zpbiyD1}Rgtx;#So=*Q%^i~*00Z6CWD&3BJS+Cz&aoF~jbr3C&yDk_{SC1^`e(aX&p zGFm1Rae{hG$U{7)^NNN@)zIK2L4$WzQ0o-wJ?W#q<8rm3l0`7jekphe!mX-87;vLQ zM#6F4Z8WADd$gZ5KBaz4KudE$O*M3@7#gCB*fp=8eA3qhi3>4--dy76&JmW??V_DckrKTG2l-~8>XOMg!}xSHFoFg{9y~T zr@q`YIW5HP*yY2PQONht{BC{KeI=I_dZCfS4HD8Ar>9uiKEIS!k_6Nmgu&81`lhb% z0x#Y>wWES77;Jhg{pE0Mw|9ZVxM>h)GWJORP7hIAoy?!auS(*zQUv7Cu(mo2k$TvrX=mX5J8TwgWcnSmcPh-$Bu6||3!JHf z?Rfw=@hkI{D?R3nCZ4iN!77DhfV75+fq>8?!TZ26(bO@GEhyr7s#j zDGdss5xg3}9)Kf9CPh>!Djaszw3TB}Pl@jAEcfMxZ2Lo-?vGW<=DIW&a$H3(i@I5A z_8A<`WX?HLEBIu8w;*LHtP zmB~r;Wtfqk%f?xL?-o|+(Gb#`z?E@If+Nm2NjJNEd67t0HrZ$RTW}$JwMo;PDM$em zZtB1~|K0bAF*JI+Fa_X-x)yPLwv-ne8+C{n ze%h&1oC*P(m-e=#r1l5-n#2?qOfoD@frxK(E z-IbgdA1>o4Q%wyWj!%jUeMIYDAhex!jx{|H&QF5A%%;6y-3eU^Pj8EAA1S5}QkX(2 zGuAdNP3TP6JT}suC4lmi!2)nm1<|xMSmybzHtyy~a|>NfTl}0+SBg1Z;xklJ3bvzv z%qJy_?oBE9Mj}3&W3_oX`RxZYjLqUZSo2)Pja{3RSoY1=a-*8Ml>NG@o8309?eFN& zx|f}p4tst#Cb-MKZ2)(F}4)|22TtnB&NMENPv-jSrB!4<}=2n9xzAx{=8R zu!V%Ark3dviQiDkp~WHL7%49U^!gwmzPW1*$**IT4TCI2qK-$#rivx6{|>abchAwJ zJ-RX@zKfPQ*#b&wux#fy9P4KpqoyX~v+eB+6XCU6y@6YHM`W-PRCg`dmRhVB5pr|1 zuRT{a%xdCehcnG(?rl>s#{qA7;Pk}T;>Ft+w0c(qFd@>SrK?3Y#o4siXhU`K6RkP5 z)i3-A_sh~D!_6KRqfDhU6mdDm{^dvVc^*NDk6(~%Z?+v*Mpj>no4oisLf>r8We73m zhsq>3c|})Sz7#cGrW257E!s#5D@>qB>SJDaU?wO24yzmWKnGKcbHp|?rCX*S#-{5_ z;e$7RpX{$%`I|HGN@w_t+u5T@GpOK)2YDH;e|H(K?;hpcvOoVbtE&k;3QI!p;6-h+ QUx2^;`|S4S@Aka-UsT4YvH$=8 literal 0 HcmV?d00001 diff --git a/pic/springblade-consul-nodes2.png b/pic/springblade-consul-nodes2.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc105e016151cb9e69a71d5a416a6a07d40ed03 GIT binary patch literal 45919 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 literal 0 HcmV?d00001 diff --git a/pic/springblade-harbor.png b/pic/springblade-harbor.png new file mode 100644 index 0000000000000000000000000000000000000000..5611bb49c7c787cc33ebe9d35b809e4b0f773d6b GIT binary patch literal 57542 zcmdSBXH=726E>;{q9BM$QM&rjAt(wcND~DGDbfQ0lrFsn=}kaIiqb(K^cs2(MNnEo zZ=r?W6N*TOz<2Y!?|atzB&>CQp7TT2lH}g^?3vlu%v>{@Ps)n26lC;d=gys@c=_U) z%DHo-w&%`W_;iT~_>E!vKYi!Uv7USROiJzjc^u|)gxWyu4&MAZwIwliHz#Wd1-IX$ zXCI}STpDkuG~e$Ezv%==|C&@-4NmE*{=A=e^V7?5-jVWQmdS-Q_O7h%! zVuC-+tgY{xb!LU(e;d!E_#ebZt?7FvqpYcJd!Hk^#7gK#7)@3#YQ8mA1h0=mo5YGV zA^9eRM)blgQplyJ9DdO|PZ!M)TwgjC`!xj@eOtkbj1ol}2%!7`)$D;*!Z zyYyK)zeFs=?EaReJDN*Kc|0%QdUT&ztYXaIPlvX!1gUD&wEfCHg#ruwxVWl{+VB3w zGwk3k`Iab(%QUX+Wz~>mm3~2@j!oI~w-20a)C-s~166h_)gf1W#ok}h)LNX+WF|J3y?9hUv0tf}b; zgUCak@SL#&WfT!Hvg~mA5AF;DONtU-iWv2Iu6o8UU{NHOA}sa>7KX18c5ol)B}WTc zowzfsHb=Z~RkAgC_6FrEEA; z5I{i>W8q#@!S?Y9DnAee8CBIMY<7Hm7!+~?Ui8UVry*TX-b?E8(c{3Cg7@ag3rb4} zPfobXQ>WG43y|)lBUw%pe_ak`kc>~=5?$qDWdYyOo5&-c;6&?WqrJF;u-R^Mde0LQqZAihwDw?3HR6&-m>qMM^a z@~?aY{qzep**got9s@t{g)VS*8-1*buD^7^TDj*>Q|GSTzeOdo9I z(%Tj|=CTxfH^4pphaGeb8ZQcZjGvxqrX8v??2vO0*w|4L-(=8d*!$Cxcz`E&z>{Pj z*s7 zQ>6~Wjr7CN4rtIM!kr~k6Ahhm=y9#OU&cPXFs7YEMegN(ADEE>3s1&wO**f zQg^=Zzf-T(4{2fc`x=xmqElhP7xH&k+9dFb*x>IM%7rEu8c6~y>*3-qT}K;y<*DNj z)eFYJ3{i#*&v^VE4nJ=OaZzqe!;Bp{2Y#6}xZ#FuWm#Bl&FGCsOG6~er+r=b zm1IM@xPwv)*xh4I*J-F}5d&2T$^Hlq%?_RE+fi*ck{ErJ$-z=)^AiBDNZyI(sP|jjuDtLISJYFVu=iOZ8`)tbUqqC2QF}=HHznXq>%w> z5Io+S6W&ZMp;Mlg+}rW;crF?dN$E8+`5L6UI#7HI9Qs>=2W_@fG@6+wzals2eDbeM zA91AWksk*ITKOjAPP!KPR%_yAr(cULo!^={DW9Wg$tTtgx6NCfmd@ z%_Q5A`kg`YVvgh%_hDK?iAUR`T+hmdJjDoP5U@K$`&q(Pg?-GkQ4ZqqPLCH>a3R%E z1tte|X?A5Q^ZxP^Xg!mJv^5X_?4oP=+iE7S&x*$yM<=Wl z&j&kf54*0|2xoM~e%W75!5~R7UtOj|hYv_4oJ@oi#v^2pr!%7|cDoq5YSzEC2vc5X zDvan-kvCi_m>kzB;$FLfT@gS}P-Yj5Ix^w}xB2-L%6%maO9h6SaKa&cUS)6BVV)jB zxu~O#serEf?m$l=kJ8Q+3(p-qd+n#J!|9Z!>RfgX=E`W0`XJ)?i;K;$_rYp)I8+QF zU+Yp8e&1K>p#VdQ!WW{yGll^kn9@++(PQ}WS8xG$LBF^$&DhL$0TUL@HPFteM;Me1 z;WZ8i?bnF2p;k3AJvBve_HR8x6Iz>EdJy@|Tfr+?rf8RLw9-M48)pI=e&$o)#8KvO z!zY#^4^f25vG@@X(Gnez$s-W#5xi#Om4C{!E$q2*b{jaZ*qDegYa& zT=VWjdXP@>%;0BzUcE=2#~13O+ZHE-ZtO5uZS8C7xhHSwZ7=96dan4&?j+h8%t!MT zIkkIxS|CZtIn^*0wnrtro6Y-UhYG_Mw|^ca7uHJ;FXMj=v)qg0KX5igC0XyfPko~S z5e<4RlTt7p272*2@;Ofw9oNT+f3IB>qr0}>Q-DfCYYxjkv2!V>YI&RS# zGP(_QDKeOQjlgM57|L&vUHp`gAa^Ra%Mv+n927;)v-44`0xcFni70GdPO<-b)#7Cl z1BcL_QzS?LI^p*c-#--TckyyGS;+B2)8wZ{#z^xFUr=8dJ3??`e>Ts?-RgsYvD=40 z(@q{+x8mxtoiS8?YB|I5#GFMzk+_RZU|p>v<$90}uLf}*V&{pdX;;Gj0e^bqor^P$Q)j{DXDq>x>of z)gnB|il>rWThgnj{Ev6=F&QiR&AuBq9ufLfNWg+P=o24Zx$o+{TsS;>f?X@r*9L!y z8#6cNEQGi3^*Y?|(()or4<#PJ2(lDZK(wOw$!|uBdQ~3vX^w+4RAZbM`{ZTUEhjRg zf%AcBu>o1+O_0cpe5PId5#&JmqO{oe zcD$DqIg)nRj|vJItB{gl%<3)LAVyx6CY`2_5vuJ(0dgC2)Z(jX}v6N9EefQy-yd`P0%*4cz z=1jh*W$sVAalJZ~Xit6%>GP*5-bxK*{Kp_5bOrs7oO(Q#Bl zT4ZCpRN-h$(%|wyA3K-X>>^vP=R&?CF1p~GT9VXYV(KxwqEdcw1e3M$v!i49E|(F= z%UMKroMcfypGDkUNwi;Usu;?-urhFqLZn$|UlQDvv8(m2m~12&2SS%8+V$L0(p!w- zSiZ5R@yeM6ruinx$8W9GsLn9BUiiJ4Nt2D!xPKk9*Gl9AXVKZkz6YTaMmzkm#XH@h z(HLf#c4*R5Qj*P(>{K<-6DTf%^oWt+7S?Fr?f|zvBbxLg=10m~AS>8j&Bv(JMmnL8 zIafheA7*_i3%cteTHUU*{wxnUoM%C&+@wFxyOZrv4x5ofQL)f>a9v)p7EVQWy1L{V zHJgQ|jpZS|QC)*EZ?Q45$Qh4pls2MM(V3`G9XraTgWJiGwcv!+0yTgnrCNx7+0vNF zB%wyJ;>KP zWe+0YVcnG;70mi&hocCE7<=1hV169A&eur+S{?oA#l`toiGIX!Xw^|rGY z+zNKLk9ab89gX=s2eHt%~_8y5F|TMT$2As#Y4TdlLfgcO45_yr~ZF+ui_Xy(Yo z(|0j>dFxS=w5YOxSxudfatwHCX%E)!FP8erG9ixjklBZa+*)w*kos~oNMus$c=ND( z3W2z|`q0S3HL=(P)7v?Bd(;N&#i@T!F&!kzrabu5eTVMq;if2uMPPA=TKP(wS7OO} zR*!VWQq{nkUJRC5i)4V)to-Vns@qmv?K*}8&eEqT5*H|QSiSbyroz*9qQypE$gnB+ zldPW6xJ%9fkYGRA4`ocmXF8 z!MWFCq9KlB=uM@|n-k_UfhW1C62iq+lYMssk9`gJw@LQYqn#md)XQ&a@r2#oQq zc~r?Ti`vU_l|mClh4=6S z7F*8xuDQMG+mF_cB3Ggw=D)7Pi6i-Mevm(9sx0Vv|8pa&t_?k;x-MPeB8pP)GK6^b zC9DDx<$o8|Are|85+CV-)2_dI-iH3}kXQZe!W^aYkjC^=B7HiFg@h(H^eQ5_Krf%& zW(O(M-8}2ivc|tKaWuE)Q<%by@8(O$aUY)|UHrM<&yLnGuGJbzbMIdaxG(Ljq4&h0 z0bv+OVHXM=sP(Ge$E6;x^h-NcK{1&Hbrq1L#yRWs1vlOKO8Fpg2MF(GYQJF6^o4QT z%Gz_mPw*`pnv1rZR28&Cd5wQc&MC(Jcw7g|KQZo6pUnn78ln)lPSSPa4Jg0IVT6== zh!dHImtNHPC?2AMxhu2syK{rxi=kL_WZEA+{+hUEEnjr0*Qvi=>()>~#WFhY;MdyR z#U6(xei-CcUPb1uKjXzqhf=tj`8VcG-LCQ~SKuL4NFi2|Q~G>S;w>{HVfH>soH?^oEHz(W z;jSuQKuy_ek8-UFV97t;boNS!hHM97#XRy90hNjP&!^6dEpWm+4U+vI!D(617oX4s+)OUG`fe5U#Mte+~>dM zeBbz?+M`n>xMIa3`a*v; zhEgqFIp6eaB+?xjGX<2VyDdqU-RTF1VhPU4dElgLnKQ1K*qaIWMGfyvl2dUW&_^IX zdZ)~?Dy-hQ+H81=f0l%kE#kuS-Qu|$}NPs)Y4>gtUrebKQ33TlZhZ)wk13${%BnIb~s zXtreI$sa)PoL$e_eF<;k5-SytvL$S+5}F_|#~*J<$`76!*LdKWP(zl5xw+f{J(z`Pk9Zl2{UbOfPS~%gd45pN8IUZ6o*_*CM?l)(n(im; zgr8?s&I7(sjGh_ujWhJYsR4XJOKSfv!3N7YB0<3Dkh}a3Lr+s> z|1lyp5AcONR{Uw``}d7L^w(IG^S{!?wLCjR#LqOW${>xfqqBS>7;qYND|v?@;cmh? zq9!sbPCA|!UT63WOa?go7PJ2OAuW&+laA@8AS-x7`he;gt&7jV>oh+kyfh@HW>Jc{ z_x9*;Z&lCsR-X?y;q^HS01LR(#_|Pv2Zi$2tT)btO6V#0q8Jmh2zPaSiUE0}Bjei) zNO;A?v3Vu^td(C@o)V}FPfQY_57_5$zI{lB^<$_XN=TvVEV+SIH6!ZhIj&C6Ocu|( zoFn)>R^1bza}_hU73}EfI8r5zKH@_X*1R&<$2u}0ao7R^b6y({l{nh{#F5BJ$^>JC z3_hX^CFrt}BY>{^wmhT!b|^uI0w}OtqvP8fKR~=2D+Ye zU~C6&_sE$OMC&XvpX!W^j2tb_pl7U7u(~?&DeK2J;Ey=cmYhxgGG+@}U7c=$5pQ~e zr-GXez%{wH2R3xq-v4fhU1Jj8-t=T(k+rj>Vj+#*9x7_Ed)jTu#6>WYD02Y@IeB=1 zoY(8^{N$}9g~#|Xma>ethPz-9OA^749bf%IAOtNDrU*RiSO?1E#t@M&IC`0_{7T;q z9{%4f!0)@lkO2;tWGQzX2g>uY3)L#&Rj&J32hs5>wy6MthUv!c28w@Y*fc3*Yvl!h zdRxKfsO`XF;{mrQ2g zn*r_LS2gRy-whf6yyX|JZBH;>`Q)?x_)4dX-I{%eybF7^m-9+SC$hj(mQ;Vt%{I}G z-+->kWLAron-KQ)@&eI%UNf*PT?fXdp?B2yJ&;~DX?)vZ&!DUF5_7;^ej+Lm!3X() z2anJnX)?6m1p3J)t@3q;e$zF=nUC!ZQ4M1it`R)YYQWhO7S43_;idEeAjUPo{yesb z-LsA{0PRVBNeKU6gq{-_K@w9%rfyW4ZSyVDS*C>s zQkM47fQx55e~xJ7I;S1%iSyn_e27IM4P-y?xdx~(ER62pev$sRtm5LTaO#&ck_Xmq zJ)i5ONRRSm=px9&>RNTFeg0Fb^ExWHH7U?M>+mgFAc znE_+EtixN#&tLci%Zc9E4|}oQyG;NiPs9k5Wj&^xesZC-7Gs*rM~UB($Wx34B%ZX< z+D1hQBJ2)zNJ3scAZRZ@$vy_ea*Ui3uG=r*Cad*>%LiEno6GCS!`(+hqT39+CBKBW z8I%c!RlqBOVTm@Pxq&42BjkojORa`?Z& z(r4pR1n!Ele=9$~&gj_po~vxF`%}mq$31(O#6U1rR@je5o&e{a`T+f+Lhs1MRJ?CN zA2SNghf{5RHMLyr+$Et@=VZ%5;Do@oiRH?r!ERw!G3hp&F+r3#1<6@2s2gY z^XX-Gt+lAz%N7H!VQkEHr)u`lloYFr_EUzMuM*vVZWbz)Pi=m}AQqORUPnE#bA1Fs zy^3xB@Q%ULS>?SFy2xYfN$mF#gyZadYOEIn!+F#brn6U30ZIJTqHGH*)I$G%Ip zbtbsx=y}ULYs`9e$pKxc5$>Sx?I4J_Dt)ZZf5PObv_B;=)omxrkEL zR;=Paru6c#o^yqm0$4S>eCkJevYkcds~C1uTD|+=Ov8UNnyh_-tYgNY>@Tsrl>q=P>DPs%&VVVPnQHD|%JCehS9ulAYK!kI~hWr7?Tx-PWmF=Nf zTv6wZj9*MsHQ7_$4jd21Y^Cq@WsF7;L@=|v%D$4|q^2FOqmA-l*H(~+?qki`vM;od zSByq2JtjGA0|BtdQ9;Pg>t->w*7nud;;C2elw+>!0TtEjuposBp@2S-NEg?TyFx-` z1G2v{3HbH8%L~?IX?R3DlI=yrLPvbXyC($?4Sro(%Ymf?khwm$*r22yWrKcgfVjwJ zoF{-Il9xM`FJANcOstY5L?;*$gFayZzE5)lxnk0$n1tx%a{#Q8tk_Y19st8 z`28B_*Oc@MjgJr8eg#yS({?!EqpGp`+JGa8=sIeZy)J->Yu{k{Oej_Hk%VoSa*~oy zU-!x9UmtpRw|L=o>1-uKBfs;iJ>`dR&uFW0`{rUraNtigXT5;-%tSgNcn*_?5zFe$(#N?H zQ+>Sg9#{H_ujTctQ7X5*jc$ttn@8)Vt9(||)wv)Bo{BMhhOcx>H@`3lSZ(uM6}#s) zX+K)c=;u^Aa$V2AgkCy2U%B;tkxM>9cR(<$Hcz>xdosVs9}cDurHFLB(w_k zZc}CO+tv_$Iu=uUO3Q;`54|6Z=-dP+4!rgF)j%vYh0T5Ipp6s;b_u8z*EcK_#M%3# z)rDqWCayHQ@M4vS_5~*t1I0nGRook++)P4cYZ&W~Tgc0g#-6ekND38qV9cgy!b>uB z9v<2vUs^HnY4_U)*pDIybAxNO`9-(?yj1nfQso!uWqO_Yglhi>20HdX_14kD$0Ax7{EcDO|r>K&G_gVqy%+6~m-rnI_{k`$!OB z2M4mH^OvG8mCC~2A|F~2Yh;Y!ONAIBX^x>2yH&0?eEYry>WLcrX0&>K8()93Q#g&W zEC^sZx;NT*to^>}7Xxis`;E?id*5Pv!?HwM>rszxk+&||Sha?IZP&6_8UC-XL`^9% zav_WcyG-%+X)fiBR%GRCMOI_1gUvJsIyoxAD^VS*nj@GYU#CyC@`UPKNnc4_2M32n zE9=|JG(<@r+u$m6_PX=*X8Q-+_$+RID(abVaXmGDT6d+$5c&;!xtPVyVMxzUOrr>U-Db&;SH)gA#x>$<)9mGV&#v^0_jnC$r7C=C8B&l#YLO>aG0rHT2zBNdo@Bs-y@43Xv>Z5WIsSoV4*ci3H zh27a6wGkbgpEo&sZ`A>kTo>l}D#kXvFHkOG5IbLGnU@@0w{gRQG4II;W@aaD2)u^H z>+rW>s2Fs;fpo%o!b1_dyFO)_2pn1!w%wFeIUvj>g}|>ol|uzVd)u`omN_Ry6j=x!Ri|CTJ?T z<@fVoA^y(%aOiD|ZS;~!1-&kZ}ov6;ue03n8IE`_7sywL(ORn%d2gZ3$K{)Jh&V3s8LL1qRvBfYnYmiM|F@c z);?3@!F!MoD`oktaMlh2@dF(SlqM5wzhJ6y=KOcD^?LXw$Dk1^R_$P5BLpsJP)`IMry;VPyH!co8d}Qh%@%kE1cq zVlO|o*9)Y%oy4=3ukh^e2AWR}6(Hzg6P-Suf?(4YvG&A{QYtv}F`g6_c1-~9dLT<t~JF`T&fi$xa>8ZW;wlJArgYIDAW^| z$@E3EZ>5lK)xnia4cRp>rtYB%BX{qfDuY@5|MkmloXhT1AoeyX1-)9iEQNsaHgB{- z;wMNWmJtH_j`~H?uy0L~XG!9W(w(R8Fxh0-y}LX2l-2~hl;)dM*TimpR8s_wpMbR% zOL%S=_#&W7p~|xcBLf&(s+DxMy<8P=@Cw3WP55Joa=f675u}PSWmhWrw|4S+GDIHT z1Aiviuv;aQ%KR6K`pEqYHXFCb=BH<+An|SC9I^~0!jEG^5DB*@uj|pR$^3+LEL!jF z6{zQUDBD!1wF+wIgNjn$eHU=w+takqh_Xeqq+PKH$^WJA?WMVOWPEGTM75HQg!~c+ zUc@t`3m-;G#djk5zxZEawxaD6nRK9|n>>pWB*Pm)IuN^8fBhukMNvHaAd71)wX8d6fKSCC&WK`hKtt+d^8J6B^ za)fJ8wsy%ENCtQ3{sB>RM_eDA=hy2vL@ky)vpC#dUZo!*Iy~;S!aAJ zugLoijM>5U!OAQ5=@0i*cY6{e!x6ifAbwF6VJAnu<7;`rWcj$RRqY&hk&hF3D#m=3 zcgX*62&NDd*VhULnPW99)15v6^@ZH)XVK3n{*DxFCz6FPOoE7XRem&;f#{%DZxUD1 z;x2|3nB+%WOomdG@~-zLRqXbVeJ^#5uWIF|KLnR9Fn8!`x6@foWD_+QSl;S+2{$f$ zWATn6k6nxe&NtN~Vv~@tW1ay<{CRTg*8lBLu#A(g&hp&+TT#s)B)?o1Y-0;N_|s}f zcC+oqL6KIInIDSm-dX}qf-`vLxh}(U-^Wj3-DspOgpbG_{Z~~p!KqtN4Jj$ z_|Wai#L=(0yg2JqEwbZaLHaX06mgO3y(Dj=e8DOvf^jJ1YQFiQ9<<^^?q^EllB`LS z9XeX8q;K>$;IXiI4*Fo-3`ddYVXhOM?~MR`OMC-`OZJnT-jB*d=jwYvo(CVUK}tRo zw;YkFhp>A~1s6Yv2Cf4Xy^hPhB69IY!NKy$NGqz+9ER>QfPJ>c>yH|!O z_GK6b`L(=5*Z2!7#;{di7c57<`TW7oH;Sq5N`@`ZCs3P)8A-=YzJt^~W1Yl_CT_oE zU(}G@Vcn^;Br8HvS5;LtecnWmSdI;72I=P{-z5FN{po+rN&Cx|QP_)HggC7K{B9Ru zx9ctv%EAI)!_E_2IzU5#VPdvpZrv< zTmY#Z9>8$s4(cR@k9`G*F3r*`dTu$mjHZ<|1mse_TxcXX`~cJzh0;~pdR&8NHGtK$ zfC`hw^Lz}mPx0mUc;Ny|hx^z5#s@$eNpp=u-eI~RJI06Hv6ClEN6Y54%k9{zp=>jZ-@PFodX*qVxx?R<^^y3 zx}mh_R+Z$pcSZ$to>&A7i(oRfJh^cNCBwUb)v31$5}h*lw9$ZBJ@O>t^I-iBGi zv&LZVsWPOIp|rH-Q5M?x;kA&#O1+-1vLTFnNS*>>Lz#uoP)FSqKELG3yptJ$=R>j7 z1e6FHB(9EJ_HkYAj`RLWsK1J>w z+;GYIfR2F$$yV@uji>Knc+%lNHz&3zTuGvfbbaLzYWfU)`Z0nqT(h0CQ$VqSU1X{cK;N-^w!cqg{h+wK z6!8lDuDHCKN8xC&qE3CX5V#ZTqx_IyISsq%(@TuR4#NA+BOMkx)ukGWzBO>EW?0s4 z4I;mmRWggYa_ZMjf99cn$dNa2M^~a$p)&|Bf6ub*927`i4yjQ#&r4_p4o$CJ1+?9tEC(H+n%;(t+Y-C2K-oJwsnP|D zGn2`4)qJ;taKdiyEhM#wmy~^~Wq_A1L1YnM%F{CbIoW24QSe}XZ5vx`f)wF{3ZwD? zS{=gU?^DbF!AkF0id!jJo13e|;l!hrM#G&x`fxjK`T%|R&a z2V`Yo87f4`2+Yg7{z;Cnv(p9m38G3F*9m2A3fX;E%&4Af)Sck`HqWI?nbO|K>C51d z8IUA;u39?7!?4zt-FdiCw)mdaq80cp|2rh5ZMCh}7SEtB5;%ZmA6Hif@z0dN@9j0f_M*J}Q3F1e3dBj5tY16LUz6&4k}7Oa|X z{LroOJAZWYp8I7VOV`wSwBV%kPROdO|(^u-D`lP4JexmBz;3*Q{OLpV>t@ z7<)A@>Y8)kIf>F=T?m63J&6iU&pgSi0dsjER(ialX9dnLF*1R#efRY71}@s_0VF_m zbu~be2$T&A|8Ew+2Jm(!9rc_$BQ>F6IRjBZu&KHF>H=ZCNy1*7pKIM2bLax*huk(7 zd+NQsXn>>cyjr!e3e>XCL&nq*h*@2wg}}8g0I2lbR@kaT!~}ipTgDds|4JeM``@`6 zl?SVc$PbCG%h{xiw%-29WUp8}ci#?p?I0#r)~)9@#H6cCde1l2ALG~bU6(_}`_)^6Iw!qCmcvO>wxpffo$@M9T{GaZJaX&~`WwJ$OS)vMji3ELd8 zD4^&yV%TdW=RZ8!sV|_YVv{&9SnkgbWGv>IKx^nTl_k5tCkNL7TjCEFBr3MD)_Vf@ zkJe54UL&^fb3yX>eY3r91(diF^|q(lD>E7!o_z|!;0TLxGR>AXf7X*jmrEBdtbzR_v*;MhfnegT>6R!V0|s6 zm_cX}+hx20@C1XHk%(ki*ydttsNy)$VX%$6bl{VSC(0V`dD23-TTYG5jsE0L*)w-b zAB+@K*rzGeWiRECB{(L}@TR;go_7f33S|KD-T&+_dv00r&>b2?6B@ZzBU@j9m~k_5y(rs()4QL;DP3X*TVzETSC$G%wF!A+ks@& z5!))GK6o`@sO|GMk*z!18qc}02piA+@!{HbO=gw4)O*y~*tDQGHpOo43C>fUtKCbC z(t(u0R;sMjKK5ruq8lU-af{)6mJw}ZM^||#cvxaZIYo7zx2tas z)D$14u01JV&;BD@Wyq-EwXyfrxubR_E%~lP)`C#$^3NyA0y{d?i(ouY@by73KyNEg&`i^Q+Ch0g5Q zGu;?Lyu~-*?Yn4*dr>ho~|AHV5B85KU`O`vG?Ww-o>?7wN2b3Ov(oJmd(E0M4z&S>)dmw*H6RNN zM>GdagZN1J{%5~&VZzGVE(o@C)~S!W=N*I9Zf^l9yie5 zR3{WdCR9gZK!R?c-*BrcrdS+#Mj8s`dK(Po^qOIqh!HSGUiDn}Gt~)d_Mb>b9XT#5iD|rIk zy#JS|TnZn1(5>ZboVngfTowir5Rg4n)ZGJ}NK6b)8PprK`gbgLESG#pq8QWD<-$j# zXq{w>uAh@BUps^D9>!aHTB-W$^}cFrv->KS=P=JYkLGe>zOpWkY*6S%-Tb#OQIi9N;%O;bWd zG-t567$nI>!mBz6Yxqr9)W^xC;j!svX{fn$-6$yLhPFNVsk$jg{)bX{xaO+%{%fc4 zI;kg25OyWa90XaAP4yCcdOFaSs1Wy3`nlZtW<@UXiA!-E4|grl^XU}Zfv};{<6h6a zihKByWykcwa*RpERqZ}-I#~}ZqV8Zmb1fk_QQrP@sf4CIm_ytmd}A(JKmXO^p^W;K5!A$={NsvSp+S8t#{PaOXgJN1o%-+0_eC;r#45OX zDp`lP`9`;}7>t>MGE2wTRKexx3`&_27fj6DUVb>E{YtG<2*=O$(GIUedsJ-+SU1}5+L&?JHM&PnOQR)TH=z;C+^U+Pp8mSo#JtJG#5P@c-g z9kp0rcnT_(HnWV?W25mxRmh%gpj|^`FghETa%U@wi$@}uS^D)?Hg#JStCxeCZA?PB zlXve65?y-a!>XW>o{*WRv!YUL)jEjsHRP$(S>?Q9A@ld10MA$?A_A#ugpH6SvL%E9 zL#-#Xr8)D&DM^hB0&~`w&-l>(=j~E)5Qn-a_f84f|3xyp6Pk6aa9hl*2&{f!k_x>4 z*X2q>P>QqtKyG?{{SZGks(5A*7=Wi-)iy2_6a4$o{2O+j0h7t8?ES3DOhlfHkQc*Z zkrTxtiQ(#mMo!aYV1r%Cb&DxM*Y$!H0atkHY)!Z;D@jHoQ|g{>`?g44Zopi%RC=$O z!3I)gZ`_qA#-R|GwpOfDVT}Qrc)deIS*oS#w{qV_x}@q+08s=c=k%p^?&4;kQ%8!R zP#oEjZf+>k#HtFx3J{>Ca-OpC`D~0;IYiRyLx+unX!*43J!?gYHI9XjcV|Lv%*-mW z`H22E{aLTuGCZww-w0Qh*7dXtXT6rKM?|KQ1TXD4J*ZyuG>ngX8hi;zzoqNHY}KNk z*wDFs2mPsDXFaVp$yk!!>zq8UeTu*(aSeC(y}9Tlpv%gwlpx{+5G~wh3-<3y9!pqI z{?e7i311>IC{wCqxYBA&L3ZWly*F*&*Z{VKd!=Ah?j^T^UbSO3bB+r68$ANm0dT7& zjZIl2B(MKuK>p@q`&sCyl`s^ib-p7}OlLy9Y9Y}rN9u9gp+}35O=+)ERBA`c3Y@|} zpRW+VJ&HX)0c4ENi*zSn(gg7+K(7vvFbB#K(&J*Gq&AVU)qtzL9mvH#t&{KqPukYhEA9-znaBMnF-) zmAL@akrTB{Bl*1SkI!~~ z^7V$}Vd$rC>!Twv7?{GnRKbkDo09)4dmJfz)QFLC;gQs%7iUjubAZ^{P?uu)wXnPu zx*EyFL5lRR|HpHXag(fg-V8N#(KF7HB9H1-1ED#Me~G_fqU=i%6pAg7G50?mBGO=; z$VjgG4I~fQSD^TE_o$2oxD(>@*0!q<7p5y;I=m16_E%x@ziqNA`<;k|uK}hC z@zD(+r*(hPgT{KD0Q>xZMCczPE{)pQ%$dyy)<^yo zj;T#14N=s&!8|$-cuJj9p3*8Y5b(g000#3V$|jGzZM#+ zye1sP)Uqc3R~P30VVz%8{Y$YUqgywqT6s?HTU1a`5Z)#1g-^$4oYLvr*#A?)|7UIt z&ENk!-};}31^^%j(WFV7Lj37SUhlwL%H`OM@E+hIqK zisfIJG|E%S2%tnCdveRN0S$nsv8wmPe~yijthy<-e}{@6_7Hq*OuNTodf44hC>F3P zfAE&i7kP3{R?jgeBm`*BbdS$|-yz(bkenm_{3;)~0<+V5-vLcCnHH3PFtTBEdIyqD z7jWbiMm1Q7Rda0&aoo`pIvLd`%=zYWk2gJhlr zN7P{gfLBD?nQ9RK1AFMQw=oyU1l39s_qZ;pQJ^Pg+Q}%$X_euAGE~wIaO50s%`FW5 zKQxa${a2%`>O}h;7D0UFyB#*3;e|PiHnu(V*nFLRopF8qvS!XpGn1A7T&Iap{^2#_ zWYcP`uee@s_Pzj={8;)V0jMJGy~$Ysg!JYwx3qun{+@B$#>HAJUEZS8b?gD6{I~8O z)@&7D#)Aikl&PuA3cR=37Zkz;Gp6TzQe`Fnv_D9vh`6DFJ<6M>C-xGTUu@$04;1xs zO&-_HYur3sHKE88&+3_*Z1B_7um9e;V61*(74=I)qE?OOn9<^iUauR2y1L7#xZipS z-fbt(!#)r#kws|cL$W!60Ikm~3e97-M@Db~#8`pB957^+zitYRwee{yuwQ`isTaJ& zI13}lvr`3+Mh+1g`fsYOR=D~)(fTP^W0R4beSW34_BKMUR#&Ii956bK_{<3wRS_@8#l_iUcy#ap>6>4>Jp#+Jok^V{T)Y0Ai1O?-0%+PLSs@&@eL*q#U`}v;Z{hs%Dzt=xJ z=D6nKx>lU)T)*>o{?0XspvP6}7_rYj9Q&3|mi9E&tp0n>AZ5c$Cu`A1qsjBI%C;6! z`JTfotkjOXx5IMMp<+I4P|IU)dRgOQ!115G#TYJ28`aZ?L3;WsL=Vo=rgf5)m3r{6oA;eB+-SIHSp2KTq45T}k8Sz;yPh)Hs>ukfJ9+Sfy# zRl!+CR*NBU?EzutXa(oN4KVCv$HU%Ad|M`NDdxea^$V=JjwAL^lgzS}Qt=qrTbMCd z`bw!Ojv1G#et1@o<|i_>09`9bFCNUqJ$FVLkp3DA(*2Zt)X|dBRd~HjW@nb)9y3Du zFkbB&E*V5WyjRlvB-bO>W>#?is~_xehPTxJC{j^|_8AN-I_XHxs6`2xrhC*l60rQX z5c+frW$--=agN#*^$Sg-K3jxrvMM*Xw!>CLDOY>GNzH8Z+hN7QG_rN)~i$eo+2f#$@U6USB`r-YVc+3g~+ z(w7C3&n?5OB%2(zfF0F}LaW$IGMwlFn$?K2 z*~r<9xgbz*f}#4V*%V2)?O((^a{UjQB9 zlDq~cbB<`5dZcl{ccGz}5~>1JL%lF!&QkMc0NWOMLZwy(mWE~~k3$o8SF%0J5W#WM zU*Q4Tw#Q=3pl6nanb{`e(veoE2PZgHa`~I<^d$k-QtolIKjqUfba`&YftZB)?CfAX z1?50;r-v)EH2K-I>5CBGbLdD@{@pyFlzXn}!TG1=1sx4&J%^lUqrDp8x^)OCVx@hk zio^PI&1~jHf<0n(opdr8=5D@S)`CO4ul}fhs}g1Ns<|3DV7L-E;8{2-XMvt;Z}pvS z0~r~{3#nb79EfxqOYIlm%SIN0+MgOcQ8z%a?i-6ZPE?9~RW34YiQv|+^A`qrpNTK8 zN<*_XNam%;cegUl6fN^}OjwXxg8QsTF1#W3IffqOX-VyO&_YM{3EfkjH)aBW)@@rO7tlHbzIiZ6$ZOOIfFj&n6^k#cnVv(znhSK4ZwxV_+u3Ue~hD6)$Mq(H_|$0VV|WR-2r2FJb=Ib z$A~K69QXVD_QY3%U4sj#ZBo{iAIkp2BLGJNP7e9=?Z<2GZ~t8m0HE%Po3a`K8YTWE zE@OqWE*%)(a4OS9Fq=#+IciM6kEZ{z+QWU&xiJRdg&_Eof(?z0qkTit6G3zW#(kG{6TX zEu^o*(Y|fozrAh_3vEeZ1uN@n+iP(MU^Cdg(@vfZZnm{f8FnHX)NvPpko|3bSF!pQHOl|`)+zTBusuLAO;7$f9a04oM`UivI zz6Qz=B-nX^eE*?|gy66gEq^NaiRn5Lhw<8aV2w!PUx zG1cHyazj%XtKh^-n*HtN$gymbo{y*mG&nAz#s^Q{xb9Eb|F^yiXkONaz=1FII2eNQ z@bEC*RdEK%96+Z~3p$ux!CIE}<$mv7)#&ZDf=C98o+o~&cBNTK9ubzhsJV#(NTP1M zZ+N6Q>{fm1tkBVBR}Vfzmdn^IyD(t=@cdP-im>Re8yT&-m)Q7NCNh zGJp*I5r$o-Bz*MoVzOaF{Ufy|H*ZJeYA7>q#Z0vqykK$c2*c8YGw-NMAd1fOIhHGCl%|;xs0FcuzcQ_zb6&=Z48>!l8G7X|o2xzO00R4nS5ZqP-mES8`k`4R0 zB=LYV0~pW&iUqYSU#|l?5vTUJo4wUUhwu7>T$VEnf<_B8Z(iYv3{9iaOia8BWfkV7culL+=z#S9`}e~Z)wuDy1z zY6WfdV)fif@f*^eTsUAiv|L&sc#lbv zc5M)+YwDuI!#!u*2f|oq^~(iaKjA~^7GF-ygh{Z50WC^++fL!+TPVBQ)>!+efeUsj z68-BV_vq@&J=~>QmKJL`Y#l5sXT-GIDtG34U*#7T-7uo;5Mmj+hrN4Of5v06OLz!BB0gOwtVTqvZxzZp6&*>d!AO66QViZ-LiD% zD>bqQ%R$SLpS8 zq9J}QGP(Ra*GpBjXN?e{}6{4|rp!bgah+(UPfB14y zOR`)pa!tlZuw7PixzSh)AzwVy}7{z?9m>R*emdg#`ADWT2XuSiH9_hk^Uvz53@ z2bQN6_PyS^`c%vuE9sGs4Hu(I$RUu5EuNo7u@CX_567w@;5P&!j8~Sb%zW)a$2GDS zVY#`~a1H)=zk-|#Z?SolMnkU!)o7y&$m*qC8I>NzA?-f;L_3hqQ#MpIy^F!SN;;6& z=yO=lT|vFO*JUp-_Bpzyy%_PS4v)GV?rv#5vg-KCmSo-C}(TdjfLs1?oXAa#Iek1whOAdOryH7k`b=8VkR#6#oWol;zw2_nK&WzMG zIP;|G-g0;Fmk;_r9e_g8!=iXInf)hX1Ap0-GJ)sZF&tf*tM?}du`_7K8V@aRON{= z$Z0u}c8HA>j&~ZCZ4=dXoPH6eY|fcxfXwA#!7EXHXdx3F$caF_M#feg_ysK9CXn#t zx*no~L?+BZf zf{B-h{RJlargG3wOG57lJtG~p^V$T~%^O}LP?ERU5tCiL%z2qnPVOAc(g$)+|2Tz) zeh&Y#SX>V}?smn|j2SZRXqDvRs=IA@mXlgZ&*dqZr++}A>9Q9QM+X7fGgeRFpT&z) zxesiC_prj0+AhoO^&PaR?Mu?vn3bhs+E23VYBd;#3TJAtWS%Q9%Vysq?k{t+tdOu^ z8U>o=va&K&91Z~imu<80vkWTBWRi;uCJI9QIXCY4ejZnre8an^vCfkxe<{)-?Oj5GC%jN&)^{786>iNm125=7-(H2q zw#^O=4ywos* zflh_dB40L#>h~K>&_q9Miwpk#?&B*ABnk>_eQWoAdGs%LDq|3aq;)#oJo(#cG_1yH zvKUNYPQTv}_wng78)Y(fl(C)gt(Mr$60I7}U*7f0*eVezC}iH9#5noe5NrkpsHqd( z36BLP@ewUZ*&X$#k@&j{X<0lRg9^Wm$tkn|hPb%lmt~J+WiPL7cFFVJB)I71lp-h}y-$__5{>+^0RM zC)I}Ngdx0%Ml2^jSmQPrKW`q*kH3uC&w=jufBFn=xaoi5gT=5h85oM%4P`=4=nojS z3knLO{xLZxKG^sQq@L`0pS;N4R8iHDxmy2+2PrPDu8U=#J-4zD%F9oY^P)#7`4V$l z2=4qWvpa&Wm$OenKvtl&xmn0*Ev~Nr=wQdu!2wmkB1N5bf^C?2iJc}2LC#nrW`Nk> zoa7Xs(GiQDM_CeZ771ai(-m#3f{MaX!VYp_=4~y z(m?p2(RI?YzILKG|FG`X2OEki-%$!`_CwxJYX+NPNRj^6uEvV!=kn9VBnU%lknEnt z4E)_8H9XIm*---hBtmkJXm+i{Lrdgxl{+|=s%C^FMLrghCwh?AoPp&%ay{v=t=S^p z+Tcx50&T{H6g*SB(9L^i=oTBIax}!2(FUv9%3B1 zCkrwgij3ILKa4kb^n`Wf#Ap%LLN&_s6^s}83U_Uc8QoV#ir1zq19QD|Q}oIL#we!@q1L^OfZCV(dbxX5ta{q8`-~!c+c4gJQ|QFn7v@Rl%>8H#GB7jzfMpUNHjf z=U3s6SH}kUYWAv*_ylZMMvakandQb4lu)u$Xo8w?SFjojFl%TpjraNux_3UZV1S49 zyql4{D@4;<1yN-{S31xI64__rzQq zTslk8F|9j2p*5&_-d~e*R(q7nQAYG2GbB(nc7LyOoxPIWZ!jTzuMdwRf>|k8qAGi) zsm~(mbeO18WM)4z4a`{GAw@^T!Go{THN~*EX{PyQNnlf49$cGvl;r28EK9FYoXqgJ zU`^nL=)TA46T)$&=!?@l3lk|GSnA%JS{=SfBs&q zszaCfSUth+lg#wSaKT*H!^L71&C=)b#hD12@hdxnUkUU{=pDVW+1|=rBKEkX>%=E= zXg)CEs4K_RYW<!f^&D`PBFlqc@$e zI>xOjur7KhABeq;l(_LIlOEIkCm6_&60?y}BwS%!SjCf^nvnmnT^Wvezrbk(TUtg= z^$r*fyLQ+ht!}^j15!t1{PLO2Zc7NNZ`P@dKF{E~h-uvyrXk3YssqO|hh;1%BYjmZ zs0=z{6Qbb12ra%Ly2yH9c&5QjiLmu?M{zI)LQTMqf}Z1GD-l5>|GbPnro5Mj_r6dP z1y-U&?fIcIty{RyXBBcPc8`X~Vi18|`pI53wQTFUdpR(rLkbuiGD{VdknWtg+W0Je zJZEEUPsUN?-MmYN({ycsRiv#Ov*c_;ZKLi+8o#z-<=O2`b~mIf->#O{SI0bTMK&Ry z?dJ3$sC)!z-lay}U*JXeMJI5;0l&lgirZ%MCokk>5_c`9yZddh=zs*#4DMc#4LOJ3 zZwPt8z~B>AqutQ(VakdM%=(6>PCUMjH!kx~mj#glte_97DlDzVs#NR$koHb095KJq z*gD@RjNk77k!IH}wVu(6cM#f`pJ%U;#U5vR1y_FF#7rgWzK&BXp{VL2X)~O7^nrxr zy-Xh|$;w?s%cQkCzm|7Swq>dvfn;5^lT~l|A}d3^&-+Bj7xa#`rzWYV%iQ9um?g&- z;iA1F+8i*xGGiCxg%8)J)2Ls>BAAEcwOALYH&~G>zNFszt&VK>rm;DUV3<`L{TGlg z3-EpbI|wn!yI7~mo*moy@F`8?>Vcz;B{9NsT0t{Vr-E-?esl#}cb1;5lDYyOGugn3 z2=d#+#5cYUkz!=<(VZ%DKXBj+rC2F*LTx(y(|-_Il#T^h>PxxYM8 zz1FN@rNM}MDtI9oD1mB#vzY_mE7Guh z_WcCDOsmuO!=tc1;ob+N&5l3aL<_4`_UiJw=Z$qK@H0f$+Hz$=YSMU(4s@42tJdhs zUotm|pp2@W53OtkRt3A9hB-Y6EF%gJU zi9L)T^<*mMXSSNYRIOs$u{dA;pN6ti`CAbZbGQE=+vx+BZKOhDC%X1%X4`c4EY&Fm>B5sD{I-ZlP2#<{4O z?}aZ&f3PW(f|JtSFySY-qGrTPP4VLX7 zDX|_dDJgnKzYkms{dHmCitr>Y=bZneVpA}u#DiuZE}k@TdYoX|B0D(4{xYiHhmiH! zni}>rlQLQWz17A{OL%zrSv;z4wL!pv2?`1ZQH$y%2AyPRg*U}+I+MSay?I&lvQjWm zcn*Poy}e;0iR}?>v!WpBT3cJ2nVCs8QhxP!o5=1#%Pj9VdAN?LM0Cz57{wJ0_Do&p zvpY9Z37Gqj5VAQ*kEMyJYNbku%45dgCvuAb@FcOxx6ykUL2Rd15E1qK{D_IJU(QUp z5sVbExe(!+RW{kY3{8+AaWSDR&Lr9x4SL;9;AW9UKG(ZcQaHL>WeVJc)1bwKiLyZoj`jTxLDqjKfum1YTROzLiGvpFPLMj@j*3y83#61(I}y4EpMB#_TiGuq>xx{?N6NR z>{6{dCXynRzzFqxu!L+K+z!p`Ozq&olo3yXVp%NC8-0eJ&BJY`!nUK-Orrv1ioUbyY9Q z9Y6J$wJ?uEQL6EZjRV^{q2lF6Zz_)3wG>q;aaIx2(%mZ35R4Bw-R&JdKUP__114c( z!|bTYC0VmR|C!@(y9K*g!g=GxRs4Q+wDDq#_@zrKBhK)<^@%}-6R>u{;Vxwc3ZMGn z@T8n05T=N>5?gY$Mq_agyL#@XF8NN?2usIC7i*Wkao+ZNH3!Eoxh|r?f8C-b#!=mM znDuC>?7jfPZDIDHt_s2C!NG~#he%YhC9)O93Ofq0&g4t}Q5I|&c2=xHsOM>0$4 za9pQ)&2MSosy?+P^qyCeMSDWgy!27Ozng@^SzO{)V|w?Pue3c2ChF`gBWEwdDDIm( z*|<3=4{6LBPIv0$3^JG*T%@5X*p*a&y&#iOfVKMF0ivJlelXTMr`ZuX+1RkfMdXKC z*eLQ+xD{-}d}!Tu1~sS!h137j@NlgZ=F$UF^2geg6w*!PYql4uc}S~?e~m2uB%pT$yTV5xZGxlrpZ zC=)QAIfZ95Su~F2?d@)Kmsj!ed4ItS0n6bh1@e3cZY-r-C8m4`n1WsYekh4)Z00*l z!d$;fN~UDDt(pmWWbJaex@vmC;F`h6$04>wm33NX=yqoOX_!d(E(uRsor=oyw1_7L zqOhOAqFHG5r^=#wsK{!C%~C(}Y5+({5ET`JPNb$iC1|vtCiJhy#qW1CxK2hELlFce zW1C%ml_iG@W%T6Od%Vu(=MFt^K(bZt70rI`?#>*aqVjiF#hQiIK&FR%;z2#pMs<9N zZOIy;M&8M>l{%u|!ULvPxEz`z(`SBD;pJ3jXII{MA~cG$Ba zu$HPzY!}$H6W%QS)aKJ@!7ccOM>>^U6kB95TKzfK7`jLoQ>fV@v*^2HB}MLuLi@1?Z@+DZT+ z8X6iOG=7@TcOXnAKSm!= zbdC80Jc8oxqzFMi0oZD89s_biT!V_-%o>x-fMPcVsiyZV5nxa5|oD;fbGhO??Cc*OG z0kL3w#UojjPa2_fW>NsEa=O%=h>ig&Aq>$p&P%@gml^wWq#-Tm7#J+2+SE>baQ^FR zeb$gPB}}fEYES@TWN1hQf;{~v2Ro~)OG`o?hfV<^Iw#mm{~6F#b1@zah#5pdw$gRS z!qU=GQ&ZC+NZeE;771!wh)GC5;?%@$<9AzsTCIXz41bj7T}!W^d^t)Ml|wOA4Xzn$ zzhVb|+nqh_j7c2HUXEYz=?8mfG~OitVhw-d@NRivG9F=9FQ}!670*BFF|oOL!!FI8 zwJyRa#@%SQE6sGJVkMBXNY@uvd+vk%SgA_0EAN>XDRnD73%P}kJ)P;jF{Ipt^}KoS zI@fyM?i-ri#T2nU&4mJf4}QRArSo2>C8!q(puzS|6$eL^Y+m>a)bikA1h82ajZE%o z_1o$mcB&Z9@u~6T7xp3rjsXGbwznr8EgO@_Vn?t5)ng7(fI6Ap7-sAl#LA@?ds;1b z;T#fkEn`5x-l5SZBN+9(s{lUZAH!#bo&OqqrYQga2tJeRd^NasjmR_8gU?x@q2{vbs!4#?MbYONjNCEWq8lrJiuD`?82RqY*!E z8{6^B7xcc#v&Gkg{q+54=xcTqo>RWNOXq9) zr9*G^ks?%C5KJ!<~MX^=K*Ooxw4_3na|e9%=JlgS@xjW{BV zA3#`>!;v3^J$m%meDUSMj%|aOX1B&tN2$U!#h0g;$Cp@&h>J$udHqt^P4@EWfT)fBH2s*QNzzP*$vRp9m+x8JP;<1i4UBD z+Z-R;DH4%9UC{+m_^slDi3U@1TN-U2?0|Li^R+wXr)OQxezr~R*E#gCu#)$z|CG~7 zI`jy-n|0W4$>b4exmRr)B<)?(8oD9nZCh^uQE^@pazb=Q;~AFfFzYy5(+tm0!0vW9 z+vLFe4s$#2r8G6~RL3B^SF143#`^i~S~y&3^qy^x3AcBxO;UbAl1Mbc;urgu4ostB zNm(gJx&wOX4bKAPr0S@vrnmE*F9g6LkSSG%lHinbgh}c(p;J}Z%}X&v*2RX)%lpK3 z$ar|NKY4{b4^{ml9V(&jtjAP|qd(t;==Q^Q3?l;^J9TTFWsNx=_CafiMZ(uhmmD?h zM~k~mVy(9K)a;(v^jRHN#m^aUF|!{N-wcmQ+{stC<$A6D3U2c?UHjT0ma+G~+;HxS zq58S!a+UptWqA(@n}Ys;&|R<+FS)~WpA5a1C403|kBdu)p9=3B3C_+JReGPMkg9iX zxlYj9$|mT(h2Zu>udS5kE**!Xy-KC}2%3!rbW zjFbhAYQna_NpK@0BWbOiC?(X=fN~ivWp9sj0LNk%Yt#b|UgV?VTg7$(QY!rejxT20 z{6jp>Ur(za9E9tWSkAT*O@7(A>=P-_N@Tg9riotha~%KN)>v5qq2~@NkZ=gVDnmI# zGZj66qxak@Ggw95Ya9@idbbuF92#2!R)%SneYCV7ALslEDFYRV5B5I(gS6=seF(Fp z8|)RD;O28U*x6@iW@13y@gVm!kRE{JXz-{-hI@Jn2psDpPJo%x)tJ+D1K7-0vPB?3 zB=CMPE+g3^F|{WtV4icYfT!A8LXplWJ;-|;&rX?H>seNs-Ve&Iwkc#bOpz*L$Q zU+xoN2cTe1p({ z(Je;H`8hc^K$SX~%n*nKjf`eN{=#%~{UjL5gM!AVa~aP)#(r)BA1QNmb#(=T!dzEE zjg7rS@WT{^#l`(SJ<5rZC-TP{z(;GcvWNiL+PE1U)a~h(MNpja!Hpk+>UyYiE1a(Q z8l)XX@vf1#-IvAtS2I1H(>M=cGFy3suc`$wKFg8-K~eDQc+F)~j$WY+pzVp((Y9T+ zcZ@1Ix^FipE}wC_ui(*W8OL=YZig%tXhFrXu%|gSo=*o_`}j;yWq8DW=eFbZ1}Qz) zEMMLM6Lm>r%RxV8?O0LFukK+vz_12+=Z=G3dm^i8No{@%n)X37)hZ_^gm8lDPZmcUWn_G$H-1O(ZMo7o8%n8>+i{Dc1&IjSZFgrnKCZ>Emsg&RWs4SrltsmZ^ z(Dpd zOIYMhChKXQmF=yLt2TU-zpAD&SlrnOzn-l8W1Dr~z0oy*;To$cq3rqzV#lq48A*uMKO$ zO1ICxfBR~}*PN@rte@1;Z!rVAW7_UZu8&Dqs6a+@k#J_``vH{pWyE`|X^=UW%^TZO zRd=Yd7y+An=Oo7>}Z?T0f1s-R}%a(zd*?T*xeZZu2!q#6U;4&|XD^sx=fm8nHO6%6T{ zNg{#FTmUMU;0KwC-T#U{9+kP#R%_q5E!LCP)2V4AEhOJya|iY}LsxSJ5N1FN>^`L7!sB z4rEbpQ9EB9c3+<=C@guCS>s)&kVx^3WhRH-{R_*Ci%aq!vCKp(xVW*F?=7AWMNMil z3dpmmAR=^CBIfPF_o({2s@9Hp$H#1~FN|xvQYZ^ZK!NT9_?@A&bXMEU3Bu&6kFpnt zy9S80_iK6>sE=5d29eon73H_C;-M$rKGhyzes#SR&$#q-=Jhv9phcDtk% zjR*LjX))IorxjGF-uYVAsO{&AZcTiSPOh_3h5O{K4_WC;xFlQ7R2O%B+^CCIIe4De zR-YgfT=rrTi6beUrt6%uJ@30Gb){@>DE@w&ohDN!&*UjywK6FABC(e2PgpbDf5HEMjD*hp)3G%>uYqOGng?Eqa zu@Q?G*wfO^EtLYv1(S9;UHjTM)|&f2VXZUmFaG4Lhj+gKzN*M}*4KJs(W^$5a@LpE z-b~2EU5clFaKe4>VJhy-R>y_EV*t>wKZPSs9KZ3`epxqCk1$8XX9wLq@{5+W^+R_^ zEJrj3&z#vgPZ*@?GZavBVgAeqI-d}7BlCDSYFMAOM>el8Po=%))xQ(d?f22-7>c?b zc+GSFWjxT6ugSpi(^gP64%Pw09K?0bn(t)A^{~+csYNS`i~0EZ_fQyXyk=l3Fc7zA zitN@2G@)70Q&8nlKfr>Xiyjr6roq;NZC;4Vu>SxTKR#rWf)4$QvJR(oZ<|mi zNF6~jDCuc#ZuUBhXTo9*g6in#Xi&4B)lq*^(ZJAUz((SHeSaCGU_LfDu8uA*FPod1 zHmxWcx6E#UAFdpjn0TbBsv2N%g018Cn}BSjSwZ$L`bR8KAAmZlaM{G>5{1BX3tf*r zgB~%Q&8wh9z($V=CdQmg_?x{#_CaY!U)%j_Xp4mBc(v0tWaY$PSQKQ{s%{Npb+zt&nmD%NE<7B{kzW+rtcwCP0GRh9ytI-;&(qR#|(cKPlu_&$q>r^6y$tmp`OU-saQjT%P)n+AeY_TFy|HN6{&i zMI?O#C6TAbA%4J+L31RyToPiq&n5`VU24Un%QScWt_5(I?Hn~&?#QiW*?JipW+c41 z72Tyss>tVgWPzwfcXMvT?pTeDaw3%Mnk1ON&l#;BrUj$c^%az!J?p9~i2ulgd{rYr zxt4hYgjiyxn7^>zy^WfMV2Jt^Q6uChBht^?e}JGLN2)5`be1+xsJ(c({UZqeGDD3!Ox{OtHVdmw9I)OlEz$E6hmxqnG~_gQr< zeNIXtaUgldZkqMAl#q>P@quv1-Z(61q$%|7_Fifhvxm;OZ80Y=i7bw!Hf=K*r^q40 zf)2$KKd*8@?)DCche?j<3ae}vSTnx!~#&D;Jk!QvB zSsCzKt6$Jmd&|!@FjEGJM7;8pShbQ@&EfbjP~wxB6qkw&+se{~SHe8DwHYZrMYcBF zCv`nZs@{cr9#zNd5`SzM*Hqh>KK%sg3j!gcGJ~lyp|S_;)Pk{_+M|_1i@A3=b6byc z+3z|@gd@CO#p2S=R&u(8)nWz}7!Ipqbpli|HxTPc#CGWkxl{bDe4)3NKi#my)9S-7 zwLmzrQr3S;)8G~O<|Rgy!gkv!hzd%d4lw^)hn24@3Tc#ngA-kq-hPB{w*gnaI&4ZK z@2?#-OvF}v+d@fg_o3VP`0iSf!Q(P^n4g^Y(-UOsY7Snv<}U_;KGYaak>?6pWm`!J z&Trge`=FxQVKv=$MT70o(;g7 z4QxWofcHDE9VQD>H``T!GXf^0id*LA#qH2wmB*AqHP)-Y;PmXylw6|^6>E+Kq)>bKPi$4)O7hY(g5AYdi`#kD zGWk4+VQ7JK%kQ*k3Ke5nn@g7A6(8V2G`qP79Qy0n;7N2|M3S-@z4YA3uu`{jBd_aB zL21cX&fg0qtKqIZX48pqerMAQcm9D*7gTCoS@5ZiMfeSI=IK=SGO0_a=fnG7+A!o8KM5Le5?^t=W^s~wi`KOkYmfKX2^(uK1!{@~N; zsZm<*6SN`m#ox3c#l;ko2bqMe>^`TPO7J8&irRl6)IBWN0w3%?#)%4`Nss!+Lga7q zkne@a$7uYOs-ZTAwMwry+wyqsq-7$Fd?>DnQH|94^riJ~z^IR>?DgKzuSIkFS+|%S zjM7wbllC4UP<6^s_odLCQHLP7+@ORhtyr7^hQmmeXO%%P)T!&-5;#aI-loLk$i>ld z=c5c6C8aPp!SdtCTU=0bT=#Bkp7=+}aWX-%`a>X*1lqv+`yAEjRA7q^(k_n{RP`qa z+^^%ck76F}&M7=MG|IexNhkBy#r{J^ZF8do^p4QNwKN>JxTXFAC8D+PnIJ2t?XJC64D=KRT+KMmnK-igov zf!O;|od)iLze%t={x1jr`*49P|29yY%=DGa9ANmm-`r*Hm?=ruT?}9fkAJSJB z83s`fVagOpp&r8k@)rkZA!68A&%H_=b%HiV-S@zm49n|XyqvMP+Ae%lqEf&$>o+h? zhRZu@yQmotjldl3(&t=ceABM?;Kw7k=y$Kl;6&{@?LBlG0_YVHPW)5@Wq zBipieFBPk1^Zg(O^^MzVZsP>#m3(TOAG*IPKV*3v&7d5e>?YL)nh)ZvwdR5K^}LRZ zjt2Q$7}yj*)KGT;NIrMh!*^OGN!WQ>BhsIvB4QJ8Zb0AmdYIS-<`0c^xVQLh*#pJ< z4=Rg{jHjm5qAVCpM=vcdk-oGzujT7X%#@Ue5?PaO{?|p;x<}WCo1*R!_PtE}G+NtQ ztf^KV{C6%rG-bg1jy(HMo%L1~CzlC2i>AZY>(TFC9Dom8h&cb=@X*=BS2JIwi9x@O zaZWih6xE3|y{&#L#+RunAUX6`3S3Boe7f~oz;ci%`H^*@)6XhT1J!HPEByOQUzR%q zn)9gd-Gb_Vt=&lfZ$n_;J9(9v-Kj*`W&`S<@_%8@s34k&SwQfv1^YD9aGUO1f3%(@?>eM-s{;a=J@P@vQO>PB?MC%&wb(X{Hm1|aRyF>Y!TDX-Y z(O9P@?^_OOalm~c>rb1VnTMLLX3gd-$-U~Nr2+!)7cF0TA3Kiejr%)v&c4#RpOG21 z^|{mia`GL{zH;$IjcPT^fn3g-CqL5;?Svqng@KxHRXGdamJsw)XsmR=mpvk9(?;`_ zsJF%}UJF0kS46&{|2#q>uVWfXK7ZFko}EzB=Rd`Yn(0(tE;rE>#^f--`!N3@!YXp9{*(dg9q$v!=&$+xL*uGM56*= zF9a!ww*lFG>kY^CmHdTr>y#dm@%+`Cxz4G~@m)`ej*bOYopkroN0o|S+4db$Lq>Y= z{6vpPii`}kOM0ym_Qt&@)&?AXMGcFo>KdO`0#VSP+6iL~6t^10?mp@|-Jhd6O0Ftv zF?bYq=@eQE?bvf0+vOCqbLnh9!0XO=-tF!GiWuac?SDxOB0c<@7-ZJ(SPas>+`nXX zL#VluegEo8u0tKsDej+Z^v~{)$?5fhGcL$26p3%?MWe`I?b(+Z%iu)Yt(BD(<=IRB z3YD62<$i9h{IR)9wn^Q!; zk(Sll=YX`+HL67%R8@t%QufVzlK;DE6{t<+$t>@voG6y~<$#x8hw0~d{ST@*{##@- zm1#A%`b7xc@!2*Jm$4at+Q5&_eLvDC&H@bxfKHY%w_gIKXU6{S*;v2L8)`nd%0Wc| zPL(8aF(-yx6kiS}iAB%v1KGl21HB z?IAc-mD6M&GB>aM;nu7!a=$O$jvS#?u}JnFJ6=3$s*Ov}c?~}Q(VlrV_RNR5s6xvQ zuV--LPgp0NW+WzzfmJ)DdpLpAl4x%A+*{N|Hr=nfzS1~v4}>K-;TXgB`*W*QBiXv$ znigvxKJL6veAVM#iVXGJnCX$i5;rXodw6|nK<&)S(O+XvXnIiM(g=p72k5E%10D#?O{ns>C%5;bajJS8_(614dxKSVZSP0PniNlm4sY_8 zxkPen-?+9+UHM{m%5?wZp{bgdfXtqFu*egci}XjO=6G0*LsI5fPg+&Y+o7Bmm7sN~D!E^b;JeyzjRuqD z;AZ)>X|ba_(>@8(u(oa88*VztzEL6-%}e=iUBRHVJ4;UQK=XyF&n1b~!K%5gXw6f!cYZ`rsz0l1?eBXXe}k9b7igf+gpId6hcdfs1G_ z>O#9hchcuxcZWbT9{W`R*$J`1Isqw1kl!Av+Gf6yMPrr zaKz`@rC@n1@q1fy!^u-qt*2}+-h2k5jt1G@C<|Jx-fVvU681T%xxf+q+beVRu$axl z@g@OS9?I^ioaP5h2C(WMZ1h{;&YgRHxy6X4H_X4l6qLXY?EJicaCUPER-<#40~bD* zWz7a{`@@V@>j>c15%&CfOR>d|LxMGM)z@y&fc?2Q);jiBCTDj26+5 zOfyTLF|ErfA(#_-lpwfkvS!}1bYL154XjX`{LKIH)tm|I9oP}U~j#b zGq!*Fedrg~)~te1frk5pB#d?}sA2p;??FIad<6EUtP2z0Q;s0)?e=@DGN;~izsBB4 z@i?$h#<2@)qy50{2Irr(iGQ)WMu5{|in0fmGunVotq?EJ*ss3^d-p_%vAu{z6MJ+0 zJSf*M=yBMQgjL|N}Xcq%%5dpY0IXYr9I_!p}9R*xTF*jt+p2 rlv#|vcbY$eGf>@nwlCO9-f_@6?2{(85zmV&ArISpI<zKsML$*$ehUas=-IdiMc6a+je#OZ!Fq~&lS5`8349+Ao-Uc;FZ(_Ry z&&X6>dhqd>N#QGv{MeF}CAX^GT|7-L8hao{?eWFD-ecBc2dw!`XXK+zHWXojn6T~M zInLsmN})lq@Xz}}G0mHsuE$p_E2CCa0QinjAIiHrs{)^Hsc@Wu;fbLWW;bkEg!?c9 z!)Ko_h$(~u6MUEC9nbtQn|-JC4~DTPV!`-*j{QFHo%kR354~lkJo+T~0kb?Ol6nw4 z_$2>%t)W|Gv)WVi9}LhJcA`^-tUjb$D*IFXHo))%Z7nm~XUBH)EFv)0g4dGB$be*x zTcW+`QmH_)GIWRt&yum3p^rO77~UgHx`6S453=kR{(kMuthf`0+XoH@8!6t44;4l#kgE%`+uQ!dtu@DC3bI~l4RXXbXIResuxX`vVY&{L z$BLvr&?e$P;MeM4H9%jA{nku!1wsU0Z$5Ifi?NS&1|;n`S7V;U21QE0+AIQzsoff!;iEhf${+bLu+PEeK);AK9O*DVaV_9lodTEGr zU`jv3E%!n`=n_+(k@M&oS}iujlelDCYua6vN06uC>Im+SGVGhGrze%`GCN5Y29pP+ z(uW_PW^tMiuVA_r2l_jHU=?`u_*1qkcZUcAr~*tqC2MRweu^x0+BaCFA(Hsl@`lsE zi_hevAg7fORl5tN65ME1_)#t&#~W$J)|`D93=7S0*FI;7Aa3TNSKpwSS1i?6tNb^O zdgZR0PBxbYyE5;#pKfw=A9)n9Uw{F;lJv-bI�)eJ2&_lxtgSqF+&ygl4iN`;D5R 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 L=8=rU#=rj`&XHXm literal 0 HcmV?d00001 diff --git a/pic/springblade-swagger2.png b/pic/springblade-swagger2.png new file mode 100644 index 0000000000000000000000000000000000000000..66a8165f1b4260e15ace4a7e2cb5646b8e167c83 GIT binary patch literal 82357 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 pJ=I+*ScM-^wlV4C(1 z)KYeXu5?XGa?xIy8ySe%o|BiNtJe7ZrCaO43Ze;Spr_aDz1pN#cR3^(PJ%ph+0-Q( z`n9rlzN>LQU{QFY(g)-eWC620dah(|vwS;stt^<--Ur&15OO(O_{ohzt(OI7jE=4u zFpW6|P+5idSg2YerZ~_DsXLi7{IxFazW>UF*TkqZ03Tmnc_)^RWEE)gp5Cokcim8x zTbtM&dZ$XYtO{M=u_v1U7_jnd>J+(A?ptQm0yn%WZv1{LwQl zsFr0_KkqgyE93#&IY_M9-7f8rzDCpAe`rEg9*12CVUAtVe{FZ2CYXm}l{+{xrXN`+ zKUy=B94#fQ+>-F>YI^JZLRV&ni@vd;fWE57P6y9|5U1|x>5myA5#=hagy2+xw1k9e zzOF>8Ny@FGZ5!7BZHt!09|moUBovREYJEoC^?~qZ40jdc_U7&CRu9|02hBka4M}gZ zr4?0X1a6+`e8KcV?@W|^760xS3n7cTpz31O7$d!`o)EHd!31e=CS4ZCx3g1%rd?yr zjj{;QQ?IU=Y1Q46 zyYB8SBgHK(Gnna%;Z<}rlc1n3qkw=qOA?MA@4vsNem;fVKb7<)`it8AbH4vv2`I&A zvBn0+Vs!e}K$QbfL^I#MW4{22gAWB|Sg*7?;@s@FA-qwI@8w5zn#lSeTf6 z%6YMlnlEuibS2KKeKzbDj}GLwLm6??SRklfn=S-GDq#CRfxg*U)8~ivE*sWxGRb#i zEc3RXsC>;K{6w?tCyVI9V)3@ zP-blB+9sLd=44`?XWJOkUl|c!E&f@#?hPX~^L}{@KTUnP^q0hdp=hlU!dIHB#5Cai zw8kq_f5uv-h@E}$AA=%R%JO&5`b6k7WTAP}tJdTKIF1GrNI^;PNRSD{ z;2&dV?wYaCYS&IWI_j#?zYo5;r2SwgcqdItkTKSc?)f43S_tLXC&Qp znIAT(iC*6rd0pT(u!h&6Rbjo`pFbK-=AFM*&ZnGk5R}@D#8O_rN&QIM;i58K1$9%p z?@opcLk_hxT&1-yAW!PiJPp~=Ndm#aH$3-_lS3Sw@3|LOSjfrB$|@w}0(1!o%wh!W zv)@5EIPjJS?u|8D%2WLy_60Y_ADjnjL0mYokbOHw?Xt@AG47m9}%los`~71YS4v9cb}0VqZ2U%1nl1D z9ZVv5KmFU6-Ch@%ZfPstC;q2~b1QGfgd*U5p&I_>cn>)Dh4}Pqc#0QU?fMfFyD*Mt* zfxeMhPl|KY#6=!rpZWVeJ?-I~Dt65Q@RNIwZv&=U;+7J*>@v4yz$O^#XUbza9;lvJ>2?iFXF*>~}pop9^6B1CaXP%eyb>M2bX1xdLU8)P zoDtyp$6pEX1m;Xc9YL=R4BE`E293`ASA&MO{m_@Bg55Uv{oDlO1V62;?K{=(hD*_~ zSsPGl?MLJWNK=!IuB^gq<=!Ngob~28b_@4twy4AJ>chZ_Krp}FsC_EU`S$3!rSI|K z4gpo?LKyS$N}=EU1N8G$o#X*t`r#;>WPw%vEnuT9#qj-6-r#$%S%ZoNuSyXP$A3^oa;l*_r3O910`gwzjTQi=6!rY}obHnZAXu|%yP61+pwds7g3^{i@QXk%^b|;Q z3=IthQXj?XN=hO#*Q=~Y78ykP2Da)q%N3#f^L+)>x=V+N#!#352?L@~lG$zNtm6GF zSSbBokmX9hEcZy?tW~o;capjdJve4vn=5=CH!k4Q4Gec9!7Dj1RylUO~_tbJ6m3-nz1WD65;K@C5>!I4e%_lIr znDS4F+TKLlivksYGjuQZWdM=y@9h$pjDXrPNyBu;NQZs~D2qC$YWa=H2ooEz_EJ4h z=Vp0a(hgySAJf`?visVocIDi;skEG_ruu ztEI)SawLe=LEK{V5C&yOsPJf*3he~-UHK4{x)N@E>jjChNmaP{tILK+zQ&({SEOK8 zr7vT-TWryztfKPP?6r9H%uy|U)f4Wvi=mfyb z3Lr*CbD+o*&~<^Wn{bnO7ku1+F@JTPu%#&J^_4`7KR3`+BKPs}ad`2EQp*W=OhSv;paxx-?cDr#@iqoDaTizD5vG2)=j60A24!Nep=`V&9za=3NIMFL7Ho1O~xU+mvM zB*5ByVS2jqUtj3EK-H;n7b1f~Y6(;x9`aQcu9mJC{_fewegq*0eyZPdiMZ3C`zBBv z*lA+sa3Ea)O6}NA99pPi-S&g*^y~aLDG2UR=EQdIcvIRhN7>Jbw4|_lzhrUPzNe(d zI9ws5m%8PMoL3!T=Z9_4FkZi2u?puIDv4cri-)aPbmxv!g-t|6kd;=3l0SgcA*1s_90q#=w+<8^>UT2+M*L2-I!@J&?rxaXL7WZ z0+%84>FtQM)m6v!g);5>Q<|wD5hO(U0Usz!2-Gv^&l^afd{$uPda#Uz0{b%L9WQUE z3|IEB<;_b2Hpl#{zG$Ygl*HZ3Ald%8fq!flVp>jWKWH%5Y%(%~FCpxK8qm%VZS=dV zz(hxvEaFkg>EgKWy6g8E@)?Vy)oo*V3^|_+OHR(z6krsnD9hj&=`k-IgH}1^Jnp0t zN#~!5b~{5ka;MuWG$ZMD>T;F+pf^!iOV{@D{?|F!fG@=^<$cq=9o7d=9xck=)C`M= zm^Su-9edy^6szFsO-hAB*FoAIsyE9tsdo7O!?QuOQvIWIU@5I z6U8=0G+DE?f?2nX#K&OR(-hzUz{|?B5-CG=Z&hL0?;>s#FEM|T{2BFyEITsBPk#L9 zZ&romglgUUJZ#y>1!_xj2NjqO@-QhmZ+D4lAriCy-T2bmdjVHeDoI6BQc>)(;!T>j zu3ns>(fmkLqUS&+a&8M*kraMAcGSTDXn>yZVy{R&>Z;-61AqIQgQq~13jn|^Bmy`r zEUNjpl{ia`bQ+l^W&&*`VJ*aWL-(439`!MKU8oT>YbYh!XsUaJI}N8Ew{s~M&kJ1s zxVJ)+gSYd+b7R@XXgo!%uj>#lod(D%#kuW~_hSo${#$p*s!~kS7UaNh+N5SmkvI|hC;DgC*vwgY(UZxBLDmxe_e9%6 zhB?g2(*~mXYF^9x(kT|rkJi;KZ*Sa`=^k}n6R}*8#S<|9soucBD){tNqb6XTZ= z)uA`C&!}LOE^g^c$?R9Kc10=ca;DPAP8muXOJ+pdRqzbby%mzFSQ5m=Z0X`KBkeYV z*z1VoONq|755w%C7u!6#%8{a3QHw*lce8@d4U}hcvR=E^)ZTth8M3O!>XUL8(L_v| z%?{%IK+UKq?kuK9Xbl~xP;Vh-`ScE zWv&@qwGo#kVJR>!qk(PC|h;I;!$ zLD!wA7eYLpsP$_+-a%Nftw=jPH#G&+r1LWM?N#Y1gJBdpOM~mwhk=-n}$XN_KaP+Zy=GmS$@}lVbjrI(iR>VWkHc;;jceK zt*0vB+^_n0ig1VaE0g79k8Fo=PfB2KXl%{nnRZH~nvUXr3#*&Md|DP67d-end+#NK znYsJZweBJWmqY)>OjOPp8Ohe1u%N4wo9@pdYszjT<6a2unJU24VW5(HIq^&};| zO`EBWj#++S1HhJOt4~UTf%7j>02a!J$v8Z>aw=5**;-*!%nC;Q4na*p0HI?N* z{^ApMb7$FLRN1zFlHI^auKzrceOTT?MuD6U7S-WOM^;QsiUKTLz`N=`q3SCXzik1MQ&~`&=@<<__123o8|3!8Q;zL z7pF=5$obf(`x)IKti;x?gGj`(WW~H=#|Eo zm9_g=kUzuk-lq^tOG`cVK)jUn1%`6x;I=$l4`P}_%?OAu)^tZ~Y+xXpe(S}AR<_V& z{@>T9J1^lwgfDLtemP3{;hh>}z4~iT$VNlC(!7u4LtxT?8lD_cG7zBtc}LVMFVx0% zJ4R^hzeK{`xr3;MHypG4fNJ~0f3*4F3*WC0j`kx(N4BxX%QxT;jZ@Y zD0El!BNq8@oGbR4oQ@fhjAg%$U{zr+g?PyYr+Z!Y4Jsi8St<;C2;jc|-ZTgoz!j7U z19||ax`Ig?7abNhP+-tOd|hpJgp32(^+a43IUoF>aSw9<5V3)7AkXBbpmp10>{#=m zy=%%Fk%f;P-tutppPgNT=S0A=U6qQvqUE!ErMHtZ*F%K3mf)}yH8@?-Gn3hX#5bZH12@nwx7A?|x~98X;9Lb# zsklPBgG74ra}*XXUIvqO3Kdd6k?lSKTGAEBFHN>67T&TB1Rd5I6tU+~1!ZJgH z6S>j%~+N>TaI(z zBKjoEu*1Bl{oXIVC1y~L@vIMiTX&+GU{Z>5>+%B=l7~Tk`|B6ATX~;V5%ta{3y_Qs zzW!d4tb|wVf#BGl)@p#tXGIbf*=iHL{yekN_l{rbGDM2$-b}I0yceV6cV0&JXVNL{ zo{Vpe9P?tbrVh` zMnZWQN&i5)Um^rUs?*Df;=+3Up1uoIZrlBwz(*L}2GY59#`|Q2Bap@L*3?*rz$s#= zx&dcu&;F7WZNabcyxE~k@MP(2B7ibe;bgM*q6yH)5^DYaBo{7}vL`w_j?^pddMH(G z^_#y`-**bE#2`p7R6NlE<(6Enf{}F~ zY2=m2QA}*b$f7u^!e#4H_K}@J&Wye>tdHO@xm(p6#=ViP`O_J9vCaRn z_7fg`unMBKqDsAVn`lr>G zna^NF_Vi?NbQHuu^`RWJLxx3bUufo$f-8w@F``Z1aJz3P3FsDjOgKq?-))mZ)E55E z9l#exKp_^;oJp*!%Rp7u1CR0nOy;t=K3K}*aW&H{P4g1~8Cd$dL&oQ&90JdHEGE#!*m8+ykUu#d>gpU=wDNi8oMdy_TBh9YE!l%4CVtaO6>e1}Sjz)) zhm4jItI*3Fx@5EG2^S-21S?@J<5N=GYWsU(EKln`=lL5@GvGVSd+^E_LX|v| zG+-P@8VOQPX0bwNJc{4E+6$g!QdLoTpEoh~`B8Y@y^Da~@2ej@7|DUw(dwvn0z{7@o z!a>JnvzN--tMa|JcAi=ADF0c@1nAEPgjR>`&c)ioD^?2o=eRZ#(dpcTGHn{k-woz3 zi{Lgsz!A`2iv04?@82aljc=I!-t$=O{o`Bb0p2cFJBBI?k%fY{o?)HVZ;vi>L>db< zf!yxa7$J3bkfZ^UkR35lw->Q$<~Qy&gRk-;+emeUGU^6 zSB6TB{PY$r!(99*lxX1s}*YzE{HP^qLCVq)UynVAx!9#Kjp>o>qn z=_3koGfs}Qod${dx>o-qCYjE@l}fAdNHd~< zz1-B z?Cgs3Apc4mq$<}tB93*71iT{|mvNFZ&o+NkraZr9v0*+Z8;UCui4{gJ6=}(AJ1sX4)*v=t&g2Z2 zxta``OOBS?wtJSC3CxpB`DCK^S5lBKvx_Ao@Xx>T|ECx*UjKio2(t4d);! zbEx!8k0+7Bc${pXQUdmcqscKK`3+^gDoG8%!pc95;vZ$8{9=?YHkD@;wA&tU>#|1P z*zR->sv33OZ@WqcPKuWmwx%vkvH?;BV$(So;YV(17ef%AMBXi@54DhS&%Sz#u6_0R zgT*yqCY+M(RWU!BX|lECP-_9+`v2%D~<%ZuRg3XZ;z(*f@QqU{Ck?wAyT2;9a=bW^>r&E=Xqv=^}NR zep*##^MP2`H_>WyMzk`NIavV{3nX9e;BaOLMQVm9ET(Z#FT6UfTr6|BObK^$fJn0c zihf$zR-0n6Q}EG%3C-OQvZ&-foNkTCP|mT7iCf*@aND;B zoN@b(WbzCEL4ty;*4lWK=b2Ca!CCQQ0+z&b#xDk_X%b=4M*ehxO4C&U6sD%8rmvsE zRC8Yz8;`;n=!}Ex0YIc=-@khQ;*oZPw;(?SqYane(gx%vrL+8u$CZfyt)o()-==B+ zor34o$s3J>YP&ggUeV7`e%S9Q2`!5Ey&cW91&$o$kp$?qFIR2EFk5GX8WGaQVW&z= z2MJ!MryeI-@jb1<-7SUxvB5*fG!}<&w~5QjE(4-IbEsl(3$eDg_VO&59mrEx>5~vT zdQ-4yoq-EtP%?`mRqwsVFh=H?La$Kbr4G4(Lfe3()P$C<0X6JVATN*0GcXA;1XW*- zj$kSgXhBh(Od@a+v@nbZ^!s1{(*o3%#*?uZ!1K$HVNGra)esb5C)xErFd57aRZB12H3aZvHbHQssT^KT9=O1#cY*Yi**2xRptOU3k~g0l}iLp z74IVT@KO0?V1u+70SXpwbstqy>Y?gkLZ`?;E4-Z zGZl`T{lfvm6azhCF&zmq4v$Y1)V!$%T;lqR5XqyNQr|44`zKURT)PIx{bOTw_>Ec; zFk;oY_m5Q;_%=cC$-&>>M3{*FR|~&VL*fQWloE znknSJy88_(@hG}XKj}YO`;--Ip)QY-|Es$}3MuB_3GqG1`oBIQ{!W5JYw|yOSNJ;# z{!W5Jm+G%M_@C_`{M`xu?gW2#f^UJtU!UNwIr#s=9CW*+9mKotRJa#NNU)7ceTh&= z1Qn>7#KGaaCoUKlu?^z#zGyaLJ%KqTl5Ejy@; z>Z#=pK+CU-rD4y05%Rf*9iXXK97U1m+eO}b2K!?*G2c@ z0)@O@ci~)|z^mEcT~6fV@z4W=i->eO3cG+~`Py%;zD@e=9tXE{_r#FPHd${7uHrlY z!K>{bjJ7<>Bx2B*S_Vk)VA?;&!M$|)doNV1vu;P|*#O|3yFMC4yWS>9&2n-~61F^Z zMjOQ^?{e1#Y-TMO8>YF6Y43g-*~0aeZ{{wr0T!-?K*> zRqYVb|5211SEc2lq{yr^i)$qlOf!8k}0Od-&rbu{4)Q?=1u&wi_ zO4ZLFG@^bm(Hw7b>{^HO5kd_BADMqu6a4?{3*-Q%|9gd}kpIX1uwQdo;2H+n$y-#@ zQ#(GHXYDRwe>nbU*Y0j@S7ouM;2&K(Ph8$eo#$Rse{}7*fNM8Iz4`}_kP1RY|H;tr zEIrE~JXu+9tof_|tSN;2te@F6vJ6+|iL(I?s k+97fKABF$fQ};94Enj?WXAveEH1JR2j?C@sTMwW8FQUpqBLDyZ literal 0 HcmV?d00001 diff --git a/pic/springblade-traefik-health.png b/pic/springblade-traefik-health.png new file mode 100644 index 0000000000000000000000000000000000000000..733172f2ba55ef6c18e695521d1c305039ea93a2 GIT binary patch literal 53756 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

htKMzU%$gx4z$6-&*fK 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�+AqY>@tUfFID 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

g2lU%)OeE1Y&rCJr&Rn zg6%XAxN=LODq>rV4>Y85Vpo67nk&*=fQSE(01=293-zGo*tEn~&OAS0s3V}2*@ow+ z!-yh$_V-EE1zhVf90)N$9szH^V?-LzC#<4XSWJGT-D%&0<}IY6N?*kI@)LryyjhB?y!5Q- zst)0TS#q!v;N05=YZ1;8gX96c7BHZIe3;HiLQJx3ZBfGVK7K**rGFDg>w}vfc8I8| zyxTNdUe2`p<^-L3X~r9y6J)wG2k0{9Xsi0M`jy5v;s_sjw6vm7C+j zd&$(eW+%yjQun7;ZUACQuf@S*kY8g$_slHvjFMI#;z9PBWFB*8IBiccCuc*3V8>}K zKH_^EUCSuXWUTu9ZPaXb%Qzp!ed&w9IZ}f{n#{UhGE`_8b-bfgn(B6m`y#}td&RkU z-0C#-mLCe>RQ=zkD`*U!Pm8s@OtDzSwkk{KaC}!!QYRvy4*o_qDIl2 z@l2=V{VK`jGq41lsY?3g^aAVWR9`2lS9X{c6g&^ScWba{0$Ohf*{L3+agcJ! zBD~WlWv;{EUZFnMEX|xDl?+TCDKIpt8wmPuJPTXX(~jSim&M`SaBu z+BYYSL|1h(%08tIAsL5Nku;sTF{`f^Y9)jWd?060yfFU)_9^j~IXUCX<3-fYT${>Eze+eNMQ@b`kuw1*pWi9xDk8=zC3F8_jFQgY}RVJd$^#b1b-J!NQ-1xmda_`BHX;<4dj^qfIm>^^MN4(7$Afm z^lJcjOPUiB+88r!bo0G}XZ97gl#TPtZZAe0m377tz7~ht;SUBDpP(Tq&o-%WMHKp& zqbk`X#H=;i++KXGJ{Whq1Xj|wC>upt^! zW_7G_o&2V@KpZH&#g`!R1sY0~RqR1XX7pj)S{UaT(WDgL6~35~7EvvlF~m&3i?nTu zf=qyx^xViY$N9sJf4e@cYSl+*0(6rVJ)M=qbk75v%)R_q@63nRE$dtC?C{WzR#CaW z3(NP!e|ge07SYTJWRJl@Qrazt&h?nb+6~tzv$pH={inf8SC#ODdo#gUgIs(~?WncT zCf7(*+x{q1dnnH+%K);It(GLJ!YNy>@j9ue5+3{1-r!(db2S!+-(`_~0~|Cp_PD1E z^!p7q$+w;I5EFYnWQog{59sD!Aq6FY4U-F!~yDVZo1=( zlzeH;n-wJo7>rd)Z(p-e0ESG!T?Z~B^C(EW%HJ&dT(OGhsaO&VBUN!r<@y~x2`etW z|4?vksZ}MyRM}?T&PivFn!aJ@V#9pT9^y}C&Ke>TL#T6CG}f%#goQ9#+h-`6O`kZu z?8!NSH1!zjUYwY5_k3(BclgZ>5%OsN?T2|51pRG?@NncAnibRw}S}fE% z9+S*|K*&Y ziYtOlWRrU6W`j`Lj0S?kLMtX5I=Ih0)fZzg%&wM|SW)*B&No27k3$Zk)n~dMcEjq4APQdRsCMMEs?d@#!B!CRMfISr1Pa8o$> zKh#!(QGLEV9#SfZ3y)r`Td^jb?b=E0nT{@369%jeJQjFtsCx#;ttvhaM<%Hy`N$KWa?Z*ZE6?<^210Q{T6gk=>N$N68KO=oOv)s!Z&oU%TAIq-I}P7(~n#F0vqtSWD4r>q{1N zU(ZS6g{QL3<$5xRq*EB#5gTsUjQdEzIIVNC01W%{$X<6+< z(#zCj+JDekm-CiFx(%>f+s(+l7q){q*9MNVnh4qZtW@*073yDFeN;ZUWnpV(Gy8;c zZhd=+@wy~uI*-I>$2VEDf)V2f0Hb;O0TtN!ctK*3FKJE3{v%=9P`AFI3>P?p^lx7r z&3RWar7p5;l7@6K4i?}z+=Ue0TYh9nJ$X3pwt9{rLcyY<*z)S0`}cNsh}xW;EEZSY z=>qIfaGg>8a0BKhvASgY)7v~(n{qmEEEQVC)8anW{=#TN1GHFUqrt%}=TRh82B>6d z_9~^B2x>V|63l*zNoKdv(U_fL^IsPi_uUs=iw|w{6pB zaeJ)PH<*Lq-$6Gm1pP6U(g(*i||`}pDv5qI-ki2l0>v{S2&n> zXXclVqB!1gck)=c$e{|^-7_?=5eSa(J0$UlA$0B0Z${w?Pqn_EwvVQUsrhlBsv~iOtWq@%?k1)G<&H$7d~C zth>aEXqnMzqswq%se>CH=FzuwEs#y9b$w!8$7L&JO77R4%q#zU3urtEB1EGTz* zl27DiEf6>8E;ssWQ-jbT1kXSYBum#;bN5eQ`Aqe%2IOdQvOCXtABirQPw7QJMaT2K z+UXY$6O$*3E|pi0!*LEKfP+PS@u$A%O7h!&I@XiNe!U44$}8~|551Koi*JBO%2e5jJt)geIwxRaVSV2D(wl)a>G;5dr_-zT|EDJ76}*!NS}9w=V&p`$XVDE!VU5hX17{K>Nr@Y)u8-fHwkn zy>LAlWXDj!V*N+cr||w@xcceXZ5A{&G-lH!B@d(tcC0KdMJqIO7p&Q-jK2ca66ckj zHb+;*>#>VU<(G3;5L`vFF0J z4;;S)!U>&TC?gjAa-?7^0TPPpP!$Z{^PdL|EC|Z#Q-yR@qJ~6sa)HcQ@Pd--sg3oU z;9sSKlj93HW@VM|u*0i7LTd%9DlyZVDx}ADEtS>h&)>l8A*YLs$JUvGfXeo7lfu%+ zF=LNDY!5f`f)oc*D6W1rIofaF3SOv4SL`T563s1m&-JrIp0s3K7@wcXG<1A9V%bmqRJ+ninY@l3cDL0m{G$IXu984k?{1MG1DF<;Fb zUxAL|aCe*RZ^i!TJFYHBI32quY5?L;=&=7Oyp$uPThu{u@M~Ty^w&euH~CiW^29B| zviZz0*Xgfk>IiuYl!<4M7A?w@Q63@zA}})!ehZra)u`)k!wM_BDV%UVoIn#Q3P7p_ zQ+Gl)jW}dQ)KTqOtArM*u~mS?Qh87|G4QN@oLb!dL?@!BXUx6c!_7}Is7qweYvD%} zluWal#hR)0pS(v=iBtTrFyOZ=ioT1A*09owP{chmw9CH8=g zJrEtgSUXb~&@e4BiZ)$f>Y^HRmMsg@VDpZi%CF57!EDhR7~cw6#t^36Anw5hd_kkO znC8lCACc)9hSX=06-JR3x2qYaMbWo##$oI@BV^`Q$h3lMWBh2p3ZX+2ECHhektqM= zptwAR3Vvc)+QM~-Wn&Hx+xBLM&8Wq`<)~Uc^djPgo@#i944j#!)&=(Xv>SSKa9}(t z`{*RjN0adYd2%yYh|R-7zc?5k`8S_PU`vi%Fjf?gP_y73xxC^h{^-cnQqW zTFnUdm3NP-1tazaX_7x2&G@S7$DUCLP~XaAf?4`H4_ z*N;Ewxg9125eA!}&?`%47A9NgBcQlFTni+Fv6iIWZyHy)VoN2j#7MwtwUw{WD)hP+kXTX=Br7k_b4S%~$u&%*-tC8b%<30Ey8< zmB%Qpv~ZCD8kA{OWF8V@silWq)?W~$C=Kkgzgif-hwHyt|NNJY0szbffSuxjp8xmg z{JGuOJj8EyAC-uI7wY=+YuiyD;`jf7#w>kBHF{{voB%YSQ%f&aDFbwBOwFKn)hipDuIK z80VK5o83xM_Gn?RCP$0WZ;@=8FUV2TqnfAv!p4?uo0(TkTguc{rd}qND)d>Ftqg1h zOY@F@CO&p&1uACyW+pK^08f0|diE1_ZQ1qbhIAofp*5;ASKY_2yzCw>px{eDr3RDx zL!~CA`0CNn-ebewzf)np%I^cs~sVxB?- zY?zCTUv9vMkMg@a2ZrUf$m$m05AImA-x;mkrN!nZ28M|bhw@MDReI6k zF-&`U6f@nd5zEIV4%f8^JEY+8X%8n#)hUihYZ=sjN;qfNs~CN6dUeB8Dz8WypRhrm zn@!sy%a`wba6^RRXv)pb`-)>B@-*>Q5y`jT+u1Ct&up!70smzDnunfuM1qt*wt zs%-ZX0gX{=ugqd$ziOY&-%Zg*_bVm;N-BO>;2Tm)aShJqt*r08E*>_-3_@(+n8yg$ zi`RNGhqh~3GtPu(vpas=SF)JWSt6QPnOjLeJKOS;3tAOg|NYS)P;YdY(?&lazPv<< z@}7!UbE319%Fe?Z7kMu}OAygDLV(2-gP(`OxLDP7Sx*bNGiE@lXJzKACn|dzF)Mn_JxYfEKzz#Nz7Ip-QY-7ziyH8s_sGw{zOkbA~ms)GY3`Urn zJ&9B&y3TOl)x`h^vPKQVcmA$t%k5Hx?$~VPrjU1aYFH)k9fV=W9ZU9^9izW*M2>} zHmEPFerK-r3Jw{ZHyoC4M5luAoV6{G^+7xr;SvqFSbB2{5tcbll409r9da6|eYGwllu4-_$@zP0`U zJYIcI#og2vnyH?+!3a&*6(rj1Im(k6fCv(VUDL+KGJ8~uP&845=XSN<`kYYtwIZz> z((636mwYLZbs-0Pwb~*kg!qbC23|qD)(M1m!^IC0KcHWRe%+e{B2M4-FJD4tQ%OW& zs{ndv$^beBe1Kf$Ii1!v-27eGGtQ>P@@12L>mB6@&TuO8a8i%e`DP~j@N{QGWXfc=giA4l(w@7%Na~6~|6yx(JM_if`U?`N9z*k|!O+SF-Kn@KY%r;&gf^FQ zwnkQ@oqSzDEK;BW4lH-?d99uWtTKvYGyUE-0oV{pt@9bXb=LY%6bJm90q+)v0c8hD z(#SNgVj0ibtR3^sK<7+}$jrIrt|?8+v>WC{m!)QW#S3j=j#-o5$_jB1a++S%ir`de zL+u)txSC(i4_7l-(^p&L$wWpe=`E9iZMIM$R1?dbikfU+SnAz-%!ITJen*Lmt7&{L z9-|i( zP#(}u2U~DS9kL=ue$3X!di_x>dSFYcMiOf_(4rKu)5dF2(RT{c*`B1++AvDne{C_l z@xI#HnO_$fRK+s1u|W+(T|k5RX)I<;Tw=Cz$UZY{Yp79kyjh^B9qS5W+^ zFI+u;dv4wWo(A#ySx4@CcLFq1#)`6tSe`J0^Dv%P`P$9NNkg3gb+4^>cTUs6Yz0(s z``AOrZt(M4idOb+)&mqQ_mi^%;AE5#+CG@dK3_1*vK!~N9Mj-B9ke&)*>8z`((o1H zG0kl?Fxm3_IC*vBrg#H_vN0#MfoAX$bgkV_luIu2}?_Q%Qx4tDB!5a9(QyrvzGXIli1nZDOL#igCTv zyP3Y6{JN%H^WzZ1{<_!Zu~9VG2Bc4^&zo3pLPWVD%P%x#`*P--s_1Y%85MSPn$1 z`X%~5v>+>T3;ElDD&x{O<yJ|L(s6{pOcCR~%o^F>3A=e7_ON2DKt@v6$6)P7wrBU}a zYp@!U_<-mWL|mkvjsx$DCIE)zaombp8y4hw2qEi4hZsIbfHt-Z!NCPaJmq_P_C}wM zN|~M=insZcjH{9mPGA;Q&ins>*s82Q)EJzFex0}v+1!ubyaBSgxsbn7e&#pcFT6Kg zaUn~_(LX)bX0OO1%pRFZTE)H1i>9#GFh4?86l5hXjp&v^K$(qto>zd9OEct1=AM?B z>|xU|8*glNT5avN-f*CEJ~_$Tm6N8FQV2$Xg=Fw^la&xH?$!iae<5!kLob0+1`#Ja zKteonliFr#nVTZg&BA^-f9YeOV|X|XU7*9=y2hM39xWExSoVsGmyC<7_xZKELL0l( zx}2do+D~VZ=_1&p>OAYVNQqyuY)9X5`o-AnO^Z^X&v= zWL#2b$##{Hpo#0NjLTz!`o)&;GuZDJ0|(3Q;-&jP58R*mu;6sxe9L6Mz#+c$xuiTv z6h3!4ncCgh#qW>%V&%E3vG~dvqDsd+jjJG{=b_o6S17FXk+F+Odj`Q7Yqj!bJM(T^ z=s6FGpVp`~gxp8zCdqB5zTvyk$()_TAV%b5J_}4&6@C6uBQg1;{)NL7$)WY`@1dPI9QhCkzrq|hTW*RU(4626FQj@$Do7q(p+a=;dRQ<;d zOFRrrHu%5FC6J&(2pIJ-G$=-21BcN^pkTQ~$II496^m){Qkm(GFh?OG!i%D{%pQ2` z=2!97Go@#w`{#M=98!d6VI&_yN;(fAGEftZWF9zKGE*TFvlHHyI>QI2b!#nj=75uuIpcBs7NR6h`U1PAN?c-%jo%Xe~S5MPF&Y{Xp-d-uF)GgZfDygzDF_GHlyK|7dV@mg0xttBt4v$c5`!dARs z1y$rxLAA7&soS&HM>9YC#5O9OPJS{JyOm#HBvw3^!S51Gi^yz6PK|u_CW;jwM7=Q; zxS5SrilnLy(zzVPP(EnbTo}LTUu-(?UK}9~oS&9ary*}Tn!N>&H}zn&YQ>bb-CYq! zax)q4p}<8JGSictz~C1+{liO)Qq@wp_ELgDKVPRhq$9#X=A4WLXO@FeTw_;F(}BUI zk6o_TC5Z(s4nX>uNs!>9-xTjv*-eIdT)PjaAldtghJ3#(efhnG7S35y;^cL>o+POe zN#4+{wTY&}4U#B~vh|cdmAH^@&|Am%YMFagUZay+O`b#AO3sfd{{#2~tZa5UMReP~ zh|^_iP6funOM2{cLU7%J`!4v2eKbx2NJyU*o!-DrNrA0P8-i}4p4{7Bi5gffhI5pT zvzWTl`#To!Kf(VHI8dH9gw%SQS180_%6xO9mvu&#e zjkkm8*X~HR`g-`B(OekFo~wTZ+q)S|YCE;FvlC&3#@K4qOicO@RCNTp(|8S)E(l_AJP8&Zt3}keS+b)aK}q(+PF6B=vvZXQZw?wqzK@6yIrsF6yyRA zUhRq0X>mWBsqu`vTz-V)Q33mWGxi?@gf0TtolmvFW93UPgeKck!j~guABE}ywK;wP@<;`*W*As zbIW2J@!!FQ-=Q3u7f=HdQl|!AQ6Ij_0EvSk0RDe~j|j@?ABY(YKISLCNKpP09r}-_ z!=GT#A3yn%G5~u$KuoRQlR3rz^#*_a>MD>3&5cNE_$$!*_g{iMdq8)(h6em9K)X;*8UkFt$yU=|G&okJgfe1_RP}PO13a(fbOayJRIUW&;$b5yvyRe z!aR`H4`P-$EzVbzyknjg}2vFLOE5MG6?=jsVRlgnkyDcGxk z{A8fGA8`zabobNe|+ zy#McbYA(}@Cg;5wOY?cP(De2|{RcZPT$WTaR=vm9#o>*Z2_7}CvnvuyS!U(~7AaIc zvcas8rR*~ZXmsV4rV1tSkALe^M+W_{;y2F7621j<7qmW=u`(1A9Pj z(*;|$`G(%mR|LSY|B7;1qo{$9*RlA(8xlpUvrOiK7DBuejrc)->gu!mFKQJ0&PIn!Cwe!izjk2+l1UXL7S^P zRQs}az7ewJ&k3v-d!Q#w^#YGCCev0D;Pub}zx;Uq{BxjF^^`?|9MADz%-Po!hX{oB z8J5)2Y?eJ5DN0bXm9auiQ?wIaa-6N`Xd`E1&hhV#thn1bn_rJhkOryu2m7ekUyXbb*PgF^qsLX!QtH~TaXNAsIII}d=2>)nm$spr+ z#sBuY&?(Xj<2*4LF@XpTvNC=+2mWc(MBJc+ zVnzDxQt!sR%3#Imh=hVaT**Poj`?_KMOP=KimSq2sXU{|>n_{pn2k2R{ z2|8?AKlKbh`bkow@6rCs)RgtbYy0kj$rAkTgO}^TuJEbCA^x63vWZY)tkZpR5^t!$ zNr8#bQ6q9lmOU&RrSMaRx%cN3RAD8{Z(frS&fIbowQWW?89rsbeS4#)Om)1Qc(=r&y zL44X$?{o6pO4>SW_t`C&w>mqq5kBi+!R&!-NyQ5Nq*a8WSaJT(79+~$7=7^pPTgOY z>&;KF)cdk*Vyeh^`VY2xtdadFcYz!W=Q*-30`{kcM@hJN@j}5Fk)~wE){$W|)!v8X z=^GWgf{G6A#u&H>?@mOkRtP$*U#1t);M++$$Ej%k$zabRw_6NZt&-^Hv?RnOT=zF5 zDB$VCk;!`+EsRIwvw-YSTru5(W32MwT*@P|2leDJXO4);!9s6%8XKucx4`i$B9Zfd zB`E?@F#jVhk=x5g=6?6P#1(^>Oa*`#LX6ZFh0VHqq27`2)GL2hj1pnSHO64I_Db}g zYX8s#dZ9{!Sry^X$HrETEku%53!bo-sz#v(ns4;FJ84!Wf4J}>bqVkgOq!B{W&OUn z?C-Eg(gc%MJZiJlJq5_>nY%Fxnr)kfqjIzxes06)R5kBY)fbQ9bI4edD!tUp3F1Q? zz3y1*p^4$nDi+~OIyrFb+&L5>rz;MrD(WL3{QkyK37`FoqgLA-@#`Sk)A=Pa60?uw zO*#=~N#Q@1N}BP~D`}_T%4OntLH%=(7b*|D1nw+cy{X?UT#5cww5r(pmHqH|Y99wr zFigt3Fe~`m$ysb*gN>+V6r^MoWYl2}`@`pr7!Mv2;JAz(wcn*Y3}y`vxq__HV&gTt zjwNeErVql1&Qh5Dy3Yn~(RksIX6oRjuLqXuyzPxPDaLV0Sv9`MQcvzf3(m-D2!_&4 z`@0GH4Bn{t5Oa^@aS)94hoL>pi+!N==2c^mCfFe26~NAXR4js2v4Daycgil;R#+fK zvTSg6;7^{)&o%7a=|22OD!a+(Yrt+%TsaSe_^suq72>$5Xk9n+VF zt%LJ2ljmAZF*Y0<^fwCX<@3dhY8+D$no~WVbV?eE81Z;OvY!L%j^#yvM-6Z_xhS|( zd)bO{W#=X4IZ|qq)zWXteiT_^SEVymNUe?#58UH)cY_3QI(aX6E(s5=4FP?me37gw`-Wh@H6q_}e%o46ME=gQ^ z70XJ^#?+yikr(@KIcl`B=!w7`;6qe#1g1MM%)s0&Uu3maG%s4h>9%AIk?NN+aY`wZ ztq%{NAUCmjt%&v&^`d*9qrl$kRH<;?UyKY3hf4llLqVGpFv>HKBu%#;lIk;*a6P4$ z6A_nHnq8U3ilj7TW(T*SL=*%EfFBnn$CXD71yGNvYBl)=4Dn=(TL8iK06cZ>GWx3f zIEy~lnd|aJ6G89Aac#ac$A;Y$#!LIv_vvtK7Vhp5=Iz5pWOn>WZO+4GKGN@s@|aTu zxbS7xasR?kqb#a-&zs70;>>BRU*;SIg5e$qIcj8^P`^>alP#dSTN?&asTC4ra6hUe z8)!5@cM`=_&W?Af^rg)yq}D4ay6am?i9M%CSl0(WnPGGRi_|NpV}d8#i@6_XKZICd z(jQhvxWT4#ZZHdvBA+m`aL0{Gp2#8*#RomP%NmIhANo!X^C2H-LTs);nc^K2lfz2^ zs_P7;TcA3^H>oaeu;PPq%|^Nd4Hmu0lCdFIvafpWqh;B9*Ooa`g!MYCV5uDg{w?V& zqhd*Ntq)G7qhv~Qj<;oMn!fZ{&blFNA>D^k6mJhlQ47}=8f<7WoeNxIxY9~74 zTV)cZj7f~V%13>|0cN-xH%4Le7!S;{3^pY*(j;^w1J#b0j86xQ3X6b8!*fpHhHdMJ zkirR*`;}3KGWu|zCj&&Ms~Do5(2whIGuV$Gltvnc>JwsQx$>W)u$!O8>kdsSXOok5 z9V675l_DZ8!8hD;$F)+Lo3GALfw1&Xa+Au<3!0@+2hRNS8pX?mSkF;8Jk0g!4_EnB zR{N^O4crLKli(>jX1@ zB><9z#sed!WK@X1pP2O0vi*ufpCtE>LoG{_}t#5Rz-(C5gs!&1W#Q6iJpn5B9Wy!)!* z1%mrzdO$6!)#pLXJUtC7SX>b!tKCLGDoxdtE{ zNV3%E-!92$VCwvZW$6nkDFhzaOR@$AybY(`K5Kd@1wy$E1@#R%%7?Tc^Oe@FZc+x% zN1U40T)b7D+x7{^3SXO>TWdKun-We<&+oiZn+H}y8%xej2i4>B-`~3rhlIMpFMZ zeADr9sjl1Aez@+rgRWNeT)9(p!K3fn^ylUD;r*#+-r1g~vo2|F zs|om)Y4rP{#&XmlTOTdX#un}3iFb&PxI6+@O076c5y=fbFnH7S(8aZ*NwdWRQkItJ zR)X&b!#MF*i6>@iooOrNuY?mU4Im+jX)NqFrd0rWKJF$S1VyKy1 zmJFW9;y9S$u*zx5i|Ji6gtdWOGt{vX2-smQiG16eS5!z}kU5;cAM#Dh??$O)!)85} z?rmJ44(m#)#Jj-3BVmw#e z2>pP2(V>%MhyM&#Qr}N4@(#ERzc#-6feJxYn5^M~F&W2eL5T4Q8&~Z9gPKhBMa0(& z!`U*YyR%8g#S|LPQz^4K{@Cc(p|Rjq8$&=yMc$}!WeMY@D2Di@^ITQp@Ko?6dd=RK zCp-KuyRv=Oml*p?k~7t90)IN{&mG+JMHCb1IunHsk01Kt)_R^FjK~XLx0E#D{=Jb% z81XVKEjSJ!DcQfa{Z+Y8GjIo65scdtSr$Ke0lG)^glY(*BJR}yn)8>=Cgn7=k8YSK}EtZ zy`mZx`NxKLJ;)#fbl88k{dFV$5B8Nn{Q=`BaES(<|G2r_n{V>ETob-M&(GGbciaG~ z9K|u~32|n_|MUB@MMq}TSfVxVj!A<+u6xynEw5c?zoH!Bak?wEl$+*#F&b?u%`!91 zH#IrG%Z-9hyuEEa-N5}gj1iwY*a{IcJ1c4{P{_-vOXR;p6qeXK?C8U|6*Lgn(&!kJX^Ep%0+cjE3YC6rD+4(u?pnPC2UOpxC5ZE)GsZE&`ZA*{b()Ha61SSNkj z@3A33qp%Z#8)|lqbpE4~Ga}cUZ)s^GYH|KuZgZp=#*nQ-<%m;s+i` z2gOu#PtKAmlWNWtri+r0G_Xz*XSMA_fccKJJ4ZEp*h5k?`cCuB_%Th37(_ncr4Ox$hz;*|9a z3aB_y66N$L^XKGg>m<2!ykmHM_GsRAaDAz2j&Sn4wa*whLbJAwA57H#T5|5RTLQ0h zxD`qTJSy#c;e-d8&UUux^}13$sXaFPw~q%+(;D38s>W0tajy7FjhUMgA>Yd#-71;o z^xd|~Za9(gOK-WVKfSeYt5Y0QGadifNL5vKJth_c<}Dge1e(-i(cQ5OFGcV)r0IJ^PGFtNc_Vf$k}nSHuI<{}B`ZhE z(JkC4Hx(tsK1YtCao*g6;Li?s~iIfU*6l04vvxRTo>R+X`3iSx&=R$f zV+@N7A>Y*e#v8R674wO!O4A}47SVV2d_!zKDYw0b zCk-0oz;&{*_EzzvtFApLSbcR+(T5a`=G^)9%lhKXbOUG41sF-!5^93Q6C&csK!UdQ z;F+|A+yp}Ib=9sEY1|?;+N7dUFvN{J=RoG9K7M~TN}z(P=aO#E_H-De@CY2C$Ptm-Hqi1$$R)kcBeBAFl_7WK__JpWA6wt%nz!3pB!ic8d-c=Kh0 zv}yPLdN)nj$BF@LjC$$#d^F;nJ^Q?*Aq{gpP?h_0$ah1bd%g_VY}I%eWMv$_ zwOo^=ZIs@uv7ir`ia+R?ln#2YGU7m*nqR16k3&#zj@&qQuhg0624MQJxnBVeYVjPfwRQF#Xn_-+A)LOTQzK+ja67ED@6cd zUh#-g`0>GXw3f$yKsr%|vE`b6&UEMq<)!SxH~1V9W?t5Z$=n&uL-QdGd*^ET3>jG( z&9#{JMgA$25-l|oG3FW316U?Dt*=1T-jV^fb7*8qo^v@5Hnx8B zlU8w>(7jG^ISH!q5%z$=pc6t$tCCfXabA0<&^^wNUGW9k3E6VDMmS|(tT!3t_rPqJ+~&ht*rQ&U_x!XS0)Z#|=TRXWOt&L|XDoT^KoH!{nomrsB@ z%hIYYCL>%9y$>Uvy{_3Fb5qcv#H-O+D!G!o;tiTu)=ThIJ=ar17K2oN`K+PY>)85P zcj_-+Xn**o^9Cq-YVYoH`B0#*_n`$rK`k#k`De^GH`19usD-0uH&UGRgG=ZV4}tjb zm>LGb@%UJdL-eMrZ$^8;jVb=CQ);*scS)lPUqxEFaol@Azy6 z+vcd*BDj4On>{=lG9ypl+F&Y?1svbnrj2c5ZJi%$Vz16zEb0CIL*_nBpDQ2hxnGsd zhm)dC6Nfr4;SYc_#lshIc$fl;;*o-J6HI}B{EnP-KdOL#$SusklVim0B@j-7Z92*? zNjNT)I>NkIHjVcs?f12u_uXcCd9tmoU*n@mN{G4fQx4*p!_;TwH3&i!iO$Oc$+IYR z;Rnd=giJ3@P!-?NhBSPD>Vj&@Kwp--hntAd_j7d`9%rhgq=f(s#erv<+v_#6#6ppW z&a!;-yL#bT+z0q;v+G;4UgNk=ciXL_udhN>uJ(D}@+_CY4Sq)3U!%G$QRQg5fm8R~ z+bTFcyYgozVeTQi8z7SXkUPm{xYQksJ89p763!0_ooYL~GK=w6(_iKWG_ zbQ0gqC@rKMC#=n_Az$+BVmYX}inY(IPA*(3Yv#Jios-2ZDa_^`T{@52ANFtWFnBy0 z_Tlj0rLSyu;`acFJ@iU7ZWlf?{}3vCHvOFd<7@$?t-V`y?4sV!Xwz6*cT25Tu{rMA z{!3G|X=(XF&BYL+n+FSlcql_j;;{ac_V3>9G2*r?>!iCYe)n^_L{nKKM~A9B^;@pu zn%xPV@{eCB$9i*{^Oe0}<`!MJLimVSj@Wq}4naZ*=bzX^Gej(LzkY%@0SZ|*Yuaq^ zz*k#&HDBC#X^$UNV&XwU5Gu_!rWlSF|j7cl^q_b`J1{~;M4PH_j>vG&ASv4#Q zO~h3T8TmnP{v{K~oPM_shj=Gtr}ITl>@${YVv3Il(zD*Cw~HSP95b$RB!TI+_zV@T zcs@Bx2yZ|+k@&<6H6>EBg zYn~f0+7}na^w_h(ogsskn;+=HYH~F;x@AJ5E3?dFp{&&*8v(Q`9Vw_ zv=Um3X|<8x+R_3;F2YTjk1DtgmMl*E=%KdG%5P7^kdW~8J`}JaW5mBsZ`8K^Uka-CkMia8(d3gy1Kx7@V&7_ z5~X?HWO#Hw|1}SdwnOK9g5QyZNdqtSEU{yCshF&GqX<5=^{x}E$oM*q^TENcz5ocQ z;@gXEjkZamS6eTpyRyl^`*E2-H7Iefopm&RMCFAkA%UBGvK1(A#6=}BbM$V^wVuo?5lLWsPe={Kl138VR-M7m*VNLpk_Go0}w?pxjl@aENwsx3+=35oKvdC#I) zZ;6j3k+2f?C*cM$K2&lA6`3D+r@mL9>^uh5P3iEC-gmKuiOS(ta3N=*BxmKIjIayrPg;u#XadZky65QJ!l)-UfF_bu|^*r+rNT= z4#G6ady*k>ko`Dl2&?H;K;JcQsIdhGr3ZUyD7XpmsJ ziqBK|Wnn1ijk+wZPH3mjV8IHgzZ}m`X(rG&${phRp7;8jjArcnM}Bk)?%^gY`)dc0 z#UuhdI=so_PKl=6=v&r+uvyf<(Uf70mX`d=$?g>wB00j;tz)^ zG^e#|wIvij(-{d%OB6KQy>=V!pKX-TLLun<5nJP~M0}-%-f;Nf&9EklHc&@MwP3Qe zMsqmK#n|-n2}vcBdb&qxNT&c7>_c-5!S|~g^G%KwtUKnLtILZ4O1YN-B<^M>F;|l@ohI_0&5C!SfP(^ueW6u@F|HkKxl!#-twZ8N zQuaJVCK4Wqkp8*1=k!|rTfSZK!m8TWO=_9x@pq`OFHA90$!=)B2&H-jb3xp;57ZB~ zj1$ivTW0uNM_23uw?_G9x0UTHG0Ss@odQSUc_&-6Rs``IG;T^E}4=DVD%l#j@=zrkgf1u=F zfjIyr|DT3~vCmoN61Gqb$LCmXN2ikoP=+HJ<{P%!u(4OZ;vxJ(QSb?K|}X%W|ODcQb=F?cK~4z&qLLmStws<{^Gc5?AWs+an|dvCh)O9 z8Y{mJm8m&>7oRs?W^SeLAG*12cj&u(!m5$rD){c8<)JCf71F|s6#Dq_N65{tnXP3m z5>_soA>Pcquy@1r_Flydh~uPksRcT-(CI_Jx$%KHFcSQlM28(Sd0#tm($!O|?U`1; zRt29WlYyU{uwa1ScLY9cM`F#XTKMyl<9lIeeinj?u|B1pL2%nxkqO%fJd+488-DGz zfltaZ(qPzRbbyn_x%W^mH_gUbrW>XKYa8JVjmu(|v94hzq<2sxoSK^N;#+y6HmzW; zX1M8@f?SV6w8kNJ$G5Q0K)~zURPX%7$ud7w$=0OQN9b~9?69P$BqMWS-i^^?e{9=7 zEW0wZC)#Z9!Q_lIkED{bRRiVepQ1Vof8P-kG1}i;Msc;o$c!4&S>}ZbV z71fIx&%h|KsF>S@yJDkqo>_QUn<${E(^(iGG2~QVr19`*UAv|)`2TQ}OwK{moFUI!Y zdb+j^;npY-#NE32JGo=So8a=)RC;ZHgR!5~o&*V_!UU@mr8PEF&tT}VYbey)%G^Q< zF4GUmPUT0b#B!}fGK7z|AugP=g}o7Q(#sxw9$!o z>|o!+qq{$oeOR0m5h6NN1RA$5fP9GFIO1~r(me9Hq_GefjQ(pm6_5UhmGc_3;3J@o zM9rRqH(}RadYXobaHlRYV{?pTMl;ri$oJva7%=94gm~*=rtH|-ntG@dagQnK9f$ih zwJWC;>=v zIE1AGxB6ULOY3vd2~0F?4Po++7S& z?y*4ufKDoGCb5UPtp+RGSMHYl?TF-GRXHmg8R%DYK1XsFP=ZgF2rN876Y55hEp;eu zoHpBCVo$d|yw8-G$ZLiYhBd5CNT{UJ3lZZ$3tK-63>OHs{>~EHA`FCAq>d%zjhNv~ zv1`jJuU}P)W14JPf7vZHrTiL97dnAdrj)^KKK~%kQ0fpNjP6kP>Vz7%1`3>q48KzK$Kz_||6~&#;#zzwx8L z;l2?uS;`?^|D^j9-u$3gU^OINiR`1-*^cL8|DZ{!@^xS*dm5oB!^6O{HkXRE<}?$b zW6kkCHaYHTWlP)$CxPan)cUUcY+(z_KIKHdy=`pUTkn&O&dO4+oW2MPH|EPZyo!0t zM-i+lGVC%bH{CS)<|*l>dXOqPTBFACq=_C(b&zlEr}=_Jb(c5*CRQGx-UR9$UtTY= zkkpjAW2oWXf(sMb42Z7j10qV?Q-yKgxWqA7@(K-r1R}MY+_|Zk@e9nfHZx)olL|k~ zA!~mS*)H?Q^cE)nnhPOsOtQ%h#g^0Q2|rx(U6_mt@6pKY_|A0vbz(X+du%tAn&EMW z>qGa0Pc*3e;`;Y}CtIrvtW0^P)x?(f&hvrCM|&PUc1VSQ3326tApf2jk%z-j>lw|r zj%!DpG2VjNd1wxH^)ITAwf({=9BoX^2Y>=al8 z_g6|eP<#&9p(%43h&k&88NAIl@;Yw4!-imUDfZiiUS@%$>x(34ZyGJ)8}BX1_G+mK z?Tr>h(;|pr&q%Kq`_)BU#dd&3&%p^lw4V+`Z{@_>7g%n_3oJB)gO|e$+zLHvF%FK2 zA*O=$T<3Ku12{2_ynS4?EgXjHM)064hj(MY)mxb9i!)+oit9%Q7){4gq5C6=fs9h= zEwXrOgmy)-{Ika0SYOs*HfFdrDhv-h$ExP4DEGeHS?7a&7+;s_F;3Vk@R{uwgJg1{ z<+ls4*D~m^&iJ_evjb;o+1+eM@GL|#I>S1k73LrR61WUN&>uIw-2I$DyB!mc_StWq z924U24``$toQcH?`GoNvD2?(GG~ABIR(d@cTJ}f9d2ruF!b09sWLdryf2Wf)Jmu+L z?U|~RW=`x%eu&rA!RCuo*^#eHi2JzDeq$3{3b7D2H@vva61VGsZQBljoWkJh(ir z8=zWyMwt8q8C94ZwjaItE$YrqPMl*Q7#qTgkmMNXe0>U}mfTNhuwseyisMBG>6Nt^ z8j`0S0^eoIYl%L^`O-UlNF5GZDV&|YD)v4Sog)eTi0C#+zvq<@-ma!?e)Q1qW>Ht@ zsXi{Q*~dJkH&!_8OLzQm=MxB_LU4+YK-_2T1b!8Z2i^B*#*?c)22VxrBuBoyH`jyA z$+fVcDD+ltd+@v>`m;1gP}~p4-(7(7xlp!=6d~$wy+bbabVaESseL=xzU>GDFe_3C zQRurR`B%YFVjnDBZpE)WC&y`oRCYq94Dzmy0&nv)Kvg_w&5`2#(h=3Gdt!Xk;r_CW zFUfZD_NPOSp@Pm(SF`7676LH(f$@!8_mP^YGt5SCEunfcB!q&DIqOUYq}kn`j^p&Q z=jL3DUXJ#2AsTzh3u&&MH>NuleT$#I(k4ccRfufm zD~ACBLu)EE!cb{=(Jl}CVU+l$>m_>Swi32Zs8U$9rVxnIKS&r8@0fH@ciq^w4d670 zY8CU_dEd4}FfiDfkW`GZ09RJTtuEEYG5Kk4ZD{;h1k5C>kft6bu05v13F^p6-g7? zLcN6hrG8+x3)}`L;bwT@CuU6ONsjujj{&GiPTJ$-!R`G({`=XD)x>e}vB1E|XKXyw z^E5vIKY*&Qe6MgA_@@}|XI5WJCO98;r`t6NEGZ#wgv-uk?UUQh!}su*AEL@U`ozf> zoYMFRUxJ9+c^7-BQ^^kt+$qEq_O7EKMbW-jE%!jQus*Z|i*NePnt*Xe`{#in6?12T z(Qo)$1+VX<7*=0;^T4^)PpCr)+)JO^(^2xfkoM#r%a*GPj?~o`@XV!}4E(8=yVok> znj+lMB)Avj!dnG++^kRZTPm`fV0sM~^Pq+=N zxA7U88@Tc+Ib2$vr*GFCTt8t$JUb)E+%kFuey8szq*PirtlG<8`kzB zk$2&3i7p=o_K$7-k>^4Y*;L z2R_j{#B%j4{-US~Vv{|jJN#Acxs24oX9mRUIeia@FB1YN(+5cs`dmLb;_-^z> zY&d4IEiyo&b?!(lx8nQ0mISiHm$%xgf@8ZFE*?v3v?FOHVbTq&%*o|8pOAqGWU|=5 zXd(l-i3yZ&tk2fl#eSpCbF(0$O3(>R&CD3tADP4SV>zf0+B;EMV?eXEwG!9?TPCi0 z70v6x>;Yr0#4|ivE`*w}G{sqW$d*!~tQ$AJvQoh$dxMH2sDIFjzh$SExn-EbfQB)L3Rm6_TvA!_CV1PpScaWRzWw~PA| zq3)k9ZccVrT!L@=r(29 z-P#r~M)PE7<4k7HSTEtW^Hg(_-O|K2prWvu&A|W}xhSZmrs-ykK3w=_h@Ld)megar zm9*Y-BLYB)XN#j7H=hGY61^yeoma}C*z={)KxVdG_CW!5!yO08)bhR!Bhaj!vXF={ z(c{WYh~J#aUKx;fb@f=p$O@f&?XYmZmp&w1acfaGL|s#p1%K<8YIw*!PvyWF7f)sP z6>f|v&7e_busoj*_Ja3eSXX9yKR$=A_~4}8siCw&Jlt%U33RdK^y_JW$9jV&tAAQfS)ag!7BpSU*B0ypa&OKh<~ z`CT}KR%fUb&VN%G*LpGSZNHa`I!bQTcrTHG)D_U;N?zB7egdh@uKwM+i-Id8{iJjK zL@rp!F6{{_K4I^f@3cbE4?ilqjp1y-2I{XEk6^$Wj8r7}?U29Ab^6F~^mFYz@POnf zGby{J=3gEdTyg-K=KdquEmd>%;+lJ%6#j* z1x35b^LzskkMz~%ga6)0c%(i`ef{9N+UHb%AhAE>!4|$dRqb%R%H~(6{NBRf{v!TP zRbyfb`lTiOtrcYhz*uXm(W#j5Z@>6;pj9jkw$uKv_g8j!y?aCXr!)NR2Caa9BwNm4e*8Q6{tKki zUjcMaHE(QlvVUxN*K4tW?%DXCZGYW-|AT!+qI3Sl0=Pt`SgyC%r?&G=*N17hSEGtd zI`xh~QtaM1=CnjbxPN>{e4TIs5qN^p5`q*Bhso@{6hvJDScU~%fFe!457@`+hQ( z%9i%zouskw)4kQ1*bTFux$kulu?~h`jb3;_W(UaCKt-Hl`o{%_C<-T9AxU zW)I!)8!6Z3Qn(dNB@&|ComD3#4?j^`OVd4Z`1gkthP8M#rosGNZb4u_>tB{(AMI8V zs-+-Dr_5_iGhCi((v%5kQ&qKr$rf>>S(hriyy4!U=^9$`%_|Ppe%1z2d1)g5N?z(z?BNUIitkFsRHW6^O zeF(K)!qL+LqmE0J)}`QQ$84$Fq5?P4dXyojt>mL``lZy6hq&t+O}d7^DKVdB&J@%6 zI69H2MM)Iq!p1Q536J^Qxzw^dAaSFr~R|u}yUD##>tlc9OV6vuQh9 z)5&ncl?@N+<>KB1$!MQ-CO3S_pRmuyN3F79HBHb^=l$JSQM;(65}IOKNI>p-A?Lit zT@ZeH>SYc#N12&dQT3>K_X$)3rUZtRl_K@Y-2uLV>sCG<{L_U7ko?q(0w1Cy#+(Cf z$mV;WnXJF!zC#{s!vZ=XTrF)k6$f$!4U+_c+b%8R}2_Jd=^F8tVFqGior9;)k9tz9M#*qCRXJ%qN6|`0edG;-GAN?oiF$dvk zJaFENuNz9+ZT*-b9i~4#bHl^`tsMxP_H~mpy>#QQJPJW+d(7AL7EfN`_{0WW;XQ-R zE7@S)OvB|F0JH|9-VF8}yik*99 zLwZ4S%9e*_N5Q?lU#|y|SY-TZR6v$U6wxN!Mqk2ee%j0PO~JUVx>kJ<1~E4uN>v|c zW;z>L8>&4tgt+pD`vCzXA61%@XwvZmnXqzycLcKsH&k?E+m-uX`v!nHYCOf(;+BT3 zU6uO}^PZ**t8m_Me6)0mIj&LEkWh?{oHFnorlM&*tyCb>N5;uGOp zV@@nTX0W%XV5AgzClVm?=<>((c}7xNzi$2oX1J*k_kijnjQyZJqd_0xe$UOSq6Fh) zo9g^=I`S=7?@U3b2qhVx(ee0v4yQRN_1w+%HaOf=?@~5_V(dWo1j208Jn@v=uprhX zmhU=Bp=Fp)bg;?YGDWe=wV1m!hN5fGYRt>()VY+5Q!S(^^pa?g5ki};gxDce|5vX^@=G7?a%L1It5?O|x z0vPptJ8~eG5_Q>yA-LpQ=1?AtL{cruKw_@{vR~po zhtAH}$VP*Vt}gP3b>hX0U0$5yU-YLJaPwEQ+lYh4E(eolZ6eKXoModA)+mYO=cG?qMe_G$V4%t0yY*1 zvr)mja>I-;u%ut=+z%E2-&Y?=K015bOp2%3;5Q^E&{_u?U1v>xVZQPS7hAMEnpH4z zo&+aEl+kdzmrYXV`LVF?3exi1*{AP#_^?U$WM(|6nl}lB>(X*wnq{urJ2yg%Pk|-UA8TQG-$c?ZQ_R5LLc0kL$xgz1wwp9txWt5t_vzP`UeBOu$MGDQ%+Bd zH?OoG$wsW%RoiAH>ejbt?5V%HIcm+m^wVPf1eyak&CQx>$EnafyRPeQF2n_wHs5

4U7uG1mB>E7cby|mnBye2Vs}Ys-tfjQz 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�m1Q5Wd$cKK3W>&3>-rdE6akxV5Pqzt2SE@ZCeseniWz?0R}EU^pEqM#I%pW z4be9_*j(c)NKS^IZhyhW^^ZHq{4fZBb0~Xx`N1j<0sB&1A`^yWqHeoEwn?mz&6x^B z0t7)GT@WnX zhvC>52*!%NG{g1fM{i@42kuONS~fTQ8o$r@Oy-Ys08H@lO(d93y3j>l&V_Ig*(}B0 z50hyJKBi(Id`|x=jx+i7K#l?≺b~toQuXkv|R!_awkJb)2<+w%Ol*-29m(3Y1Gd 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%0D&|s9}Ejlvhhi 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 literal 0 HcmV?d00001 diff --git a/pic/sword-menu-edit.png b/pic/sword-menu-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..a3bd0a1e2badc6c7c61d6cd03590c49d5700edea GIT binary patch literal 73355 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

?kf_R&w8h?rVWS2bwG5 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%0Dl*XE)&{0N9I&zr?-BF4G0{gnl&ZDSPZ1 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 p^){I0>HNGjBppW9o%9k8! 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

X!U=;??@`YCSZ@+v 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 Y-{8@$A@ui(BLfh4y85}Sb4q9e03CSre*gdg literal 0 HcmV?d00001 diff --git a/pic/sword-user.png b/pic/sword-user.png new file mode 100644 index 0000000000000000000000000000000000000000..3414a334c9dd48b650342be3de114726d6cbf061 GIT binary patch literal 76295 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 kPX#> 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bb9ac04 --- /dev/null +++ b/pom.xml @@ -0,0 +1,204 @@ + + + 4.0.0 + + org.springblade + blade-tool + 1.0.0-RC1 + pom + + + 1.0.0-RC1 + + 1.8 + 3.8.0 + 2.9.2 + 1.5.21 + 1.8.8 + 3.0.6 + 4.0.1 + 1.6.0 + 3.4.2 + 2.0.2 + + 2.0.7.RELEASE + Finchley.SR2 + Cairo-SR5 + + + + blade-core-boot + blade-core-launch + blade-core-secure + blade-core-tool + blade-core-log + blade-core-mybatis + blade-core-swagger + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + io.spring.platform + platform-bom + ${spring.platform.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-test + test + + + de.codecentric + spring-boot-admin-starter-client + ${spring.boot.admin.version} + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + org.springframework.cloud + spring-cloud-starter-consul-discovery + + + org.springframework.retry + spring-retry + + + org.projectlombok + lombok + provided + + + org.springframework.boot + spring-boot-devtools + true + + + + + + ${project.name} + + + src/main/resources + + + src/main/java + + **/*.xml + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.plugin.version} + + ${java.version} + ${java.version} + UTF-8 + + -parameters + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + true + + + + compile + + jar + + + + + + + + + + aliyun-repos + http://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + + + + aliyun-plugin + http://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + + + + release + Release Repository + http://nexus.gitee.ltd/repository/maven-releases/ + + + +

r7%)iW9ix{ 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 literal 0 HcmV?d00001 diff --git a/pic/sword-locale-us.png b/pic/sword-locale-us.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb8f32545576d39bb24482beb81590f37e390f5 GIT binary patch literal 109096 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