田源
2024-04-08 8e378a11ac6371c843d53b541008eb6986727f02
Merge remote-tracking branch 'origin/master'
已修改8个文件
已删除256个文件
已添加45个文件
11384 ■■■■■ 文件已修改
.idea/modules.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/flatlaf-2.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/icegridgui.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/jgoodies-common-1.8.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/jgoodies-looks-2.5.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/jgraph.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/jgraphx-3.1.0.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/nativeskin.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/pinyin4j-2.5.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/plt-client.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/plt-clientbase.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/poi-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/poi-ooxml-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/poi-ooxml-schemas-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/poi-scratchpad-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/protege35.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/skinlf.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/swingx-1.6.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/swixml.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/client/uitheme-1.3.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/commons-lang3-3.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/dom4j-1.6.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/fastjson-1.2.83.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/freemarker.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/icegridgui.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/junit-4.8.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/log4j-api-2.12.4.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/log4j-core-2.12.4.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/mail.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/META-INF/MANIFEST.MF 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/ServiceNames.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/annotaion/CustomAnnotaion.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/annotaion/CustomAnnotaionHelper.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/annotaion/MethodTypeAnnotation.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/exception/LocaleCommonDisplay.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/exception/ORAUniqueProperties.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/exception/VciException.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/exception/VciExceptionTool.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/file/FileDigest.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/locale/LocaleDisplay.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/log/LogByType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/log/LogType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/log/ServerWithLog4j.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/AbstractEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/AbstractHistorizable.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/Historizable.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/QueryParam.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/QueryResult.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/objects/UserEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/constants/PLDefinationConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/constants/PRMConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/constants/TemplateTypeConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/AreaType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/ComponentType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/ControlType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/GetByType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/PortalVIType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/enums/PortalVITypeFlag.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/portal/utils/PortalUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/interfaces/IParserFactory.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/CItemRelation.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/ChildrenInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/ComparatorOrderInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/Condition.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/ConditionItem.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/Connector.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/LeafInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/LeafValue.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/Operator.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/OrderInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/PageInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/ParserHelper.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/QTConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/QueryTemplate.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/Symbol.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/qt/object/Version.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/resource/CommonProperties.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/resource/IceClientProperties.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/timer/VCITimeInterface.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/util/CollectionUtils$EnumerationIterator.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/util/CollectionUtils.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/util/IceProxyUtility.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/ClassLoaderUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/Converter.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/ObjectUtility.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID20.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID36.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID8.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/common/utility/SnowFlake.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/mw/ClientContextVariable.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/mw/IInvocationContext.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/mw/InvocationUtility.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/mw/LaunchModeEnum.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/AttributeConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/BusinessConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/FileObjectType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/LinkConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/LinkTypeConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/OmdConstants.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/constants/SystemAttribute.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/dataType/VTDataType.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/objects/OtherInfo.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/utils/AbComparator.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/utils/BTComparator.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/utils/LinkTypeComparator.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/com/vci/omd/utils/ObjectTool.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/properties/conf.properties 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-common/properties/log4j2.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/plt-slice.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/common/spring-core-3.2.0.RELEASE.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/BOFService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/CacheService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/FrameService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/OMDService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/OQService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/ServiceBase.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/META-INF/MANIFEST.MF 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/UIBoxService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/PortalServiceImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionClsCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionParamCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ButtonParamCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ComponentBtnCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/ComponentCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/PortalVICacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/TabPageCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/UICacheBaseUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/UICacheNames.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/cache/UIContextCacheUtil.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionClsEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionParamEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLCommandParameterEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLPageDefinationEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTabButtonEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTabPageEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTypeActionEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PLUILayoutEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/PortalVIEntityDao.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionClsEntityDaoImp.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionParamEntityDaoImp.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLCommandParameterEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLPageDefinationEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTabButtonEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTabPageEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTypeActionEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLUILayoutEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PortalVIEntityDaoImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/delegate/IPortalServiceDelegate.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate$1.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate$2.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionClsEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionParamEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLCommandParameterEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLPageDefinationEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTabButtonEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTabPageEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTypeActionEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PLUILayoutEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/entity/PortalVIEntity.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionClsEntity.hbm.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionEntity.hbm.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionParamEntity.hbm.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLCommandParameterEntity.hbm.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLPageDefinationEntity.hbm.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTabButtonEntity.hbm.xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTabPageEntity.hbm.xml 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTypeActionEntity.hbm.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLUILayoutEntity.hbm.xml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/hbm/PortalVIEntity.hbm.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLActionEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLCommandParameterEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLPageDefinationEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLTabButtonEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLTabPageEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLTypeActionEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PLUILayoutEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/PortalVIEntityService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/service/UIDeleteService.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/com/vci/server/portal/tools/ServerTool.class 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/properties/PLMUIService.properties 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/properties/PLMUIService_zh.properties 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/properties/PLMUIService_zhNative.properties 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/UIService/properties/hibernate.map.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/VciServiceMain.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/VolumeService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/WFPlugins.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/service/WFService.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/IKAnalyzer2012FF_u1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/XmlSchema-1.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/activation.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/antlr-2.7.6.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/avalon-framework-4.1.5.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/axis-ant.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/axis.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/bsf-2.3.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/bsh.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/c3p0-0.9.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-codec-1.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-collections-3.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-dbcp-1.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-discovery-0.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-fileupload-1.2.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-httpclient-3.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-io-2.0.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-logging-1.0.4.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-net-1.4.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/commons-pool2-2.6.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/geronimo-stax-api_1.0_spec-1.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/guava-20.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/hibernate-jpa-2.0-api-1.0.1.Final.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/hibernate3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/inforbroker-core-5.1.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/javassist-3.12.0.GA.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jaxen-1.1-beta-9.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jaxrpc.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jbpm-4.3.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jcalendar-1.3.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jcommon-1.0.17.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jdom-1.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jdsl.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jedis-2.9.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jee-management-1.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jfreechart-1.0.14.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jms-1.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/jta-1.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/juel-engine.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/juel-impl.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/juel.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/livetribe-jsr223.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/logkit-1.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/ognl-2.6.11.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/ojdbc8.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/picocontainer-1.2.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/plugin.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/poi-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/poi-ooxml-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/poi-ooxml-schemas-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/poi-scratchpad-3.9-20121203.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/portalcustom.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/proxool-0.8.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/quartz-all-1.8.6.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/rsyntax.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/saaj.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/sapjco.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/slf4j-api-1.7.14.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/slf4j-jdk14-1.7.14.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/xml-apis.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/xmlbeans-2.3.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/xmlsec-1.3.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Bin/lib/thrid/xstream-1.3.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/pom.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/pom.xml 401 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/controller/WebUIDataController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/UIEngineServiceI.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java 501 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/BeanUtil.java 424 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ClassUtil.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConvertUtil.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java 634 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java 433 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java 2140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/PlatformClientUtil.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ReflectUtil.java 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java 1560 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Unchecked.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/UrlUtil.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BeanProperty.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanCopier.java 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanCopierKey.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMap.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMapEmitter.java 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMapKey.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/CopyProperty.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/BladeConversionService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/BladeConverter.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/EnumToStringConverter.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/StringToEnumConverter.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedCallable.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedComparator.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedConsumer.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedFunction.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedRunnable.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedSupplier.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java 705 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/modules.xml
@@ -3,6 +3,10 @@
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/PLTWEB.iml" filepath="$PROJECT_DIR$/.idea/PLTWEB.iml" />
      <module fileurl="file://$PROJECT_DIR$/Source/platformProject/platform-parent.iml" filepath="$PROJECT_DIR$/Source/platformProject/platform-parent.iml" />
      <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-server-starter/vci-platform-server-starter.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-server-starter/vci-platform-server-starter.iml" />
      <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-starter/vci-platform-starter.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-starter/vci-platform-starter.iml" />
      <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-web/vci-platform-web.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-web/vci-platform-web.iml" />
    </modules>
  </component>
</project>
Bin/lib/client/flatlaf-2.3.jar
Binary files differ
Bin/lib/client/icegridgui.jar
Binary files differ
Bin/lib/client/jgoodies-common-1.8.1.jar
Binary files differ
Bin/lib/client/jgoodies-looks-2.5.3.jar
Binary files differ
Bin/lib/client/jgraph.jar
Binary files differ
Bin/lib/client/jgraphx-3.1.0.0.jar
Binary files differ
Bin/lib/client/nativeskin.jar
Binary files differ
Bin/lib/client/pinyin4j-2.5.0.jar
Binary files differ
Bin/lib/client/plt-client.jar
Binary files differ
Bin/lib/client/plt-clientbase.jar
Binary files differ
Bin/lib/client/poi-3.9-20121203.jar
Binary files differ
Bin/lib/client/poi-ooxml-3.9-20121203.jar
Binary files differ
Bin/lib/client/poi-ooxml-schemas-3.9-20121203.jar
Binary files differ
Bin/lib/client/poi-scratchpad-3.9-20121203.jar
Binary files differ
Bin/lib/client/protege35.jar
Binary files differ
Bin/lib/client/skinlf.jar
Binary files differ
Bin/lib/client/swingx-1.6.1.jar
Binary files differ
Bin/lib/client/swixml.jar
Binary files differ
Bin/lib/client/uitheme-1.3.1.jar
Binary files differ
Bin/lib/common/commons-lang3-3.1.jar
Binary files differ
Bin/lib/common/dom4j-1.6.1.jar
Binary files differ
Bin/lib/common/fastjson-1.2.83.jar
Binary files differ
Bin/lib/common/freemarker.jar
Binary files differ
Bin/lib/common/icegridgui.jar
Binary files differ
Bin/lib/common/junit-4.8.jar
Binary files differ
Bin/lib/common/log4j-api-2.12.4.jar
Binary files differ
Bin/lib/common/log4j-core-2.12.4.jar
Binary files differ
Bin/lib/common/mail.jar
Binary files differ
Bin/lib/common/plt-common.jar
Binary files differ
Bin/lib/common/plt-common/META-INF/MANIFEST.MF
ÎļþÒÑɾ³ý
Bin/lib/common/plt-common/com/vci/common/ServiceNames.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/annotaion/CustomAnnotaion.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/annotaion/CustomAnnotaionHelper.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/annotaion/MethodTypeAnnotation.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/exception/LocaleCommonDisplay.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/exception/ORAUniqueProperties.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/exception/VciException.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/exception/VciExceptionTool.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/file/FileDigest.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/locale/LocaleDisplay.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/log/LogByType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/log/LogType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/log/ServerWithLog4j.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/AbstractEntity.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/AbstractHistorizable.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/Historizable.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/QueryParam.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/QueryResult.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/objects/UserEntity.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/constants/PLDefinationConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/constants/PRMConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/constants/TemplateTypeConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/AreaType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/ComponentType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/ControlType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/GetByType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/PortalVIType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/enums/PortalVITypeFlag.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/portal/utils/PortalUtil.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/interfaces/IParserFactory.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/CItemRelation.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/ChildrenInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/ComparatorOrderInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/Condition.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/ConditionItem.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/Connector.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/LeafInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/LeafValue.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/Operator.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/OrderInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/PageInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/ParserHelper.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/QTConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/QueryTemplate.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/Symbol.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/qt/object/Version.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/resource/CommonProperties.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/resource/IceClientProperties.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/timer/VCITimeInterface.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/util/CollectionUtils$EnumerationIterator.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/util/CollectionUtils.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/util/IceProxyUtility.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/ClassLoaderUtil.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/Converter.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/ObjectUtility.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID20.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID36.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/RandomGUID8.class
Binary files differ
Bin/lib/common/plt-common/com/vci/common/utility/SnowFlake.class
Binary files differ
Bin/lib/common/plt-common/com/vci/mw/ClientContextVariable.class
Binary files differ
Bin/lib/common/plt-common/com/vci/mw/IInvocationContext.class
Binary files differ
Bin/lib/common/plt-common/com/vci/mw/InvocationUtility.class
Binary files differ
Bin/lib/common/plt-common/com/vci/mw/LaunchModeEnum.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/AttributeConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/BusinessConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/FileObjectType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/LinkConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/LinkTypeConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/OmdConstants.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/constants/SystemAttribute.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/dataType/VTDataType.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/objects/OtherInfo.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/utils/AbComparator.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/utils/BTComparator.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/utils/LinkTypeComparator.class
Binary files differ
Bin/lib/common/plt-common/com/vci/omd/utils/ObjectTool.class
Binary files differ
Bin/lib/common/plt-common/properties/conf.properties
ÎļþÒÑɾ³ý
Bin/lib/common/plt-common/properties/log4j2.xml
ÎļþÒÑɾ³ý
Bin/lib/common/plt-slice.jar
Binary files differ
Bin/lib/common/spring-core-3.2.0.RELEASE.jar
Binary files differ
Bin/lib/service/BOFService.jar
Binary files differ
Bin/lib/service/CacheService.jar
Binary files differ
Bin/lib/service/FrameService.jar
Binary files differ
Bin/lib/service/OMDService.jar
Binary files differ
Bin/lib/service/OQService.jar
Binary files differ
Bin/lib/service/ServiceBase.jar
Binary files differ
Bin/lib/service/UIService.jar
Binary files differ
Bin/lib/service/UIService/META-INF/MANIFEST.MF
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/UIBoxService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/PortalServiceImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionClsCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ActionParamCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ButtonParamCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ComponentBtnCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/ComponentCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/PortalVICacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/TabPageCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/UICacheBaseUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/UICacheNames.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/cache/UIContextCacheUtil.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionClsEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLActionParamEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLCommandParameterEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLPageDefinationEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTabButtonEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTabPageEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLTypeActionEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PLUILayoutEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/PortalVIEntityDao.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionClsEntityDaoImp.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLActionParamEntityDaoImp.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLCommandParameterEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLPageDefinationEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTabButtonEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTabPageEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLTypeActionEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PLUILayoutEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/dao/impl/PortalVIEntityDaoImpl.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/delegate/IPortalServiceDelegate.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate$1.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate$2.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/delegate/PortalServiceDelegate.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionClsEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLActionParamEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLCommandParameterEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLPageDefinationEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTabButtonEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTabPageEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLTypeActionEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PLUILayoutEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/entity/PortalVIEntity.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionClsEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLActionParamEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLCommandParameterEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLPageDefinationEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTabButtonEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTabPageEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLTypeActionEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PLUILayoutEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/hbm/PortalVIEntity.hbm.xml
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/com/vci/server/portal/service/PLActionEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLCommandParameterEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLPageDefinationEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLTabButtonEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLTabPageEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLTypeActionEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PLUILayoutEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/PortalVIEntityService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/service/UIDeleteService.class
Binary files differ
Bin/lib/service/UIService/com/vci/server/portal/tools/ServerTool.class
Binary files differ
Bin/lib/service/UIService/properties/PLMUIService.properties
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/properties/PLMUIService_zh.properties
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/properties/PLMUIService_zhNative.properties
ÎļþÒÑɾ³ý
Bin/lib/service/UIService/properties/hibernate.map.xml
ÎļþÒÑɾ³ý
Bin/lib/service/VciServiceMain.jar
Binary files differ
Bin/lib/service/VolumeService.jar
Binary files differ
Bin/lib/service/WFPlugins.jar
Binary files differ
Bin/lib/service/WFService.jar
Binary files differ
Bin/lib/thrid/IKAnalyzer2012FF_u1.jar
Binary files differ
Bin/lib/thrid/XmlSchema-1.1.jar
Binary files differ
Bin/lib/thrid/activation.jar
Binary files differ
Bin/lib/thrid/antlr-2.7.6.jar
Binary files differ
Bin/lib/thrid/avalon-framework-4.1.5.jar
Binary files differ
Bin/lib/thrid/axis-ant.jar
Binary files differ
Bin/lib/thrid/axis.jar
Binary files differ
Bin/lib/thrid/bsf-2.3.0.jar
Binary files differ
Bin/lib/thrid/bsh.jar
Binary files differ
Bin/lib/thrid/c3p0-0.9.1.jar
Binary files differ
Bin/lib/thrid/commons-codec-1.3.jar
Binary files differ
Bin/lib/thrid/commons-collections-3.1.jar
Binary files differ
Bin/lib/thrid/commons-dbcp-1.1.jar
Binary files differ
Bin/lib/thrid/commons-discovery-0.2.jar
Binary files differ
Bin/lib/thrid/commons-fileupload-1.2.2.jar
Binary files differ
Bin/lib/thrid/commons-httpclient-3.0.jar
Binary files differ
Bin/lib/thrid/commons-io-2.0.1.jar
Binary files differ
Bin/lib/thrid/commons-logging-1.0.4.jar
Binary files differ
Bin/lib/thrid/commons-net-1.4.1.jar
Binary files differ
Bin/lib/thrid/commons-pool2-2.6.2.jar
Binary files differ
Bin/lib/thrid/geronimo-stax-api_1.0_spec-1.0.jar
Binary files differ
Bin/lib/thrid/guava-20.0.jar
Binary files differ
Bin/lib/thrid/hibernate-jpa-2.0-api-1.0.1.Final.jar
Binary files differ
Bin/lib/thrid/hibernate3.jar
Binary files differ
Bin/lib/thrid/inforbroker-core-5.1.0.jar
Binary files differ
Bin/lib/thrid/javassist-3.12.0.GA.jar
Binary files differ
Bin/lib/thrid/jaxen-1.1-beta-9.jar
Binary files differ
Bin/lib/thrid/jaxrpc.jar
Binary files differ
Bin/lib/thrid/jbpm-4.3.2.jar
Binary files differ
Bin/lib/thrid/jcalendar-1.3.3.jar
Binary files differ
Bin/lib/thrid/jcommon-1.0.17.jar
Binary files differ
Bin/lib/thrid/jdom-1.0.jar
Binary files differ
Bin/lib/thrid/jdsl.jar
Binary files differ
Bin/lib/thrid/jedis-2.9.0.jar
Binary files differ
Bin/lib/thrid/jee-management-1.1.jar
Binary files differ
Bin/lib/thrid/jfreechart-1.0.14.jar
Binary files differ
Bin/lib/thrid/jms-1.1.jar
Binary files differ
Bin/lib/thrid/jta-1.1.jar
Binary files differ
Bin/lib/thrid/juel-engine.jar
Binary files differ
Bin/lib/thrid/juel-impl.jar
Binary files differ
Bin/lib/thrid/juel.jar
Binary files differ
Bin/lib/thrid/livetribe-jsr223.jar
Binary files differ
Bin/lib/thrid/logkit-1.2.jar
Binary files differ
Bin/lib/thrid/ognl-2.6.11.jar
Binary files differ
Bin/lib/thrid/ojdbc8.jar
Binary files differ
Bin/lib/thrid/picocontainer-1.2.jar
Binary files differ
Bin/lib/thrid/plugin.jar
Binary files differ
Bin/lib/thrid/poi-3.9-20121203.jar
Binary files differ
Bin/lib/thrid/poi-ooxml-3.9-20121203.jar
Binary files differ
Bin/lib/thrid/poi-ooxml-schemas-3.9-20121203.jar
Binary files differ
Bin/lib/thrid/poi-scratchpad-3.9-20121203.jar
Binary files differ
Bin/lib/thrid/portalcustom.jar
Binary files differ
Bin/lib/thrid/proxool-0.8.3.jar
Binary files differ
Bin/lib/thrid/quartz-all-1.8.6.jar
Binary files differ
Bin/lib/thrid/rsyntax.jar
Binary files differ
Bin/lib/thrid/saaj.jar
Binary files differ
Bin/lib/thrid/sapjco.jar
Binary files differ
Bin/lib/thrid/slf4j-api-1.7.14.jar
Binary files differ
Bin/lib/thrid/slf4j-jdk14-1.7.14.jar
Binary files differ
Bin/lib/thrid/xml-apis.jar
Binary files differ
Bin/lib/thrid/xmlbeans-2.3.0.jar
Binary files differ
Bin/lib/thrid/xmlsec-1.3.0.jar
Binary files differ
Bin/lib/thrid/xstream-1.3.1.jar
Binary files differ
Source/platformProject/pom.xml
@@ -20,6 +20,8 @@
        <old.spring.version>3.2.0.RELEASE</old.spring.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <lombok.version>1.18.22</lombok.version>
        <jackson.version>2.13.3</jackson.version>
    </properties>
    <!-- <distributionManagement>
Source/platformProject/vci-platform-web/pom.xml
@@ -12,183 +12,192 @@
    <artifactId>vci-platform-web</artifactId>
    <dependencies>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-starter-parent</artifactId>
           <version>1.0-SNAPSHOT</version>
           <type>pom</type>
       </dependency>
       <dependency>
           <groupId>com.vci.corba</groupId>
           <artifactId>plt-slice</artifactId>
           <version>1.0.RELEASE</version>
       </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-starter-parent</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.vci.corba</groupId>
            <artifactId>plt-slice</artifactId>
            <version>1.0.RELEASE</version>
        </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-starter-web</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>org.apache.logging.log4j</groupId>
                   <artifactId>*</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>com.google.guava</groupId>
                   <artifactId>guava</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-starter-corba</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency><!--文件的信息-->
           <groupId>com.vci</groupId>
           <artifactId>vci-file-api</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>org.apache.logging.log4j</groupId>
                   <artifactId>*</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-file-integration</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-starter-word</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>com.vci</groupId>
                   <artifactId>vci-starter-web</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-starter-poi</artifactId>
           <version>1.0-SNAPSHOT</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>com.vci</groupId>
                   <artifactId>vci-starter-web</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>eu.bitwalker</groupId>
           <artifactId>UserAgentUtils</artifactId>
           <version>1.20</version>
       </dependency>
       <!--开启 cache ç¼“å­˜ -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-cache</artifactId>
           <version>2.1.3.RELEASE</version>
       </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-starter-web</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-starter-corba</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency><!--文件的信息-->
            <groupId>com.vci</groupId>
            <artifactId>vci-file-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-file-integration</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-starter-word</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.vci</groupId>
                    <artifactId>vci-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-starter-poi</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.vci</groupId>
                    <artifactId>vci-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.20</version>
        </dependency>
        <!--开启 cache ç¼“å­˜ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
       <!-- ehcache缓存 -->
       <dependency>
           <groupId>net.sf.ehcache</groupId>
           <artifactId>ehcache</artifactId>
           <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
       </dependency>
        <!-- ehcache缓存 -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
        </dependency>
       <dependency><!--java bean å’Œxml转换-->
           <groupId>com.thoughtworks.xstream</groupId>
           <artifactId>xstream</artifactId>
           <version>1.4.10</version>
       </dependency>
       <dependency><!--代码生成器所需模板-->
           <artifactId>velocity</artifactId>
           <groupId>org.apache.velocity</groupId>
           <version>1.7</version>
       </dependency>
       <dependency><!--数据库操作工具-->
           <groupId>com.vci.platform</groupId>
           <artifactId>ddlTool-client</artifactId>
           <version>${vciplt.version}</version>
       </dependency>
       <dependency><!--数据库操作工具-->
           <groupId>com.vci.platform</groupId>
           <artifactId>ddlTool-common</artifactId>
           <version>${vciplt.version}</version>
       </dependency>
       <dependency>
           <groupId>com.vci.client</groupId>
           <artifactId>plt-clientbase</artifactId>
           <version>1.0.RELEASE</version>
       </dependency>
       <dependency>
           <groupId>com.zeroc</groupId>
           <artifactId>icegridgui</artifactId>
           <version>1.0.RELEASE</version>
       </dependency>
        <dependency><!--java bean å’Œxml转换-->
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.10</version>
        </dependency>
        <dependency><!--代码生成器所需模板-->
            <artifactId>velocity</artifactId>
            <groupId>org.apache.velocity</groupId>
            <version>1.7</version>
        </dependency>
        <dependency><!--数据库操作工具-->
            <groupId>com.vci.platform</groupId>
            <artifactId>ddlTool-client</artifactId>
            <version>${vciplt.version}</version>
        </dependency>
        <dependency><!--数据库操作工具-->
            <groupId>com.vci.platform</groupId>
            <artifactId>ddlTool-common</artifactId>
            <version>${vciplt.version}</version>
        </dependency>
        <dependency>
            <groupId>com.vci.client</groupId>
            <artifactId>plt-clientbase</artifactId>
            <version>1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>icegridgui</artifactId>
            <version>1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.vci.common</groupId>
            <artifactId>plt-common</artifactId>
            <version>1.0.RELEASE</version>
        </dependency>
       <dependency>
           <groupId>com.vci</groupId>
           <artifactId>vci-platform-starter</artifactId>
           <version>2022.1-SNAPSHOT</version>
       </dependency>
        <dependency>
            <groupId>com.vci</groupId>
            <artifactId>vci-platform-starter</artifactId>
            <version>2022.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.11</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
       <dependency>
           <groupId>org.reflections</groupId>
           <artifactId>reflections</artifactId>
           <version>0.9.11</version>
       </dependency>
       <!--redis start-->
       <dependency>
           <groupId>org.springframework.data</groupId>
           <artifactId>spring-data-redis</artifactId>
           <version>2.1.5.RELEASE</version>
       </dependency>
       <dependency>
           <groupId>redis.clients</groupId>
           <artifactId>jedis</artifactId>
           <version>2.9.0</version>
       </dependency>
       <!--redis end-->
   </dependencies>
        <!--redis start-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--redis end-->
    </dependencies>
    <build>
        <finalName>vci-platform-web</finalName>
@@ -211,34 +220,34 @@
                    </excludes>
                </configuration>
            </plugin>
<!--            <plugin>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
<!--                <configuration>-->
<!--                    &lt;!&ndash;重写包含依赖,包含不存在的依赖,jar里没有pom里的依赖&ndash;&gt;-->
<!--                    <includes>-->
<!--                        <include>-->
<!--                            <groupId>null</groupId>-->
<!--                            <artifactId>null</artifactId>-->
<!--                        </include>-->
<!--                    </includes>-->
<!--                    <layout>ZIP</layout>-->
<!--                    &lt;!&ndash;使用外部配置文件,jar包里没有资源文件&ndash;&gt;-->
<!--                    <addResources>true</addResources>-->
<!--                </configuration>-->
<!--                <executions>-->
<!--                    <execution>-->
<!--                        <goals>-->
<!--                            <goal>repackage</goal>-->
<!--                        </goals>-->
<!--                        <configuration>-->
<!--                            &lt;!&ndash;配置jar包特殊标识 é…ç½®åŽï¼Œä¿ç•™åŽŸæ–‡ä»¶ï¼Œç”Ÿæˆæ–°æ–‡ä»¶ *-run.jar &ndash;&gt;-->
<!--                            &lt;!&ndash;配置jar包特殊标识 ä¸é…ç½®ï¼ŒåŽŸæ–‡ä»¶å‘½åä¸º *.jar.original,生成新文件 *.jar &ndash;&gt;-->
<!--                            &lt;!&ndash;<classifier>run</classifier>&ndash;&gt;-->
<!--                        </configuration>-->
<!--                    </execution>-->
<!--                </executions>-->
<!--            </plugin>-->
            <!--            <plugin>-->
            <!--                <groupId>org.springframework.boot</groupId>-->
            <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
            <!--                <configuration>-->
            <!--                    &lt;!&ndash;重写包含依赖,包含不存在的依赖,jar里没有pom里的依赖&ndash;&gt;-->
            <!--                    <includes>-->
            <!--                        <include>-->
            <!--                            <groupId>null</groupId>-->
            <!--                            <artifactId>null</artifactId>-->
            <!--                        </include>-->
            <!--                    </includes>-->
            <!--                    <layout>ZIP</layout>-->
            <!--                    &lt;!&ndash;使用外部配置文件,jar包里没有资源文件&ndash;&gt;-->
            <!--                    <addResources>true</addResources>-->
            <!--                </configuration>-->
            <!--                <executions>-->
            <!--                    <execution>-->
            <!--                        <goals>-->
            <!--                            <goal>repackage</goal>-->
            <!--                        </goals>-->
            <!--                        <configuration>-->
            <!--                            &lt;!&ndash;配置jar包特殊标识 é…ç½®åŽï¼Œä¿ç•™åŽŸæ–‡ä»¶ï¼Œç”Ÿæˆæ–°æ–‡ä»¶ *-run.jar &ndash;&gt;-->
            <!--                            &lt;!&ndash;配置jar包特殊标识 ä¸é…ç½®ï¼ŒåŽŸæ–‡ä»¶å‘½åä¸º *.jar.original,生成新文件 *.jar &ndash;&gt;-->
            <!--                            &lt;!&ndash;<classifier>run</classifier>&ndash;&gt;-->
            <!--                        </configuration>-->
            <!--                    </execution>-->
            <!--                </executions>-->
            <!--            </plugin>-->
        </plugins>
    </build>
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/controller/WebUIDataController.java
@@ -43,6 +43,7 @@
     * @return åˆ—表数据
     */
    @PostMapping("/dataGridQuery")
    @VciUnCheckRight
    @VciBusinessLog(operateName = "列表数据的查询",description = "${param.btmname}里的${param.tableDefineId}")
    public DataGrid dataGrid(UIDataGridQuery dataGridQuery){
        return uiDataService.getDataForGrid(dataGridQuery);
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/UIEngineServiceI.java
@@ -1,13 +1,10 @@
package com.vci.web.service;
import com.vci.corba.common.VCIError;
import com.vci.corba.portal.data.PLAction;
import com.vci.corba.portal.data.PLTabButton;
import com.vci.corba.portal.data.PLUILayout;
import com.vci.corba.portal.data.PortalVI;
import com.vci.corba.portal.data.PLAction;
import com.vci.web.pageModel.*;
import plm.corba.portal.PLPageLayoutDefination;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -127,14 +124,14 @@
     * @param actions æ•°æ®å¯¹è±¡
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    List<UIActionVO> actionDO2VOs(Collection<com.vci.corba.portal.data.PLAction> actions);
    List<UIActionVO> actionDO2VOs(Collection<PLAction> actions);
    /**
     * action数据对象转换为显示对象
     * @param action æ•°æ®å¯¹è±¡
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    UIActionVO actionDO2VO(com.vci.corba.portal.data.PLAction action);
    UIActionVO actionDO2VO(PLAction action);
    /**
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
@@ -5,7 +5,6 @@
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.frameworkcore.lcstatuspck.ReleaseDataLCStatus;
import com.vci.starter.revision.bo.TreeWrapperOptions;
import com.vci.starter.revision.service.RevisionModelUtil;
import com.vci.starter.web.annotation.bus.VciChangeDataAfter;
import com.vci.starter.web.annotation.bus.VciChangeDataBefore;
import com.vci.starter.web.annotation.bus.VciChangeDataPlugin;
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
@@ -6,6 +6,7 @@
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.vci.client.common.providers.ServiceProvider;
import com.vci.corba.common.VCIError;
import com.vci.corba.portal.data.PLTabButton;
import com.vci.corba.portal.data.PLUILayout;
import com.vci.starter.web.annotation.log.VciUnLog;
import com.vci.starter.web.exception.VciBaseException;
@@ -39,6 +40,11 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.vci.corba.portal.data.PortalVI;
import com.vci.corba.portal.data.PLTabPage;
import com.vci.corba.portal.data.PLAction;
import com.vci.corba.portal.data.PLPageDefination;
import com.vci.corba.portal.data.PLCommandParameter;
import plm.corba.portal.*;
import java.util.*;
@@ -53,7 +59,7 @@
 *
 */
@Service
public class UIEngineServiceImpl  implements UIEngineServiceI {
public class UIEngineServiceImpl implements UIEngineServiceI {
    /**
     * æ˜¯å¦ä»Žç¼“存中查询
@@ -137,7 +143,8 @@
    public void checkInvalidXmlVI() {
        PortalVI[] portalVIS = null;
        try {
            portalVIS = platformClientUtil.getPortalService().getAllPortalVI();
            portalVIS = ServiceProvider.getUIService().getAllPortalVI();
            // portalVIS = platformClientUtil.getPortalService().getAllPortalVI();
        } catch (VCIError vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
@@ -159,13 +166,13 @@
    @Override
    @VciUnLog
    public List<UIFormDefineVO> selectAllForm() {
        com.vci.corba.portal.data.PortalVI[] portalVIS = null;
        PortalVI[] portalVIS = null;
        try {
            portalVIS = ServiceProvider.getUIService().getAllPortalVI();
        } catch (VCIError vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        List<com.vci.corba.portal.data.PortalVI> portalVIList = Arrays.stream(portalVIS).filter(portal -> 1 == portal.viType).collect(Collectors.toList());
        List<PortalVI> portalVIList = Arrays.stream(portalVIS).filter(portal -> 1 == portal.viType).collect(Collectors.toList());
        return formDO2VOs(portalVIList);
    }
@@ -187,9 +194,9 @@
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    @Override
    public List<UIFormDefineVO> formDO2VOs(Collection<com.vci.corba.portal.data.PortalVI> portalVIS) {
    public List<UIFormDefineVO> formDO2VOs(Collection<PortalVI> portalVIS) {
        List<UIFormDefineVO> formDefineVOList = new ArrayList<>();
        Optional.ofNullable(portalVIS).orElseGet(()->new ArrayList<com.vci.corba.portal.data.PortalVI>()).stream().forEach(portal->{
        Optional.ofNullable(portalVIS).orElseGet(()->new ArrayList<PortalVI>()).stream().forEach(portal->{
            try {
                UIFormDefineVO defineVO = formDO2VO(portal);
                formDefineVOList.add(defineVO);
@@ -210,7 +217,7 @@
     */
    @Override
    @VciUnLog
    public UIFormDefineVO formDO2VO(com.vci.corba.portal.data.PortalVI portal) {
    public UIFormDefineVO formDO2VO(PortalVI portal) {
        if(portal == null ||StringUtils.isBlank(portal.prm)){
            throw new VciBaseException("表单可能不存在,因为未能获取到它的信息");
        }
@@ -410,7 +417,7 @@
            return null;
        }
        if(!QUERY_BY_CACHE){
            com.vci.corba.portal.data.PortalVI portalVI = null;
            PortalVI portalVI = null;
            try {
                portalVI = ServiceProvider.getUIService().getPortalVIByTypeNameAndVIName(btmId, id);
            } catch (VCIError vciError) {
@@ -453,13 +460,13 @@
    @Cacheable(value = VCI_OBJECT_SERVICE,key = CacheKeyConstant.ALL_TABLE,unless = "#result == null")
    @VciUnLog
    public List<UITableDefineVO> selectAllTable() {
        com.vci.corba.portal.data.PortalVI[] portalVIS = null;
        PortalVI[] portalVIS = null;
        try {
            portalVIS = ServiceProvider.getUIService().getAllPortalVI();
        } catch (VCIError vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        List<com.vci.corba.portal.data.PortalVI> portalVIList = Arrays.stream(portalVIS).filter(portal -> 0 == portal.viType).collect(Collectors.toList());
        List<PortalVI> portalVIList = Arrays.stream(portalVIS).filter(portal -> 0 == portal.viType).collect(Collectors.toList());
        return tableDO2VOs(portalVIList,false);
    }
@@ -482,9 +489,9 @@
     */
    @Override
    @VciUnLog
    public List<UITableDefineVO> tableDO2VOs(Collection<com.vci.corba.portal.data.PortalVI> prms, boolean queryDetail) {
    public List<UITableDefineVO> tableDO2VOs(Collection<PortalVI> prms, boolean queryDetail) {
        List<UITableDefineVO> tableDefineVOList = new ArrayList<>();
        Optional.ofNullable(prms).orElseGet(()->new ArrayList<com.vci.corba.portal.data.PortalVI>()).stream().forEach(portal->{
        Optional.ofNullable(prms).orElseGet(()->new ArrayList<PortalVI>()).stream().forEach(portal->{
            UITableDefineVO defineVO = tableDO2VO(portal,queryDetail);
            tableDefineVOList.add(defineVO);
        });
@@ -500,7 +507,10 @@
     */
    @Override
    @VciUnLog
    public UITableDefineVO tableDO2VO(com.vci.corba.portal.data.PortalVI portal, boolean queryDetail) {
    public UITableDefineVO tableDO2VO(PortalVI portal, boolean queryDetail) {
        if(null != null){
        }
        UITableDefineVO tableDefineVO = new UITableDefineVO();
        tableDefineVO.setOid(portal.id);
        tableDefineVO.setId(portal.viName);
@@ -730,7 +740,7 @@
            return null;
        }
        if(!QUERY_BY_CACHE){
            com.vci.corba.portal.data.PortalVI portalVI = null;
            PortalVI portalVI = null;
            try {
                portalVI = ServiceProvider.getUIService().getPortalVIByTypeNameAndVIName(btmId, id);
            } catch (VCIError vciError) {
@@ -799,7 +809,7 @@
     */
    @Override
    @VciUnLog
    public List<UIActionVO> actionDO2VOs(Collection<com.vci.corba.portal.data.PLAction> actions) {
    public List<UIActionVO> actionDO2VOs(Collection<PLAction> actions) {
        List<UIActionVO> actionVOS = new ArrayList<>();
        Optional.ofNullable(actions).orElseGet(()->new ArrayList<>()).stream().forEach(action->{
            UIActionVO actionVO = actionDO2VO(action);
@@ -816,7 +826,7 @@
     */
    @Override
    @VciUnLog
    public UIActionVO actionDO2VO(com.vci.corba.portal.data.PLAction action) {
    public UIActionVO actionDO2VO(PLAction action) {
        UIActionVO actionVO = new UIActionVO();
        if(action!=null){
            actionVO.setOid(action.plOId);
@@ -829,8 +839,8 @@
            actionVO.setCreator(action.plCreateUser);
            actionVO.setLastModifier(action.plModifyUser);
            try {
                actionVO.setCreateTime(new Date(action.plCreateTime));
                actionVO.setLastModifyTime(new Date(action.plCreateTime));
                actionVO.setCreateTime(VciDateUtil.str2Date(String.valueOf(action.plCreateTime), VciDateUtil.DateTimeFormat));
                actionVO.setLastModifyTime(VciDateUtil.str2Date(String.valueOf(action.plCreateTime), VciDateUtil.DateTimeFormat));
            }catch (Throwable e){
                logger.error("转换时间",e);
            }
@@ -914,8 +924,8 @@
            contentVO.setDescription(pageLayoutDefination.plDesc);
            contentVO.setCreator(pageLayoutDefination.plCreateUser);
            try {
                contentVO.setCreateTime(new Date(pageLayoutDefination.plCreateTime));
                contentVO.setLastModifyTime(new Date(pageLayoutDefination.plModifyTime));
                contentVO.setCreateTime(VciDateUtil.str2Date(String.valueOf(pageLayoutDefination.plCreateTime),VciDateUtil.DateTimeFormat));
                contentVO.setLastModifyTime(VciDateUtil.str2Date(String.valueOf(pageLayoutDefination.plModifyTime),VciDateUtil.DateTimeFormat));
            } catch (Exception e) {
                e.printStackTrace();
            }
@@ -998,24 +1008,24 @@
        return contentVO;
    }
//    private List<UILayoutVO> swapLayArea(List<UILayoutVO> layoutVOS){
//        List<UILayoutVO> layoutVOList = new ArrayList<>();
//        //1 å¯¼èˆªåŒº
//        //2 ä¸»å†…容区
//        //3 é¡µç­¾åŒº
//        if(!CollectionUtils.isEmpty(layoutVOS)){
//            //只有一个区域的时候,都放在center里,哪怕本身是导航区
//            if(layoutVOS.size() == 1){
//                layoutVOS.get(0).setLayoutAreaType(UILayoutAreaTypeEnum.CENTER.getValue());
//                layoutVOList.add(layoutVOS.get(0));
//            }else{
//                Map<String,List<UILayoutVO>> layoutAreaMap = layoutVOS.stream().collect(Collectors.groupingBy(UILayoutVO::getLayoutAreaType));
//                if(layoutAreaMap.containsKey("1")){
//                    //
//                }
//            }
//        }
//    }
    //    private List<UILayoutVO> swapLayArea(List<UILayoutVO> layoutVOS){
    //        List<UILayoutVO> layoutVOList = new ArrayList<>();
    //        //1 å¯¼èˆªåŒº
    //        //2 ä¸»å†…容区
    //        //3 é¡µç­¾åŒº
    //        if(!CollectionUtils.isEmpty(layoutVOS)){
    //            //只有一个区域的时候,都放在center里,哪怕本身是导航区
    //            if(layoutVOS.size() == 1){
    //                layoutVOS.get(0).setLayoutAreaType(UILayoutAreaTypeEnum.CENTER.getValue());
    //                layoutVOList.add(layoutVOS.get(0));
    //            }else{
    //                Map<String,List<UILayoutVO>> layoutAreaMap = layoutVOS.stream().collect(Collectors.groupingBy(UILayoutVO::getLayoutAreaType));
    //                if(layoutAreaMap.containsKey("1")){
    //                    //
    //                }
    //            }
    //        }
    //    }
    /**
     * èŽ·å–æŸä¸ªUI上下文的区域
@@ -1082,9 +1092,9 @@
     * @param pages åŒºåŸŸçš„æ•°æ®å¯¹è±¡
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    private List<UILayoutVO> UILayoutDO2VOs(Collection<com.vci.corba.portal.data.PLTabPage> pages, boolean queryDetail){
    private List<UILayoutVO> UILayoutDO2VOs(Collection<PLTabPage> pages, boolean queryDetail){
        List<UILayoutVO> contentVOS = new ArrayList<>();
        Optional.ofNullable(pages).orElseGet(()->new ArrayList<com.vci.corba.portal.data.PLTabPage>()).stream().forEach(page->{
        Optional.ofNullable(pages).orElseGet(()->new ArrayList<PLTabPage>()).stream().forEach(page->{
            UILayoutVO layoutVO = UILayoutDO2VO(page, queryDetail);
            if(layoutVO.isEnableStatus()) {
                contentVOS.add(layoutVO);
@@ -1108,7 +1118,7 @@
     * @return åŒºåŸŸçš„æ˜¾ç¤ºå¯¹è±¡
     */
    @VciUnLog
    private UILayoutVO UILayoutDO2VO(com.vci.corba.portal.data.PLTabPage page, boolean queryDetail){
    private UILayoutVO UILayoutDO2VO(PLTabPage page, boolean queryDetail){
        UILayoutVO layoutVO = new UILayoutVO();
        if(page !=null ){
            layoutVO.setOid(page.plOId);
@@ -1136,8 +1146,8 @@
            }
            layoutVO.setCreator(page.plCreateUser);
            try {
                layoutVO.setCreateTime(new Date(page.plCreateTime));
                layoutVO.setLastModifyTime(new Date(page.plModifyTime));
                layoutVO.setCreateTime(VciDateUtil.str2Date(String.valueOf(page.plCreateTime),VciDateUtil.DateTimeFormat));
                layoutVO.setLastModifyTime(VciDateUtil.str2Date(String.valueOf(page.plModifyTime),VciDateUtil.DateTimeFormat));
            } catch (Exception e) {
                e.printStackTrace();
            }
@@ -1196,8 +1206,7 @@
        }
        if(!QUERY_BY_CACHE){
            try {
                platformClientUtil.getPortalService().getPLPageDefinationById(componentOid);
                return uiComponentDO2VO(null,true);
                return uiComponentDO2VO(ServiceProvider.getUIService().getPLPageDefinationById(componentOid),true);
            } catch (VCIError vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
@@ -1216,7 +1225,7 @@
     * @param pages æ•°æ®å¯¹è±¡
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    private List<UIComponentVO> uiComponentDO2VOs(Collection<com.vci.corba.portal.data.PLPageDefination> pages, boolean queryDetail){
    private List<UIComponentVO> uiComponentDO2VOs(Collection<PLPageDefination> pages, boolean queryDetail){
        List<UIComponentVO> componentVOS = new ArrayList<>();
        pages.stream().forEach(page->{
            componentVOS.add(uiComponentDO2VO(page,queryDetail));
@@ -1230,7 +1239,7 @@
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    @VciUnLog
    private UIComponentVO uiComponentDO2VO(com.vci.corba.portal.data.PLPageDefination page, boolean queryDetail){
    private UIComponentVO uiComponentDO2VO(PLPageDefination page, boolean queryDetail){
        UIComponentVO componentVO = new UIComponentVO();
        if(page !=null){
            componentVO.setOid(page.plOId);
@@ -1270,6 +1279,7 @@
                }else{
                    try {
                        componentVO.setTableDefineVO(tableDO2VO(ServiceProvider.getUIService().getPortalVIByTypeNameAndVIName(btmType,componentDefineXO.getTemplateId()),true));
                        //componentVO.setTableDefineVO(tableDO2VO(platformClientUtil.getPortalService().getPortalVIByTypeNameAndVIName(btmType,componentDefineXO.getTemplateId()),true));
                    } catch (VCIError vciError) {
                        throw WebUtil.getVciBaseException(vciError);
                    }
@@ -1426,8 +1436,6 @@
        }
    }
    /**
     * æŒ‰é’®çš„æ•°æ®å¯¹è±¡è½¬æ¢ä¸ºæ˜¾ç¤ºå¯¹è±¡
     * @param buttons æŒ‰é’®çš„æ•°æ®å¯¹è±¡
@@ -1448,10 +1456,10 @@
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    @Override
    public UIButtonDefineVO buttonDO2VO(com.vci.corba.portal.data.PLTabButton button)  {
    public UIButtonDefineVO buttonDO2VO(PLTabButton button)  {
        UIButtonDefineVO buttonVO = new UIButtonDefineVO();
        Map<String, UIActionVO> actionVOMap = self.selectAllActionMap();
//        Map<String, UIActionVO> actionVOMap = ServiceProvider.getUIService().getAllPLAction();
        //Map<String, UIActionVO> actionVOMap = ServiceProvider.getUIService().getAllPLAction();
        if(button !=null){
            buttonVO.setOid(button.plOId);
            buttonVO.setPkComponent(button.plTableOId);
@@ -1482,10 +1490,10 @@
                //查找参数
                Map<String,String> params = new HashMap<>();
                try {
//                    PLCommandParameter[] parameters = platformClientUtil.getPortalService().getPLCommandParametersByCommandOId(buttonVO.getOid());
                    com.vci.corba.portal.data.PLCommandParameter[] parameters = ServiceProvider.getUIService().getPLCommandParametersByCommandOId(buttonVO.getOid());
                    //PLCommandParameter[] parameters = platformClientUtil.getPortalService().getPLCommandParametersByCommandOId(buttonVO.getOid());
                    PLCommandParameter[] parameters = ServiceProvider.getUIService().getPLCommandParametersByCommandOId(buttonVO.getOid());
                    if(parameters!=null && parameters.length > 0){
                        for(com.vci.corba.portal.data.PLCommandParameter parameter: parameters){
                        for(PLCommandParameter parameter: parameters){
                            params.put(parameter.plKey,parameter.plValue);
                        }
                    }
@@ -1560,8 +1568,9 @@
                break;
            }
        }
//        return UIContentDO2VO(context,true);
        //return UIContentDO2VO(context,true);
        return UIContentDO2VO(null,true);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,501 @@
package com.vci.web.support;
import com.vci.web.util.StringUtil;
import com.vci.web.util.Func;
import com.vci.web.util.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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
        if (StringUtil.isEmpty(str)) {
            return new ArrayList<String>(0);
        }
        if (limit == 1) {
            return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
        }
        final ArrayList<String> 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;
                //检查是否超出范围(最大允许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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
        if (StringUtil.isEmpty(str)) {
            return new ArrayList<String>(0);
        }
        if (limit == 1) {
            return addToList(new ArrayList<String>(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<String> 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
    /**
     * ä½¿ç”¨ç©ºç™½ç¬¦åˆ‡åˆ†å­—符串<br>
     * åˆ‡åˆ†åŽçš„字符串两边不包含空白符,空串或空白符串并不做为元素之一
     *
     * @param str   è¢«åˆ‡åˆ†çš„字符串
     * @param limit é™åˆ¶åˆ†ç‰‡æ•°
     * @return åˆ‡åˆ†åŽçš„集合
     * @since 3.0.8
     */
    public static List<String> split(String str, int limit) {
        if (StringUtil.isEmpty(str)) {
            return new ArrayList<String>(0);
        }
        if (limit == 1) {
            return addToList(new ArrayList<String>(1), str, true, true);
        }
        final ArrayList<String> 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;
                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<String> split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
        if (StringUtil.isEmpty(str)) {
            return new ArrayList<String>(0);
        }
        if (limit == 1) {
            return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
        }
        if (null == separatorPattern) {
            return split(str, limit);
        }
        final Matcher matcher = separatorPattern.matcher(str);
        final ArrayList<String> 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();
            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<String> addToList(List<String> 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<String> list) {
        return list.toArray(new String[list.size()]);
    }
    //---------------------------------------------------------------------------------------------------------- Private method end
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
/**
 * 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);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/BeanUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,424 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import com.vci.web.util.beans.BeanProperty;
import com.vci.web.util.beans.BladeBeanCopier;
import com.vci.web.util.convert.BladeConverter;
import com.vci.web.util.beans.BladeBeanMap;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.cglib.beans.BeanGenerator;
import org.springframework.lang.Nullable;
import java.util.*;
/**
 * å®žä½“工具类
 *
 * @author L.cm
 */
public class BeanUtil extends org.springframework.beans.BeanUtils {
    /**
     * å®žä¾‹åŒ–对象
     *
     * @param clazz ç±»
     * @param <T>   æ³›åž‹æ ‡è®°
     * @return å¯¹è±¡
     */
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> clazz) {
        return (T) instantiateClass(clazz);
    }
    /**
     * å®žä¾‹åŒ–对象
     *
     * @param clazzStr ç±»å
     * @param <T>      æ³›åž‹æ ‡è®°
     * @return å¯¹è±¡
     */
    public static <T> T newInstance(String clazzStr) {
        try {
            Class<?> clazz = ClassUtil.forName(clazzStr, null);
            return newInstance(clazz);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * èŽ·å–Bean的属性, æ”¯æŒ propertyName å¤šçº§ ï¼štest.user.name
     *
     * @param bean         bean
     * @param propertyName å±žæ€§å
     * @return å±žæ€§å€¼
     */
    @Nullable
    public static Object getProperty(@Nullable Object bean, String propertyName) {
        if (bean == null) {
            return null;
        }
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
        return beanWrapper.getPropertyValue(propertyName);
    }
    /**
     * è®¾ç½®Bean属性, æ”¯æŒ propertyName å¤šçº§ ï¼štest.user.name
     *
     * @param bean         bean
     * @param propertyName å±žæ€§å
     * @param value        å±žæ€§å€¼
     */
    public static void setProperty(Object bean, String propertyName, Object value) {
        Objects.requireNonNull(bean, "bean Could not null");
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
        beanWrapper.setPropertyValue(propertyName, value);
    }
    /**
     * æ·±å¤åˆ¶
     *
     * <p>
     * æ”¯æŒ map bean
     * </p>
     *
     * @param source æºå¯¹è±¡
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @SuppressWarnings("unchecked")
    @Nullable
    public static <T> T clone(@Nullable T source) {
        if (source == null) {
            return null;
        }
        return (T) BeanUtil.copy(source, source.getClass());
    }
    /**
     * copy å¯¹è±¡å±žæ€§ï¼Œé»˜è®¤ä¸ä½¿ç”¨Convert
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source æºå¯¹è±¡
     * @param clazz  ç±»å
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copy(@Nullable Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        return BeanUtil.copy(source, source.getClass(), clazz);
    }
    /**
     * copy å¯¹è±¡å±žæ€§ï¼Œé»˜è®¤ä¸ä½¿ç”¨Convert
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source      æºå¯¹è±¡
     * @param sourceClazz æºç±»åž‹
     * @param targetClazz è½¬æ¢æˆçš„类型
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copy(@Nullable Object source, Class sourceClazz, Class<T> targetClazz) {
        if (source == null) {
            return null;
        }
        BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, false);
        T to = newInstance(targetClazz);
        copier.copy(source, to, null);
        return to;
    }
    /**
     * copy åˆ—表对象,默认不使用Convert
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param sourceList  æºåˆ—表
     * @param targetClazz è½¬æ¢æˆçš„类型
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return T
     */
    public static <T> List<T> copy(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
        if (sourceList == null || sourceList.isEmpty()) {
            return Collections.emptyList();
        }
        List<T> outList = new ArrayList<>(sourceList.size());
        Class<?> sourceClazz = null;
        for (Object source : sourceList) {
            if (source == null) {
                continue;
            }
            if (sourceClazz == null) {
                sourceClazz = source.getClass();
            }
            T bean = BeanUtil.copy(source, sourceClazz, targetClazz);
            outList.add(bean);
        }
        return outList;
    }
    /**
     * æ‹·è´å¯¹è±¡
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source     æºå¯¹è±¡
     * @param targetBean éœ€è¦èµ‹å€¼çš„对象
     */
    public static void copy(@Nullable Object source, @Nullable Object targetBean) {
        if (source == null || targetBean == null) {
            return;
        }
        BladeBeanCopier copier = BladeBeanCopier
            .create(source.getClass(), targetBean.getClass(), false);
        copier.copy(source, targetBean, null);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œsource å±žæ€§åš null åˆ¤æ–­ï¼ŒMap ä¸æ”¯æŒï¼Œmap ä¼šåš instanceof åˆ¤æ–­ï¼Œä¸ä¼š
     *
     * <p>
     * æ”¯æŒ bean copy
     * </p>
     *
     * @param source     æºå¯¹è±¡
     * @param targetBean éœ€è¦èµ‹å€¼çš„对象
     */
    public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) {
        if (source == null || targetBean == null) {
            return;
        }
        BladeBeanCopier copier = BladeBeanCopier
            .create(source.getClass(), targetBean.getClass(), false, true);
        copier.copy(source, targetBean, null);
    }
    /**
     * æ‹·è´å¯¹è±¡å¹¶å¯¹ä¸åŒç±»åž‹å±žæ€§è¿›è¡Œè½¬æ¢
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source æºå¯¹è±¡
     * @param targetClazz è½¬æ¢æˆçš„ç±»
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copyWithConvert(@Nullable Object source, Class<T> targetClazz) {
        if (source == null) {
            return null;
        }
        return BeanUtil.copyWithConvert(source, source.getClass(), targetClazz);
    }
    /**
     * æ‹·è´å¯¹è±¡å¹¶å¯¹ä¸åŒç±»åž‹å±žæ€§è¿›è¡Œè½¬æ¢
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source æºå¯¹è±¡
     * @param sourceClazz æºç±»
     * @param targetClazz è½¬æ¢æˆçš„ç±»
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copyWithConvert(@Nullable Object source, Class<?> sourceClazz, Class<T> targetClazz) {
        if (source == null) {
            return null;
        }
        BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, true);
        T to = newInstance(targetClazz);
        copier.copy(source, to, new BladeConverter(sourceClazz, targetClazz));
        return to;
    }
    /**
     * æ‹·è´åˆ—表并对不同类型属性进行转换
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param sourceList æºå¯¹è±¡åˆ—表
     * @param targetClazz è½¬æ¢æˆçš„ç±»
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return List
     */
    public static <T> List<T> copyWithConvert(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
        if (sourceList == null || sourceList.isEmpty()) {
            return Collections.emptyList();
        }
        List<T> outList = new ArrayList<>(sourceList.size());
        Class<?> sourceClazz = null;
        for (Object source : sourceList) {
            if (source == null) {
                continue;
            }
            if (sourceClazz == null) {
                sourceClazz = source.getClass();
            }
            T bean = BeanUtil.copyWithConvert(source, sourceClazz, targetClazz);
            outList.add(bean);
        }
        return outList;
    }
    /**
     * Copy the property values of the given source bean into the target class.
     * <p>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.
     * <p>This is just a convenience method. For more complex transfer needs,
     *
     * @param source the source bean
     * @param targetClazz the target bean class
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     * @throws BeansException if the copying failed
     */
    @Nullable
    public static <T> T copyProperties(@Nullable Object source, Class<T> targetClazz) throws BeansException {
        if (source == null) {
            return null;
        }
        T to = newInstance(targetClazz);
        BeanUtil.copyProperties(source, to);
        return to;
    }
    /**
     * Copy the property values of the given source bean into the target class.
     * <p>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.
     * <p>This is just a convenience method. For more complex transfer needs,
     *
     * @param sourceList the source list bean
     * @param targetClazz the target bean class
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return List
     * @throws BeansException if the copying failed
     */
    public static <T> List<T> copyProperties(@Nullable Collection<?> sourceList, Class<T> targetClazz) throws BeansException {
        if (sourceList == null || sourceList.isEmpty()) {
            return Collections.emptyList();
        }
        List<T> outList = new ArrayList<>(sourceList.size());
        for (Object source : sourceList) {
            if (source == null) {
                continue;
            }
            T bean = BeanUtil.copyProperties(source, targetClazz);
            outList.add(bean);
        }
        return outList;
    }
    /**
     * å°†å¯¹è±¡è£…成map形式
     *
     * @param bean æºå¯¹è±¡
     * @return {Map}
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(@Nullable Object bean) {
        if (bean == null) {
            return new HashMap<>(0);
        }
        return BladeBeanMap.create(bean);
    }
    /**
     * å°†map è½¬ä¸º bean
     *
     * @param beanMap   map
     * @param valueType å¯¹è±¡ç±»åž‹
     * @param <T>       æ³›åž‹æ ‡è®°
     * @return {T}
     */
    public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) {
        Objects.requireNonNull(beanMap, "beanMap Could not null");
        T to = newInstance(valueType);
        if (beanMap.isEmpty()) {
            return to;
        }
        BeanUtil.copy(beanMap, to);
        return to;
    }
    /**
     * ç»™ä¸€ä¸ªBean添加字段
     *
     * @param superBean çˆ¶çº§Bean
     * @param props     æ–°å¢žå±žæ€§
     * @return {Object}
     */
    @Nullable
    public static Object generator(@Nullable Object superBean, BeanProperty... props) {
        if (superBean == null) {
            return null;
        }
        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();
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.vci.web.util;
/**
 * char å¸¸é‡æ± 
 *
 * @author L.cm
 */
public interface CharPool {
    // @formatter:off
    char UPPER_A          = 'A';
    char LOWER_A          = 'a';
    char UPPER_Z          = 'Z';
    char LOWER_Z          = 'z';
    char DOT              = '.';
    char AT               = '@';
    char LEFT_BRACE       = '{';
    char RIGHT_BRACE      = '}';
    char LEFT_BRACKET     = '(';
    char RIGHT_BRACKET    = ')';
    char DASH             = '-';
    char PERCENT          = '%';
    char PIPE             = '|';
    char PLUS             = '+';
    char QUESTION_MARK    = '?';
    char EXCLAMATION_MARK = '!';
    char EQUALS           = '=';
    char AMPERSAND        = '&';
    char ASTERISK         = '*';
    char STAR             = ASTERISK;
    char BACK_SLASH       = '\\';
    char COLON            = ':';
    char COMMA            = ',';
    char DOLLAR           = '$';
    char SLASH            = '/';
    char HASH             = '#';
    char HAT              = '^';
    char LEFT_CHEV        = '<';
    char NEWLINE          = '\n';
    char N                = 'n';
    char Y                = 'y';
    char QUOTE            = '\"';
    char RETURN           = '\r';
    char TAB              = '\t';
    char RIGHT_CHEV       = '>';
    char SEMICOLON        = ';';
    char SINGLE_QUOTE     = '\'';
    char BACKTICK         = '`';
    char SPACE            = ' ';
    char TILDA            = '~';
    char LEFT_SQ_BRACKET  = '[';
    char RIGHT_SQ_BRACKET = ']';
    char UNDERSCORE       = '_';
    char ONE              = '1';
    char ZERO             = '0';
    // @formatter:on
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
/**
 * å­—符集工具类
 *
 * @author L.cm
 */
public class Charsets {
    /**
     * å­—符集ISO-8859-1
     */
    public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
    public static final String ISO_8859_1_NAME = ISO_8859_1.name();
    /**
     * å­—符集GBK
     */
    public static final Charset GBK = Charset.forName(StringPool.GBK);
    public static final String GBK_NAME = GBK.name();
    /**
     * å­—符集utf-8
     */
    public static final Charset UTF_8 = StandardCharsets.UTF_8;
    public static final String UTF_8_NAME = UTF_8.name();
    /**
     * è½¬æ¢ä¸ºCharset对象
     *
     * @param charsetName å­—符集,为空则返回默认字符集
     * @return Charsets
     * @throws UnsupportedCharsetException ç¼–码不支持
     */
    public static Charset charset(String charsetName) throws UnsupportedCharsetException {
        return StringUtil.isBlank(charsetName) ? Charset.defaultCharset() : Charset.forName(charsetName);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ClassUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,130 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
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 <A>            æ³›åž‹æ ‡è®°
     * @return {Annotation}
     */
    public static <A extends Annotation> A getAnnotation(Method method, Class<A> 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 <A>            æ³›åž‹æ ‡è®°
     * @return {Annotation}
     */
    public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
        // å…ˆæ‰¾æ–¹æ³•,再找方法上的类
        A annotation = handlerMethod.getMethodAnnotation(annotationType);
        if (null != annotation) {
            return annotation;
        }
        // èŽ·å–ç±»ä¸Šé¢çš„Annotation,可能包含组合注解,故采用spring的工具类
        Class<?> beanType = handlerMethod.getBeanType();
        return AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦æœ‰æ³¨è§£ Annotation
     *
     * @param method         Method
     * @param annotationType æ³¨è§£ç±»
     * @param <A>            æ³›åž‹æ ‡è®°
     * @return {boolean}
     */
    public static <A extends Annotation> boolean isAnnotated(Method method, Class<A> annotationType) {
        // å…ˆæ‰¾æ–¹æ³•,再找方法上的类
        boolean isMethodAnnotated = AnnotatedElementUtils.isAnnotated(method, annotationType);
        if (isMethodAnnotated) {
            return true;
        }
        // èŽ·å–ç±»ä¸Šé¢çš„Annotation,可能包含组合注解,故采用spring的工具类
        Class<?> targetClass = method.getDeclaringClass();
        return AnnotatedElementUtils.isAnnotated(targetClass, annotationType);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
package com.vci.web.util;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;
/**
 * é›†åˆå·¥å…·ç±»
 *
 * @author L.cm
 */
public class CollectionUtil extends CollectionUtils {
    /**
     * Return {@code true} if the supplied Collection is not {@code null} or empty.
     * Otherwise, return {@code false}.
     *
     * @param collection the Collection to check
     * @return whether the given Collection is not empty
     */
    public static boolean isNotEmpty(@Nullable Collection<?> collection) {
        return !CollectionUtil.isEmpty(collection);
    }
    /**
     * Return {@code true} if the supplied Map is not {@code null} or empty.
     * Otherwise, return {@code false}.
     *
     * @param map the Map to check
     * @return whether the given Map is not empty
     */
    public static boolean isNotEmpty(@Nullable Map<?, ?> map) {
        return !CollectionUtil.isEmpty(map);
    }
    /**
     * Check whether the given Array contains the given element.
     *
     * @param array   the Array to check
     * @param element the element to look for
     * @param <T>     The generic tag
     * @return {@code true} if found, {@code false} else
     */
    public static <T> boolean contains(@Nullable T[] array, final T element) {
        if (array == null) {
            return false;
        }
        return Arrays.stream(array).anyMatch(x -> ObjectUtil.nullSafeEquals(x, element));
    }
    /**
     * Concatenates 2 arrays
     *
     * @param one   æ•°ç»„1
     * @param other æ•°ç»„2
     * @return æ–°æ•°ç»„
     */
    public static String[] concat(String[] one, String[] other) {
        return concat(one, other, String.class);
    }
    /**
     * Concatenates 2 arrays
     *
     * @param one   æ•°ç»„1
     * @param other æ•°ç»„2
     * @param clazz æ•°ç»„ç±»
     * @return æ–°æ•°ç»„
     */
    public static <T> T[] concat(T[] one, T[] other, Class<T> clazz) {
        T[] target = (T[]) Array.newInstance(clazz, one.length + other.length);
        System.arraycopy(one, 0, target, 0, one.length);
        System.arraycopy(other, 0, target, one.length, other.length);
        return target;
    }
    /**
     * å¯¹è±¡æ˜¯å¦ä¸ºæ•°ç»„对象
     *
     * @param obj å¯¹è±¡
     * @return æ˜¯å¦ä¸ºæ•°ç»„对象,如果为{@code null} è¿”回false
     */
    public static boolean isArray(Object obj) {
        if (null == obj) {
            return false;
        }
        return obj.getClass().isArray();
    }
    /**
     * ä¸å¯å˜ Set
     *
     * @param es  å¯¹è±¡
     * @param <E> æ³›åž‹
     * @return é›†åˆ
     */
    @SafeVarargs
    public static <E> Set<E> ofImmutableSet(E... es) {
        Objects.requireNonNull(es, "args es is null.");
        return Arrays.stream(es).collect(Collectors.toSet());
    }
    /**
     * ä¸å¯å˜ List
     *
     * @param es  å¯¹è±¡
     * @param <E> æ³›åž‹
     * @return é›†åˆ
     */
    @SafeVarargs
    public static <E> List<E> ofImmutableList(E... es) {
        Objects.requireNonNull(es, "args es is null.");
        return Arrays.stream(es).collect(Collectors.toList());
    }
    /**
     * Iterable è½¬æ¢ä¸ºList集合
     *
     * @param elements Iterable
     * @param <E>      æ³›åž‹
     * @return é›†åˆ
     */
    public static <E> List<E> toList(Iterable<E> elements) {
        Objects.requireNonNull(elements, "elements es is null.");
        if (elements instanceof Collection) {
            return new ArrayList((Collection) elements);
        }
        Iterator<E> iterator = elements.iterator();
        List<E> list = new ArrayList<>();
        while (iterator.hasNext()) {
            list.add(iterator.next());
        }
        return list;
    }
    /**
     * å°†key value æ•°ç»„转为 map
     *
     * @param keysValues key value æ•°ç»„
     * @param <K>        key
     * @param <V>        value
     * @return map é›†åˆ
     */
    public static <K, V> Map<K, V> toMap(Object... keysValues) {
        int kvLength = keysValues.length;
        if (kvLength % 2 != 0) {
            throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd");
        }
        Map<K, V> keyValueMap = new HashMap<>(kvLength);
        for (int i = kvLength - 2; i >= 0; i -= 2) {
            Object key = keysValues[i];
            Object value = keysValues[i + 1];
            keyValueMap.put((K) key, (V) value);
        }
        return keyValueMap;
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
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
 * <p>
 * {@link SimpleDateFormat}的线程安全包装器。
 * ä¸ä½¿ç”¨ThreadLocal,创建足够的SimpleDateFormat对象来满足并发性要求。
 * </p>
 *
 * @author L.cm
 */
public class ConcurrentDateFormat {
    private final String format;
    private final Locale locale;
    private final TimeZone timezone;
    private final Queue<SimpleDateFormat> 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;
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConvertUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.vci.web.util;
import com.vci.web.util.convert.BladeConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.lang.Nullable;
/**
 * åŸºäºŽ spring ConversionService ç±»åž‹è½¬æ¢
 *
 * @author L.cm
 */
@SuppressWarnings("unchecked")
public class ConvertUtil {
    /**
     * Convenience operation for converting a source object to the specified targetType.
     * {@link TypeDescriptor#forObject(Object)}.
     * @param source the source object
     * @param targetType the target type
     * @param <T> æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     * or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, Class<T> targetType) {
        if (source == null) {
            return null;
        }
        if (ClassUtil.isAssignableValue(targetType, source)) {
            return (T) source;
        }
        GenericConversionService conversionService = BladeConversionService.getInstance();
        return conversionService.convert(source, targetType);
    }
    /**
     * Convenience operation for converting a source object to the specified targetType,
     * where the target type is a descriptor that provides additional conversion context.
     * {@link TypeDescriptor#forObject(Object)}.
     * @param source the source object
     * @param sourceType the source type
     * @param targetType the target type
     * @param <T> æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     * or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        if (source == null) {
            return null;
        }
        GenericConversionService conversionService = BladeConversionService.getInstance();
        return (T) conversionService.convert(source, sourceType, targetType);
    }
    /**
     * Convenience operation for converting a source object to the specified targetType,
     * where the target type is a descriptor that provides additional conversion context.
     * Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and
     * encapsulates the construction of the source type descriptor using
     * {@link TypeDescriptor#forObject(Object)}.
     * @param source the source object
     * @param targetType the target type
     * @param <T> æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     * or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, TypeDescriptor targetType) {
        if (source == null) {
            return null;
        }
        GenericConversionService conversionService = BladeConversionService.getInstance();
        return (T) conversionService.convert(source, targetType);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
package com.vci.web.util;
/**
 * æ•°æ®ç±»åž‹è½¬æ¢å·¥å…·ç±»
 *
 * @author Chill
 */
public class DatatypeConverterUtil {
    /**
     * hex文本转换为二进制
     *
     * @param hexStr hex文本
     * @return byte[]
     */
    public static byte[] parseHexBinary(String hexStr) {
        final int len = hexStr.length();
        if (len % 2 != 0) {
            throw new IllegalArgumentException("hexBinary needs to be even-length: " + hexStr);
        }
        byte[] out = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            int h = hexToBin(hexStr.charAt(i));
            int l = hexToBin(hexStr.charAt(i + 1));
            if (h == -1 || l == -1) {
                throw new IllegalArgumentException("contains illegal character for hexBinary: " + hexStr);
            }
            out[i / 2] = (byte) (h * 16 + l);
        }
        return out;
    }
    /**
     * hex文本转换为int
     *
     * @param ch hex文本
     * @return int
     */
    private static int hexToBin(char ch) {
        if ('0' <= ch && ch <= '9') {
            return ch - '0';
        }
        if ('A' <= ch && ch <= 'F') {
            return ch - 'A' + 10;
        }
        if ('a' <= ch && ch <= 'f') {
            return ch - 'a' + 10;
        }
        return -1;
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
/**
 * DateTime å·¥å…·ç±»
 *
 * @author L.cm
 */
public class DateTimeUtil {
    public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
    public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
    public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
    /**
     * æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @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 LocalDateTime parseDateTime(String dateStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return DateTimeUtil.parseDateTime(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
        return LocalDateTime.parse(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalDateTime parseDateTime(String dateStr) {
        return DateTimeUtil.parseDateTime(dateStr, DateTimeUtil.DATETIME_FORMAT);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @param pattern è¡¨è¾¾å¼
     * @return æ—¶é—´
     */
    public static LocalDate parseDate(String dateStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return DateTimeUtil.parseDate(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
        return LocalDate.parse(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为日期
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalDate parseDate(String dateStr) {
        return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @param pattern æ—¶é—´æ­£åˆ™
     * @return æ—¶é—´
     */
    public static LocalTime parseTime(String dateStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return DateTimeUtil.parseTime(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
        return LocalTime.parse(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalTime parseTime(String dateStr) {
        return DateTimeUtil.parseTime(dateStr, DateTimeUtil.TIME_FORMAT);
    }
    /**
     * æ—¶é—´è½¬ 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());
    }
    /**
     * è½¬æ¢æˆ date
     *
     * @param dateTime LocalDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime dateTime) {
        return Date.from(DateTimeUtil.toInstant(dateTime));
    }
    /**
     * æ¯”较2个时间差,跨度比较小
     *
     * @param startInclusive å¼€å§‹æ—¶é—´
     * @param endExclusive   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Duration between(Temporal startInclusive, Temporal endExclusive) {
        return Duration.between(startInclusive, endExclusive);
    }
    /**
     * æ¯”较2个时间差,跨度比较大,年月日为单位
     *
     * @param startDate å¼€å§‹æ—¶é—´
     * @param endDate   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Period between(LocalDate startDate, LocalDate endDate) {
        return Period.between(startDate, endDate);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,634 @@
package com.vci.web.util;
import org.springframework.util.Assert;
import java.text.ParseException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalQuery;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
 * æ—¥æœŸå·¥å…·ç±»
 *
 * @author L.cm
 */
public class DateUtil {
    public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_TIME = "HH:mm:ss";
    /**
     * è€ date æ ¼å¼åŒ–
     */
    public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
    public static final ConcurrentDateFormat DATETIME_MINI_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME_MINI);
    public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
    public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
    /**
     * java 8 æ—¶é—´æ ¼å¼åŒ–
     */
    public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
    public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
    /**
     * èŽ·å–å½“å‰æ—¥æœŸ
     *
     * @return å½“前日期
     */
    public static Date now() {
        return new Date();
    }
    /**
     * æ·»åŠ å¹´
     *
     * @param date       æ—¶é—´
     * @param yearsToAdd æ·»åŠ çš„å¹´æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusYears(Date date, int yearsToAdd) {
        return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
    }
    /**
     * æ·»åŠ æœˆ
     *
     * @param date        æ—¶é—´
     * @param monthsToAdd æ·»åŠ çš„æœˆæ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusMonths(Date date, int monthsToAdd) {
        return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
    }
    /**
     * æ·»åР呍
     *
     * @param date       æ—¶é—´
     * @param weeksToAdd æ·»åŠ çš„å‘¨æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusWeeks(Date date, int weeksToAdd) {
        return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
    }
    /**
     * æ·»åР天
     *
     * @param date      æ—¶é—´
     * @param daysToAdd æ·»åŠ çš„å¤©æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusDays(Date date, long daysToAdd) {
        return DateUtil.plus(date, Duration.ofDays(daysToAdd));
    }
    /**
     * æ·»åŠ å°æ—¶
     *
     * @param date       æ—¶é—´
     * @param hoursToAdd æ·»åŠ çš„å°æ—¶æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusHours(Date date, long hoursToAdd) {
        return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
    }
    /**
     * æ·»åŠ åˆ†é’Ÿ
     *
     * @param date         æ—¶é—´
     * @param minutesToAdd æ·»åŠ çš„åˆ†é’Ÿæ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusMinutes(Date date, long minutesToAdd) {
        return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
    }
    /**
     * æ·»åŠ ç§’
     *
     * @param date         æ—¶é—´
     * @param secondsToAdd æ·»åŠ çš„ç§’æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusSeconds(Date date, long secondsToAdd) {
        return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
    }
    /**
     * æ·»åŠ æ¯«ç§’
     *
     * @param date        æ—¶é—´
     * @param millisToAdd æ·»åŠ çš„æ¯«ç§’æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusMillis(Date date, long millisToAdd) {
        return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
    }
    /**
     * æ·»åŠ çº³ç§’
     *
     * @param date       æ—¶é—´
     * @param nanosToAdd æ·»åŠ çš„çº³ç§’æ•°
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plusNanos(Date date, long nanosToAdd) {
        return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
    }
    /**
     * æ—¥æœŸæ·»åŠ æ—¶é—´é‡
     *
     * @param date   æ—¶é—´
     * @param amount æ—¶é—´é‡
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date plus(Date date, TemporalAmount amount) {
        Instant instant = date.toInstant();
        return Date.from(instant.plus(amount));
    }
    /**
     * å‡å°‘å¹´
     *
     * @param date  æ—¶é—´
     * @param years å‡å°‘的年数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusYears(Date date, int years) {
        return DateUtil.set(date, Calendar.YEAR, -years);
    }
    /**
     * å‡å°‘月
     *
     * @param date   æ—¶é—´
     * @param months å‡å°‘的月数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusMonths(Date date, int months) {
        return DateUtil.set(date, Calendar.MONTH, -months);
    }
    /**
     * å‡å°‘周
     *
     * @param date  æ—¶é—´
     * @param weeks å‡å°‘的周数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusWeeks(Date date, int weeks) {
        return DateUtil.minus(date, Period.ofWeeks(weeks));
    }
    /**
     * å‡å°‘天
     *
     * @param date æ—¶é—´
     * @param days å‡å°‘的天数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusDays(Date date, long days) {
        return DateUtil.minus(date, Duration.ofDays(days));
    }
    /**
     * å‡å°‘小时
     *
     * @param date  æ—¶é—´
     * @param hours å‡å°‘的小时数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusHours(Date date, long hours) {
        return DateUtil.minus(date, Duration.ofHours(hours));
    }
    /**
     * å‡å°‘分钟
     *
     * @param date    æ—¶é—´
     * @param minutes å‡å°‘的分钟数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusMinutes(Date date, long minutes) {
        return DateUtil.minus(date, Duration.ofMinutes(minutes));
    }
    /**
     * å‡å°‘ç§’
     *
     * @param date    æ—¶é—´
     * @param seconds å‡å°‘的秒数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusSeconds(Date date, long seconds) {
        return DateUtil.minus(date, Duration.ofSeconds(seconds));
    }
    /**
     * å‡å°‘毫秒
     *
     * @param date   æ—¶é—´
     * @param millis å‡å°‘的毫秒数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusMillis(Date date, long millis) {
        return DateUtil.minus(date, Duration.ofMillis(millis));
    }
    /**
     * å‡å°‘纳秒
     *
     * @param date  æ—¶é—´
     * @param nanos å‡å°‘的纳秒数
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minusNanos(Date date, long nanos) {
        return DateUtil.minus(date, Duration.ofNanos(nanos));
    }
    /**
     * æ—¥æœŸå‡å°‘时间量
     *
     * @param date   æ—¶é—´
     * @param amount æ—¶é—´é‡
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    public static Date minus(Date date, TemporalAmount amount) {
        Instant instant = date.toInstant();
        return Date.from(instant.minus(amount));
    }
    /**
     * è®¾ç½®æ—¥æœŸå±žæ€§
     *
     * @param date          æ—¶é—´
     * @param calendarField æ›´æ”¹çš„属性
     * @param amount        æ›´æ”¹æ•°ï¼Œ-1表示减少
     * @return è®¾ç½®åŽçš„æ—¶é—´
     */
    private static Date set(Date date, int calendarField, int amount) {
        Assert.notNull(date, "The date must not be null");
        Calendar c = Calendar.getInstance();
        c.setLenient(false);
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }
    /**
     * æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @param date æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDateTime(Date date) {
        return DATETIME_FORMAT.format(date);
    }
    /**
     * æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @param date æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDateTimeMini(Date date) {
        return DATETIME_MINI_FORMAT.format(date);
    }
    /**
     * æ—¥æœŸæ ¼å¼åŒ–
     *
     * @param date æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDate(Date date) {
        return DATE_FORMAT.format(date);
    }
    /**
     * æ—¶é—´æ ¼å¼åŒ–
     *
     * @param date æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatTime(Date date) {
        return TIME_FORMAT.format(date);
    }
    /**
     * æ—¥æœŸæ ¼å¼åŒ–
     *
     * @param date    æ—¶é—´
     * @param pattern è¡¨è¾¾å¼
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String format(Date date, String pattern) {
        return ConcurrentDateFormat.of(pattern).format(date);
    }
    /**
     * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @param temporal æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDateTime(TemporalAccessor temporal) {
        return DATETIME_FORMATTER.format(temporal);
    }
    /**
     * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @param temporal æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDateTimeMini(TemporalAccessor temporal) {
        return DATETIME_MINI_FORMATTER.format(temporal);
    }
    /**
     * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
     *
     * @param temporal æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatDate(TemporalAccessor temporal) {
        return DATE_FORMATTER.format(temporal);
    }
    /**
     * java8 æ—¶é—´æ ¼å¼åŒ–
     *
     * @param temporal æ—¶é—´
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String formatTime(TemporalAccessor temporal) {
        return TIME_FORMATTER.format(temporal);
    }
    /**
     * java8 æ—¥æœŸæ ¼å¼åŒ–
     *
     * @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 Date parse(String dateStr, String pattern) {
        ConcurrentDateFormat format = ConcurrentDateFormat.of(pattern);
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @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);
        }
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @param pattern è¡¨è¾¾å¼
     * @return æ—¶é—´
     */
    public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
        return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
    }
    /**
     * æ—¶é—´è½¬ 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());
    }
    /**
     * è½¬æ¢æˆ date
     *
     * @param dateTime LocalDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime dateTime) {
        return Date.from(DateUtil.toInstant(dateTime));
    }
    /**
     * è½¬æ¢æˆ date
     *
     * @param localDate LocalDate
     * @return Date
     */
    public static Date toDate(final LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }
    /**
     * Converts local date time to Calendar.
     */
    public static Calendar toCalendar(final LocalDateTime localDateTime) {
        return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
    }
    /**
     * localDateTime è½¬æ¢æˆæ¯«ç§’æ•°
     *
     * @param localDateTime LocalDateTime
     * @return long
     */
    public static long toMilliseconds(final LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    /**
     * localDate è½¬æ¢æˆæ¯«ç§’æ•°
     *
     * @param localDate LocalDate
     * @return long
     */
    public static long toMilliseconds(LocalDate localDate) {
        return toMilliseconds(localDate.atStartOfDay());
    }
    /**
     * è½¬æ¢æˆjava8 æ—¶é—´
     *
     * @param calendar æ—¥åކ
     * @return LocalDateTime
     */
    public static LocalDateTime fromCalendar(final Calendar calendar) {
        TimeZone tz = calendar.getTimeZone();
        ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
        return LocalDateTime.ofInstant(calendar.toInstant(), zid);
    }
    /**
     * è½¬æ¢æˆjava8 æ—¶é—´
     *
     * @param instant Instant
     * @return LocalDateTime
     */
    public static LocalDateTime fromInstant(final Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
    /**
     * è½¬æ¢æˆjava8 æ—¶é—´
     *
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime fromDate(final Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }
    /**
     * è½¬æ¢æˆjava8 æ—¶é—´
     *
     * @param milliseconds æ¯«ç§’æ•°
     * @return LocalDateTime
     */
    public static LocalDateTime fromMilliseconds(final long milliseconds) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
    }
    /**
     * æ¯”较2个时间差,跨度比较小
     *
     * @param startInclusive å¼€å§‹æ—¶é—´
     * @param endExclusive   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Duration between(Temporal startInclusive, Temporal endExclusive) {
        return Duration.between(startInclusive, endExclusive);
    }
    /**
     * æ¯”较2个时间差,跨度比较大,年月日为单位
     *
     * @param startDate å¼€å§‹æ—¶é—´
     * @param endDate   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Period between(LocalDate startDate, LocalDate endDate) {
        return Period.between(startDate, endDate);
    }
    /**
     * æ¯”较2个 æ—¶é—´å·®
     *
     * @param startDate å¼€å§‹æ—¶é—´
     * @param endDate   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Duration between(Date startDate, Date endDate) {
        return Duration.between(startDate.toInstant(), endDate.toInstant());
    }
    /**
     * å°†ç§’数转换为日时分秒
     *
     * @param second ç§’æ•°
     * @return æ—¶é—´
     */
    public static String secondToTime(Long second) {
        // åˆ¤æ–­æ˜¯å¦ä¸ºç©º
        if (second == null || second == 0L) {
            return StringPool.EMPTY;
        }
        //转换天数
        long days = second / 86400;
        //剩余秒数
        second = second % 86400;
        //转换小时
        long hours = second / 3600;
        //剩余秒数
        second = second % 3600;
        //转换分钟
        long minutes = second / 60;
        //剩余秒数
        second = second % 60;
        if (days > 0) {
            return StringUtil.format("{}天{}小时{}分{}秒", days, hours, minutes, second);
        } else {
            return StringUtil.format("{}小时{}分{}秒", hours, minutes, second);
        }
    }
    /**
     * èŽ·å–ä»Šå¤©çš„æ—¥æœŸ
     *
     * @return æ—¶é—´
     */
    public static String today() {
        return format(new Date(), "yyyyMMdd");
    }
    /**
     * èŽ·å–ä»Šå¤©çš„æ—¶é—´
     *
     * @return æ—¶é—´
     */
    public static String time() {
        return format(new Date(), PATTERN_DATETIME_MINI);
    }
    /**
     * èŽ·å–ä»Šå¤©çš„å°æ—¶æ•°
     *
     * @return æ—¶é—´
     */
    public static Integer hour() {
        return NumberUtil.toInt(format(new Date(), "HH"));
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,433 @@
package com.vci.web.util;
import org.springframework.lang.Nullable;
import org.springframework.util.DigestUtils;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
 * åŠ å¯†ç›¸å…³å·¥å…·ç±»ç›´æŽ¥ä½¿ç”¨Spring util封装,减少jar依赖
 *
 * @author L.cm
 */
public class DigestUtil extends org.springframework.util.DigestUtils {
    private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    /**
     * 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 DigestUtils.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 DigestUtils.md5DigestAsHex(bytes);
    }
    /**
     * sha1Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha1Hex(String data) {
        return DigestUtil.sha1Hex(data.getBytes(Charsets.UTF_8));
    }
    /**
     * sha1Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha1Hex(final byte[] bytes) {
        return DigestUtil.digestHex("SHA-1", bytes);
    }
    /**
     * SHA224Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha224Hex(String data) {
        return DigestUtil.sha224Hex(data.getBytes(Charsets.UTF_8));
    }
    /**
     * SHA224Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha224Hex(final byte[] bytes) {
        return DigestUtil.digestHex("SHA-224", bytes);
    }
    /**
     * sha256Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha256Hex(String data) {
        return DigestUtil.sha256Hex(data.getBytes(Charsets.UTF_8));
    }
    /**
     * sha256Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha256Hex(final byte[] bytes) {
        return DigestUtil.digestHex("SHA-256", bytes);
    }
    /**
     * sha384Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha384Hex(String data) {
        return DigestUtil.sha384Hex(data.getBytes(Charsets.UTF_8));
    }
    /**
     * sha384Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha384Hex(final byte[] bytes) {
        return DigestUtil.digestHex("SHA-384", bytes);
    }
    /**
     * sha512Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha512Hex(String data) {
        return DigestUtil.sha512Hex(data.getBytes(Charsets.UTF_8));
    }
    /**
     * sha512Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha512Hex(final byte[] bytes) {
        return DigestUtil.digestHex("SHA-512", bytes);
    }
    /**
     * digest Hex
     *
     * @param algorithm ç®—法
     * @param bytes     Data to digest
     * @return digest as a hex string
     */
    public static String digestHex(String algorithm, byte[] bytes) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            return encodeHex(md.digest(bytes));
        } catch (NoSuchAlgorithmException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * hmacMd5 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacMd5Hex(String data, String key) {
        return DigestUtil.hmacMd5Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacMd5 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacMd5Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacMD5", bytes, key);
    }
    /**
     * hmacSha1 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha1Hex(String data, String key) {
        return DigestUtil.hmacSha1Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha1 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha1Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacSHA1", bytes, key);
    }
    /**
     * hmacSha224 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha224Hex(String data, String key) {
        return DigestUtil.hmacSha224Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha224 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha224Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacSHA224", bytes, key);
    }
    /**
     * hmacSha256
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static byte[] hmacSha256(String data, String key) {
        return DigestUtil.hmacSha256(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha256
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a byte array
     */
    public static byte[] hmacSha256(final byte[] bytes, String key) {
        return DigestUtil.digestHMac("HmacSHA256", bytes, key);
    }
    /**
     * hmacSha256 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha256Hex(String data, String key) {
        return DigestUtil.hmacSha256Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha256 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha256Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacSHA256", bytes, key);
    }
    /**
     * hmacSha384 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha384Hex(String data, String key) {
        return DigestUtil.hmacSha384Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha384 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha384Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacSHA384", bytes, key);
    }
    /**
     * hmacSha512 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha512Hex(String data, String key) {
        return DigestUtil.hmacSha512Hex(data.getBytes(Charsets.UTF_8), key);
    }
    /**
     * hmacSha512 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha512Hex(final byte[] bytes, String key) {
        return DigestUtil.digestHMacHex("HmacSHA512", bytes, key);
    }
    /**
     * digest HMac Hex
     *
     * @param algorithm ç®—法
     * @param bytes     Data to digest
     * @return digest as a hex string
     */
    public static String digestHMacHex(String algorithm, final byte[] bytes, String key) {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
        try {
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return DigestUtil.encodeHex(mac.doFinal(bytes));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * digest HMac
     *
     * @param algorithm ç®—法
     * @param bytes     Data to digest
     * @return digest as a byte array
     */
    public static byte[] digestHMac(String algorithm, final byte[] bytes, String key) {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
        try {
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return mac.doFinal(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * encode Hex
     *
     * @param bytes Data to Hex
     * @return bytes as a hex string
     */
    public static String encodeHex(byte[] bytes) {
        StringBuilder r = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            r.append(HEX_CODE[(b >> 4) & 0xF]);
            r.append(HEX_CODE[(b & 0xF)]);
        }
        return r.toString();
    }
    /**
     * decode Hex
     *
     * @param hexStr Hex string
     * @return decode hex to bytes
     */
    public static byte[] decodeHex(final String hexStr) {
        return DatatypeConverterUtil.parseHexBinary(hexStr);
    }
    /**
     * æ¯”较字符串,避免字符串因为过长,产生耗时
     *
     * @param a String
     * @param b String
     * @return æ˜¯å¦ç›¸åŒ
     */
    public static boolean slowEquals(@Nullable String a, @Nullable String b) {
        if (a == null || b == null) {
            return false;
        }
        return DigestUtil.slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8));
    }
    /**
     * æ¯”较 byte æ•°ç»„,避免字符串因为过长,产生耗时
     *
     * @param a byte array
     * @param b byte array
     * @return æ˜¯å¦ç›¸åŒ
     */
    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 < a.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }
    /**
     * è‡ªå®šä¹‰åР坆 å°†å‰ç«¯ä¼ é€’的密码再次加密
     *
     * @param data æ•°æ®
     * @return {String}
     */
    public static String hex(String data) {
        if (StringUtil.isBlank(data)) {
            return StringPool.EMPTY;
        }
        return sha1Hex(data);
    }
    /**
     * ç”¨æˆ·å¯†ç åŠ å¯†è§„åˆ™ å…ˆMD5再SHA1
     *
     * @param data æ•°æ®
     * @return {String}
     */
    public static String encrypt(String data) {
        if (StringUtil.isBlank(data)) {
            return StringPool.EMPTY;
        }
        return sha1Hex(md5Hex(data));
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import cn.hutool.core.io.FastStringWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
/**
 * å¼‚常处理工具类
 *
 * @author L.cm
 */
public class Exceptions {
    /**
     * å°†CheckedException转换为UncheckedException.
     *
     * @param e Throwable
     * @return {RuntimeException}
     */
    public static RuntimeException unchecked(Throwable e) {
        if (e instanceof Error) {
            throw (Error) e;
        } else 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 if (e instanceof InterruptedException) {
            Thread.currentThread().interrupt();
        }
        return Exceptions.runtime(e);
    }
    /**
     * ä¸é‡‡ç”¨ RuntimeException åŒ…装,直接抛出,使异常更加精准
     *
     * @param throwable Throwable
     * @param <T>       æ³›åž‹æ ‡è®°
     * @return Throwable
     * @throws T æ³›åž‹
     */
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> T runtime(Throwable throwable) throws T {
        throw (T) throwable;
    }
    /**
     * ä»£ç†å¼‚常解包
     *
     * @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();
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,383 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
 * æ–‡ä»¶å·¥å…·ç±»
 *
 * @author L.cm
 */
public class FileUtil extends org.springframework.util.FileCopyUtils {
    /**
     * é»˜è®¤ä¸ºtrue
     *
     * @author L.cm
     */
    public static class TrueFilter implements FileFilter, Serializable {
        private static final long serialVersionUID = -6420452043795072619L;
        public final static TrueFilter TRUE = new TrueFilter();
        @Override
        public boolean accept(File pathname) {
            return true;
        }
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param path è·¯å¾„
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(String path) {
        File file = new File(path);
        return list(file, TrueFilter.TRUE);
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param path   è·¯å¾„
     * @param fileNamePattern æ–‡ä»¶å * å·
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(String path, final String fileNamePattern) {
        File file = new File(path);
        return list(file, pathname -> {
            String fileName = pathname.getName();
            return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
        });
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param path   è·¯å¾„
     * @param filter æ–‡ä»¶è¿‡æ»¤
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(String path, FileFilter filter) {
        File file = new File(path);
        return list(file, filter);
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param file æ–‡ä»¶
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(File file) {
        List<File> fileList = new ArrayList<>();
        return list(file, fileList, TrueFilter.TRUE);
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param file   æ–‡ä»¶
     * @param fileNamePattern Spring AntPathMatcher è§„则
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(File file, final String fileNamePattern) {
        List<File> fileList = new ArrayList<>();
        return list(file, fileList, pathname -> {
            String fileName = pathname.getName();
            return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
        });
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param file   æ–‡ä»¶
     * @param filter æ–‡ä»¶è¿‡æ»¤
     * @return æ–‡ä»¶é›†åˆ
     */
    public static List<File> list(File file, FileFilter filter) {
        List<File> fileList = new ArrayList<>();
        return list(file, fileList, filter);
    }
    /**
     * æ‰«æç›®å½•下的文件
     *
     * @param file   æ–‡ä»¶
     * @param filter æ–‡ä»¶è¿‡æ»¤
     * @return æ–‡ä»¶é›†åˆ
     */
    private static List<File> list(File file, List<File> fileList, FileFilter filter) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    list(f, fileList, filter);
                }
            }
        } else {
            // è¿‡æ»¤æ–‡ä»¶
            boolean accept = filter.accept(file);
            if (file.exists() && accept) {
                fileList.add(file);
            }
        }
        return fileList;
    }
    /**
     * èŽ·å–æ–‡ä»¶åŽç¼€å
     * @param fullName æ–‡ä»¶å…¨å
     * @return {String}
     */
    public static String getFileExtension(String fullName) {
        if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
        String fileName = new File(fullName).getName();
        int dotIndex = fileName.lastIndexOf(CharPool.DOT);
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
    }
    /**
     * èŽ·å–æ–‡ä»¶åï¼ŒåŽ»é™¤åŽç¼€å
     * @param fullName æ–‡ä»¶å…¨å
     * @return {String}
     */
    public static String getNameWithoutExtension(String fullName) {
        if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
        String fileName = new File(fullName).getName();
        int dotIndex = fileName.lastIndexOf(CharPool.DOT);
        return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
    }
    /**
     * Returns the path to the system temporary directory.
     *
     * @return the path to the system temporary directory.
     */
    public static String getTempDirPath() {
        return System.getProperty("java.io.tmpdir");
    }
    /**
     * Returns a {@link File} representing the system temporary directory.
     *
     * @return the system temporary directory.
     */
    public static File getTempDir() {
        return new File(getTempDirPath());
    }
    /**
     * Reads the contents of a file into a String.
     * The file is always closed.
     *
     * @param file the file to read, must not be {@code null}
     * @return the file contents, never {@code null}
     */
    public static String readToString(final File file) {
        return readToString(file, Charsets.UTF_8);
    }
    /**
     * Reads the contents of a file into a String.
     * The file is always closed.
     *
     * @param file     the file to read, must not be {@code null}
     * @param encoding the encoding to use, {@code null} means platform default
     * @return the file contents, never {@code null}
     */
    public static String readToString(final File file, final Charset encoding) {
        try (InputStream in = Files.newInputStream(file.toPath())) {
            return IoUtil.readToString(in, encoding);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * Reads the contents of a file into a String.
     * The file is always closed.
     *
     * @param file     the file to read, must not be {@code null}
     * @return the file contents, never {@code null}
     */
    public static byte[] readToByteArray(final File file) {
        try (InputStream in = Files.newInputStream(file.toPath())) {
            return IoUtil.readToByteArray(in);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * Writes a String to a file creating the file if it does not exist.
     *
     * @param file the file to write
     * @param data the content to write to the file
     */
    public static void writeToFile(final File file, final String data) {
        writeToFile(file, data, Charsets.UTF_8, false);
    }
    /**
     * Writes a String to a file creating the file if it does not exist.
     *
     * @param file   the file to write
     * @param data   the content to write to the file
     * @param append if {@code true}, then the String will be added to the
     *               end of the file rather than overwriting
     */
    public static void writeToFile(final File file, final String data, final boolean append){
        writeToFile(file, data, Charsets.UTF_8, append);
    }
    /**
     * Writes a String to a file creating the file if it does not exist.
     *
     * @param file     the file to write
     * @param data     the content to write to the file
     * @param encoding the encoding to use, {@code null} means platform default
     */
    public static void writeToFile(final File file, final String data, final Charset encoding) {
        writeToFile(file, data, encoding, false);
    }
    /**
     * Writes a String to a file creating the file if it does not exist.
     *
     * @param file     the file to write
     * @param data     the content to write to the file
     * @param encoding the encoding to use, {@code null} means platform default
     * @param append   if {@code true}, then the String will be added to the
     *                 end of the file rather than overwriting
     */
    public static void writeToFile(final File file, final String data, final Charset encoding, final boolean append) {
        try (OutputStream out = new FileOutputStream(file, append)) {
            IoUtil.write(data, out, encoding);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è½¬æˆfile
     * @param multipartFile MultipartFile
     * @param file File
     */
    public static void toFile(MultipartFile multipartFile, final File file) {
        try {
            FileUtil.toFile(multipartFile.getInputStream(), file);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è½¬æˆfile
     * @param in InputStream
     * @param file File
     */
    public static void toFile(InputStream in, final File file) {
        try (OutputStream out = new FileOutputStream(file)) {
            FileUtil.copy(in, out);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * Moves a file.
     * <p>
     * When the destination file is on another file system, do a "copy and delete".
     *
     * @param srcFile  the file to be moved
     * @param destFile the destination file
     * @throws NullPointerException if source or destination is {@code null}
     * @throws IOException          if source or destination is invalid
     * @throws IOException          if an IO error occurs moving the file
     */
    public static void moveFile(final File srcFile, final File destFile) throws IOException {
        Assert.notNull(srcFile, "Source must not be null");
        Assert.notNull(destFile, "Destination must not be null");
        if (!srcFile.exists()) {
            throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
        }
        if (srcFile.isDirectory()) {
            throw new IOException("Source '" + srcFile + "' is a directory");
        }
        if (destFile.exists()) {
            throw new IOException("Destination '" + destFile + "' already exists");
        }
        if (destFile.isDirectory()) {
            throw new IOException("Destination '" + destFile + "' is a directory");
        }
        final boolean rename = srcFile.renameTo(destFile);
        if (!rename) {
            FileUtil.copy(srcFile, destFile);
            if (!srcFile.delete()) {
                FileUtil.deleteQuietly(destFile);
                throw new IOException("Failed to delete original file '" + srcFile + "' after copy to '" + destFile + "'");
            }
        }
    }
    /**
     * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
     * <p>
     * The difference between File.delete() and this method are:
     * <ul>
     * <li>A directory to be deleted does not have to be empty.</li>
     * <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
     * </ul>
     *
     * @param file file or directory to delete, can be {@code null}
     * @return {@code true} if the file or directory was deleted, otherwise
     * {@code false}
     */
    public static boolean deleteQuietly(@Nullable final File file) {
        if (file == null) {
            return false;
        }
        try {
            if (file.isDirectory()) {
                FileSystemUtils.deleteRecursively(file);
            }
        } catch (final Exception ignored) {
        }
        try {
            return file.delete();
        } catch (final Exception ignored) {
            return false;
        }
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2140 @@
package com.vci.web.util;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.vci.web.util.jackson.JsonUtil;
import org.springframework.util.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.method.HandlerMethod;
import java.io.Closeable;
import java.io.File;
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.text.DecimalFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
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 {
    /**
     * æ–­è¨€ï¼Œå¿…须不能为 null
     * <blockquote><pre>
     * public Foo(Bar bar) {
     *     this.bar = $.requireNotNull(bar);
     * }
     * </pre></blockquote>
     *
     * @param obj the object reference to check for nullity
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNotNull(T obj) {
        return Objects.requireNonNull(obj);
    }
    /**
     * æ–­è¨€ï¼Œå¿…须不能为 null
     * <blockquote><pre>
     * public Foo(Bar bar, Baz baz) {
     *     this.bar = $.requireNotNull(bar, "bar must not be null");
     *     this.baz = $.requireNotNull(baz, "baz must not be null");
     * }
     * </pre></blockquote>
     *
     * @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 <T>     the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNotNull(T obj, String message) {
        return Objects.requireNonNull(obj, message);
    }
    /**
     * æ–­è¨€ï¼Œå¿…须不能为 null
     * <blockquote><pre>
     * public Foo(Bar bar, Baz baz) {
     *     this.bar = $.requireNotNull(bar, () -> "bar must not be null");
     * }
     * </pre></blockquote>
     *
     * @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 <T>             the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNotNull(T obj, Supplier<String> messageSupplier) {
        return Objects.requireNonNull(obj, messageSupplier);
    }
    /**
     * åˆ¤æ–­å¯¹è±¡æ˜¯å¦ä¸ºnull
     * <p>
     * This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter($::isNull)}
     * </p>
     *
     * @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
     */
    public static boolean isNull(@Nullable Object obj) {
        return Objects.isNull(obj);
    }
    /**
     * åˆ¤æ–­å¯¹è±¡æ˜¯å¦ not null
     * <p>
     * This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter($::notNull)}
     * </p>
     *
     * @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
     */
    public static boolean notNull(@Nullable Object obj) {
        return Objects.nonNull(obj);
    }
    /**
     * é¦–字母变小写
     *
     * @param str å­—符串
     * @return {String}
     */
    public static String firstCharToLower(String str) {
        return StringUtil.firstCharToLower(str);
    }
    /**
     * é¦–字母变大写
     *
     * @param str å­—符串
     * @return {String}
     */
    public static String firstCharToUpper(String str) {
        return StringUtil.firstCharToUpper(str);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦ä¸ºç©ºå­—符串
     * <pre class="code">
     * $.isBlank(null)        = true
     * $.isBlank("")        = true
     * $.isBlank(" ")        = true
     * $.isBlank("12345")    = false
     * $.isBlank(" 12345 ")    = false
     * </pre>
     *
     * @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);
    }
    /**
     * åˆ¤æ–­ä¸ä¸ºç©ºå­—符串
     * <pre>
     * $.isNotBlank(null)    = false
     * $.isNotBlank("")        = false
     * $.isNotBlank(" ")    = false
     * $.isNotBlank("bob")    = true
     * $.isNotBlank("  bob  ") = true
     * </pre>
     *
     * @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);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦æœ‰ä»»æ„ä¸€ä¸ª ç©ºå­—符串
     *
     * @param css CharSequence
     * @return boolean
     */
    public static boolean isAnyBlank(final CharSequence... css) {
        return StringUtil.isAnyBlank(css);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦å…¨ä¸ºéžç©ºå­—符串
     *
     * @param css CharSequence
     * @return boolean
     */
    public static boolean isNoneBlank(final CharSequence... css) {
        return StringUtil.isNoneBlank(css);
    }
    /**
     * åˆ¤æ–­å¯¹è±¡æ˜¯æ•°ç»„
     *
     * @param obj the object to check
     * @return æ˜¯å¦æ•°ç»„
     */
    public static boolean isArray(@Nullable Object obj) {
        return ObjectUtil.isArray(obj);
    }
    /**
     * åˆ¤æ–­ç©ºå¯¹è±¡ object、map、list、set、字符串、数组
     *
     * @param obj the object to check
     * @return æ•°ç»„是否为空
     */
    public static boolean isEmpty(@Nullable Object obj) {
        return ObjectUtil.isEmpty(obj);
    }
    /**
     * å¯¹è±¡ä¸ä¸ºç©º object、map、list、set、字符串、数组
     *
     * @param obj the object to check
     * @return æ˜¯å¦ä¸ä¸ºç©º
     */
    public static boolean isNotEmpty(@Nullable Object obj) {
        return !ObjectUtil.isEmpty(obj);
    }
    /**
     * åˆ¤æ–­æ•°ç»„为空
     *
     * @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 boolean
     */
    public static boolean hasEmpty(Object... os) {
        for (Object o : os) {
            if (isEmpty(o)) {
                return true;
            }
        }
        return false;
    }
    /**
     * å¯¹è±¡ç»„中是否全部为 Empty Object
     *
     * @param os å¯¹è±¡ç»„
     * @return boolean
     */
    public static boolean isAllEmpty(Object... os) {
        for (Object o : os) {
            if (isNotEmpty(o)) {
                return false;
            }
        }
        return true;
    }
    /**
     * å°†å­—符串中特定模式的字符转换成map中对应的值
     * <p>
     * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
     *
     * @param message éœ€è¦è½¬æ¢çš„字符串
     * @param params  è½¬æ¢æ‰€éœ€çš„键值对集合
     * @return è½¬æ¢åŽçš„字符串
     */
    public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
        return StringUtil.format(message, params);
    }
    /**
     * åŒ log æ ¼å¼çš„ format è§„则
     * <p>
     * use: format("my name is {}, and i like {}!", "L.cm", "Java")
     *
     * @param message   éœ€è¦è½¬æ¢çš„字符串
     * @param arguments éœ€è¦æ›¿æ¢çš„变量
     * @return è½¬æ¢åŽçš„字符串
     */
    public static String format(@Nullable String message, @Nullable Object... arguments) {
        return StringUtil.format(message, arguments);
    }
    /**
     * æ ¼å¼åŒ–执行时间,单位为 ms å’Œ s,保留三位小数
     *
     * @param nanos çº³ç§’
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String format(long nanos) {
        return StringUtil.format(nanos);
    }
    /**
     * æ¯”较两个对象是否相等。<br>
     * ç›¸åŒçš„æ¡ä»¶æœ‰ä¸¤ä¸ªï¼Œæ»¡è¶³å…¶ä¸€å³å¯ï¼š<br>
     *
     * @param obj1 å¯¹è±¡1
     * @param obj2 å¯¹è±¡2
     * @return æ˜¯å¦ç›¸ç­‰
     */
    public static boolean equals(Object obj1, Object obj2) {
        return Objects.equals(obj1, obj2);
    }
    /**
     * å®‰å…¨çš„ equals
     *
     * @param o1 first Object to compare
     * @param o2 second Object to compare
     * @return whether the given objects are equal
     * @see Object#equals(Object)
     * @see java.util.Arrays#equals
     */
    public static boolean equalsSafe(@Nullable Object o1, @Nullable Object o2) {
        return ObjectUtil.nullSafeEquals(o1, o2);
    }
    /**
     * åˆ¤æ–­æ•°ç»„中是否包含元素
     *
     * @param array   the Array to check
     * @param element the element to look for
     * @param <T>     The generic tag
     * @return {@code true} if found, {@code false} else
     */
    public static <T> boolean contains(@Nullable T[] array, final T element) {
        return CollectionUtil.contains(array, 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);
    }
    /**
     * åˆ¤æ–­æžšä¸¾æ˜¯å¦åŒ…含该元素
     *
     * @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);
    }
    /**
     * ä¸å¯å˜ Set
     *
     * @param es  å¯¹è±¡
     * @param <E> æ³›åž‹
     * @return é›†åˆ
     */
    @SafeVarargs
    public static <E> Set<E> ofImmutableSet(E... es) {
        return CollectionUtil.ofImmutableSet(es);
    }
    /**
     * ä¸å¯å˜ List
     *
     * @param es  å¯¹è±¡
     * @param <E> æ³›åž‹
     * @return é›†åˆ
     */
    @SafeVarargs
    public static <E> List<E> ofImmutableList(E... es) {
        return CollectionUtil.ofImmutableList(es);
    }
    /**
     * å¼ºè½¬string,并去掉多余空格
     *
     * @param str å­—符串
     * @return {String}
     */
    public static String toStr(Object str) {
        return toStr(str, "");
    }
    /**
     * å¼ºè½¬string,并去掉多余空格
     *
     * @param str          å­—符串
     * @param defaultValue é»˜è®¤å€¼
     * @return {String}
     */
    public static String toStr(Object str, String defaultValue) {
        if (null == str || str.equals(StringPool.NULL)) {
            return defaultValue;
        }
        return String.valueOf(str);
    }
    /**
     * å¼ºè½¬string(包含空字符串),并去掉多余空格
     *
     * @param str          å­—符串
     * @param defaultValue é»˜è®¤å€¼
     * @return {String}
     */
    public static String toStrWithEmpty(Object str, String defaultValue) {
        if (null == str || str.equals(StringPool.NULL) || str.equals(StringPool.EMPTY)) {
            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);
    }
    /**
     * å­—符串转 int,为空则返回0
     *
     * <pre>
     *   $.toInt(null) = 0
     *   $.toInt("")   = 0
     *   $.toInt("1")  = 1
     * </pre>
     *
     * @param str the string to convert, may be null
     * @return the int represented by the string, or <code>zero</code> if
     * conversion fails
     */
    public static int toInt(final Object str) {
        return NumberUtil.toInt(String.valueOf(str));
    }
    /**
     * å­—符串转 int,为空则返回默认值
     *
     * <pre>
     *   $.toInt(null, 1) = 1
     *   $.toInt("", 1)   = 1
     *   $.toInt("1", 0)  = 1
     * </pre>
     *
     * @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 Object str, final int defaultValue) {
        return NumberUtil.toInt(String.valueOf(str), defaultValue);
    }
    /**
     * å­—符串转 long,为空则返回0
     *
     * <pre>
     *   $.toLong(null) = 0L
     *   $.toLong("")   = 0L
     *   $.toLong("1")  = 1L
     * </pre>
     *
     * @param str the string to convert, may be null
     * @return the long represented by the string, or <code>0</code> if
     * conversion fails
     */
    public static long toLong(final Object str) {
        return NumberUtil.toLong(String.valueOf(str));
    }
    /**
     * å­—符串转 long,为空则返回默认值
     *
     * <pre>
     *   $.toLong(null, 1L) = 1L
     *   $.toLong("", 1L)   = 1L
     *   $.toLong("1", 0L)  = 1L
     * </pre>
     *
     * @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 Object str, final long defaultValue) {
        return NumberUtil.toLong(String.valueOf(str), defaultValue);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toDouble(null, 1) = 1.0
     *   $.toDouble("", 1)   = 1.0
     *   $.toDouble("1", 0)  = 1.0
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toDouble(null, 1) = 1.0
     *   $.toDouble("", 1)   = 1.0
     *   $.toDouble("1", 0)  = 1.0
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toFloat(null, 1) = 1.00f
     *   $.toFloat("", 1)   = 1.00f
     *   $.toFloat("1", 0)  = 1.00f
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toFloat(null, 1) = 1.00f
     *   $.toFloat("", 1)   = 1.00f
     *   $.toFloat("1", 0)  = 1.00f
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toBoolean("true", true)  = true
     *   $.toBoolean("false")       = false
     *   $.toBoolean("", false)      = false
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   $.toBoolean("true", true)  = true
     *   $.toBoolean("false")       = false
     *   $.toBoolean("", false)      = false
     * </pre>
     *
     * @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();
            return Boolean.parseBoolean(val);
        }
        return defaultValue;
    }
    /**
     * è½¬æ¢ä¸ºInteger数组<br>
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Integer[] toIntArray(String str) {
        return toIntArray(",", str);
    }
    /**
     * è½¬æ¢ä¸ºInteger数组<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @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;
    }
    /**
     * è½¬æ¢ä¸ºInteger集合<br>
     *
     * @param str ç»“果被转换的值
     * @return ç»“æžœ
     */
    public static List<Integer> toIntList(String str) {
        return Arrays.asList(toIntArray(str));
    }
    /**
     * è½¬æ¢ä¸ºInteger集合<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static List<Integer> toIntList(String split, String str) {
        return Arrays.asList(toIntArray(split, str));
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½Integer数值
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Integer firstInt(String str) {
        return firstInt(",", str);
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½Integer数值
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Integer firstInt(String split, String str) {
        List<Integer> ints = toIntList(split, str);
        if (isEmpty(ints)) {
            return null;
        } else {
            return ints.get(0);
        }
    }
    /**
     * è½¬æ¢ä¸ºLong数组<br>
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Long[] toLongArray(String str) {
        return toLongArray(",", str);
    }
    /**
     * è½¬æ¢ä¸ºLong数组<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Long[] toLongArray(String split, String str) {
        if (StringUtil.isEmpty(str)) {
            return new Long[]{};
        }
        String[] arr = str.split(split);
        final Long[] longs = new Long[arr.length];
        for (int i = 0; i < arr.length; i++) {
            final Long v = toLong(arr[i], 0);
            longs[i] = v;
        }
        return longs;
    }
    /**
     * è½¬æ¢ä¸ºLong集合<br>
     *
     * @param str ç»“果被转换的值
     * @return ç»“æžœ
     */
    public static List<Long> toLongList(String str) {
        return Arrays.asList(toLongArray(str));
    }
    /**
     * è½¬æ¢ä¸ºLong集合<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static List<Long> toLongList(String split, String str) {
        return Arrays.asList(toLongArray(split, str));
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½Long数值
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Long firstLong(String str) {
        return firstLong(",", str);
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½Long数值
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static Long firstLong(String split, String str) {
        List<Long> longs = toLongList(split, str);
        if (isEmpty(longs)) {
            return null;
        } else {
            return longs.get(0);
        }
    }
    /**
     * è½¬æ¢ä¸ºString数组<br>
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static String[] toStrArray(String str) {
        return toStrArray(",", str);
    }
    /**
     * è½¬æ¢ä¸ºString数组<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static String[] toStrArray(String split, String str) {
        if (isBlank(str)) {
            return new String[]{};
        }
        return str.split(split);
    }
    /**
     * è½¬æ¢ä¸ºString集合<br>
     *
     * @param str ç»“果被转换的值
     * @return ç»“æžœ
     */
    public static List<String> toStrList(String str) {
        return Arrays.asList(toStrArray(str));
    }
    /**
     * è½¬æ¢ä¸ºString集合<br>
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static List<String> toStrList(String split, String str) {
        return Arrays.asList(toStrArray(split, str));
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½String数值
     *
     * @param str è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static String firstStr(String str) {
        return firstStr(",", str);
    }
    /**
     * èŽ·å–ç¬¬ä¸€ä½String数值
     *
     * @param split åˆ†éš”符
     * @param str   è¢«è½¬æ¢çš„值
     * @return ç»“æžœ
     */
    public static String firstStr(String split, String str) {
        List<String> strs = toStrList(split, str);
        if (isEmpty(strs)) {
            return null;
        } else {
            return strs.get(0);
        }
    }
    /**
     * å°† long è½¬çŸ­å­—符串 ä¸º 62 è¿›åˆ¶
     *
     * @param num æ•°å­—
     * @return çŸ­å­—符串
     */
    public static String to62String(long num) {
        return NumberUtil.to62String(num);
    }
    /**
     * å°†é›†åˆæ‹¼æŽ¥æˆå­—符串,默认使用`,`拼接
     *
     * @param coll the {@code Collection} to convert
     * @return the delimited {@code String}
     */
    public static String join(Collection<?> coll) {
        return StringUtil.join(coll);
    }
    /**
     * å°†é›†åˆæ‹¼æŽ¥æˆå­—符串,默认指定分隔符
     *
     * @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);
    }
    /**
     * å°†æ•°ç»„拼接成字符串,默认使用`,`拼接
     *
     * @param arr the array to display
     * @return the delimited {@code String}
     */
    public static String join(Object[] arr) {
        return StringUtil.join(arr);
    }
    /**
     * å°†æ•°ç»„拼接成字符串,默认指定分隔符
     *
     * @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);
    }
    /**
     * åˆ‡åˆ†å­—符串,不去除切分后每个元素两边的空白符,不去除空白项
     *
     * @param str       è¢«åˆ‡åˆ†çš„字符串
     * @param separator åˆ†éš”符字符
     * @return åˆ‡åˆ†åŽçš„集合
     */
    public static List<String> split(CharSequence str, char separator) {
        return StringUtil.split(str, separator, -1);
    }
    /**
     * åˆ‡åˆ†å­—符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       è¢«åˆ‡åˆ†çš„字符串
     * @param separator åˆ†éš”符字符
     * @return åˆ‡åˆ†åŽçš„集合
     */
    public static List<String> splitTrim(CharSequence str, char separator) {
        return StringUtil.splitTrim(str, separator);
    }
    /**
     * åˆ‡åˆ†å­—符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       è¢«åˆ‡åˆ†çš„字符串
     * @param separator åˆ†éš”符字符
     * @return åˆ‡åˆ†åŽçš„集合
     */
    public static List<String> splitTrim(CharSequence str, CharSequence separator) {
        return StringUtil.splitTrim(str, separator);
    }
    /**
     * åˆ†å‰² å­—符串
     *
     * @param str       å­—符串
     * @param delimiter åˆ†å‰²ç¬¦
     * @return å­—符串数组
     */
    public static String[] split(@Nullable String str, @Nullable String delimiter) {
        return StringUtil.delimitedListToStringArray(str, delimiter);
    }
    /**
     * åˆ†å‰² å­—符串 åˆ é™¤å¸¸è§ ç©ºç™½ç¬¦
     *
     * @param str       å­—符串
     * @param delimiter åˆ†å‰²ç¬¦
     * @return å­—符串数组
     */
    public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
        return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
    }
    /**
     * å­—符串是否符合指定的 è¡¨è¾¾å¼
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param pattern è¡¨è¾¾å¼
     * @param str     å­—符串
     * @return æ˜¯å¦åŒ¹é…
     */
    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
        return PatternMatchUtils.simpleMatch(pattern, str);
    }
    /**
     * å­—符串是否符合指定的 è¡¨è¾¾å¼
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param patterns è¡¨è¾¾å¼ æ•°ç»„
     * @param str      å­—符串
     * @return æ˜¯å¦åŒ¹é…
     */
    public static boolean simpleMatch(@Nullable String[] patterns, String str) {
        return PatternMatchUtils.simpleMatch(patterns, str);
    }
    /**
     * ç”Ÿæˆ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);
    }
    /**
     * å­—符串序列化成 md5
     *
     * @param data Data to digest
     * @return MD5 digest as a hex string
     */
    public static String md5Hex(final String data) {
        return DigestUtil.md5Hex(data);
    }
    /**
     * æ•°ç»„序列化成 md5
     *
     * @param bytes the bytes to calculate the digest over
     * @return md5 digest string
     */
    public static String md5Hex(final byte[] bytes) {
        return DigestUtil.md5Hex(bytes);
    }
    /**
     * sha1Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha1Hex(String data) {
        return DigestUtil.sha1Hex(data);
    }
    /**
     * sha1Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha1Hex(final byte[] bytes) {
        return DigestUtil.sha1Hex(bytes);
    }
    /**
     * SHA224Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha224Hex(String data) {
        return DigestUtil.sha224Hex(data);
    }
    /**
     * SHA224Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha224Hex(final byte[] bytes) {
        return DigestUtil.sha224Hex(bytes);
    }
    /**
     * sha256Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha256Hex(String data) {
        return DigestUtil.sha256Hex(data);
    }
    /**
     * sha256Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha256Hex(final byte[] bytes) {
        return DigestUtil.sha256Hex(bytes);
    }
    /**
     * sha384Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha384Hex(String data) {
        return DigestUtil.sha384Hex(data);
    }
    /**
     * sha384Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha384Hex(final byte[] bytes) {
        return DigestUtil.sha384Hex(bytes);
    }
    /**
     * sha512Hex
     *
     * @param data Data to digest
     * @return digest as a hex string
     */
    public static String sha512Hex(String data) {
        return DigestUtil.sha512Hex(data);
    }
    /**
     * sha512Hex
     *
     * @param bytes Data to digest
     * @return digest as a hex string
     */
    public static String sha512Hex(final byte[] bytes) {
        return DigestUtil.sha512Hex(bytes);
    }
    /**
     * hmacMd5 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacMd5Hex(String data, String key) {
        return DigestUtil.hmacMd5Hex(data, key);
    }
    /**
     * hmacMd5 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacMd5Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacMd5Hex(bytes, key);
    }
    /**
     * hmacSha1 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha1Hex(String data, String key) {
        return DigestUtil.hmacSha1Hex(data, key);
    }
    /**
     * hmacSha1 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha1Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacSha1Hex(bytes, key);
    }
    /**
     * hmacSha224 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha224Hex(String data, String key) {
        return DigestUtil.hmacSha224Hex(data, key);
    }
    /**
     * hmacSha224 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha224Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacSha224Hex(bytes, key);
    }
    /**
     * hmacSha256 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha256Hex(String data, String key) {
        return DigestUtil.hmacSha256Hex(data, key);
    }
    /**
     * hmacSha256 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha256Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacSha256Hex(bytes, key);
    }
    /**
     * hmacSha384 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha384Hex(String data, String key) {
        return DigestUtil.hmacSha384Hex(data, key);
    }
    /**
     * hmacSha384 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha384Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacSha384Hex(bytes, key);
    }
    /**
     * hmacSha512 Hex
     *
     * @param data Data to digest
     * @param key  key
     * @return digest as a hex string
     */
    public static String hmacSha512Hex(String data, String key) {
        return DigestUtil.hmacSha512Hex(data, key);
    }
    /**
     * hmacSha512 Hex
     *
     * @param bytes Data to digest
     * @param key   key
     * @return digest as a hex string
     */
    public static String hmacSha512Hex(final byte[] bytes, String key) {
        return DigestUtil.hmacSha512Hex(bytes, key);
    }
    /**
     * byte æ•°ç»„序列化成 hex
     *
     * @param bytes bytes to encode
     * @return MD5 digest as a hex string
     */
    public static String encodeHex(byte[] bytes) {
        return DigestUtil.encodeHex(bytes);
    }
    /**
     * å­—符串反序列化成 hex
     *
     * @param hexString String to decode
     * @return MD5 digest as a hex string
     */
    public static byte[] decodeHex(final String hexString) {
        return DigestUtil.decodeHex(hexString);
    }
    /**
     * Base64编码
     *
     * @param value å­—符串
     * @return {String}
     */
    public static String encodeBase64(String value) {
        return Base64Util.encode(value);
    }
    /**
     * Base64编码
     *
     * @param value   å­—符串
     * @param charset å­—符集
     * @return {String}
     */
    public static String encodeBase64(String value, Charset charset) {
        return Base64Util.encode(value, charset);
    }
    /**
     * Base64编码为URL安全
     *
     * @param value å­—符串
     * @return {String}
     */
    public static String encodeBase64UrlSafe(String value) {
        return Base64Util.encodeUrlSafe(value);
    }
    /**
     * Base64编码为URL安全
     *
     * @param value   å­—符串
     * @param charset å­—符集
     * @return {String}
     */
    public static String encodeBase64UrlSafe(String value, Charset charset) {
        return Base64Util.encodeUrlSafe(value, charset);
    }
    /**
     * Base64解码
     *
     * @param value å­—符串
     * @return {String}
     */
    public static String decodeBase64(String value) {
        return Base64Util.decode(value);
    }
    /**
     * Base64解码
     *
     * @param value   å­—符串
     * @param charset å­—符集
     * @return {String}
     */
    public static String decodeBase64(String value, Charset charset) {
        return Base64Util.decode(value, charset);
    }
    /**
     * Base64URL安全解码
     *
     * @param value å­—符串
     * @return {String}
     */
    public static String decodeBase64UrlSafe(String value) {
        return Base64Util.decodeUrlSafe(value);
    }
    /**
     * Base64URL安全解码
     *
     * @param value   å­—符串
     * @param charset å­—符集
     * @return {String}
     */
    public static String decodeBase64UrlSafe(String value, Charset charset) {
        return Base64Util.decodeUrlSafe(value, charset);
    }
    /**
     * å…³é—­ Closeable
     *
     * @param closeable è‡ªåЍ关闭
     */
    public static void closeQuietly(@Nullable Closeable closeable) {
        IoUtil.closeQuietly(closeable);
    }
    /**
     * InputStream to String utf-8
     *
     * @param input the <code>InputStream</code> to read from
     * @return the requested String
     * @throws NullPointerException if the input is null
     */
    public static String readToString(InputStream input) {
        return IoUtil.readToString(input);
    }
    /**
     * InputStream to String
     *
     * @param input   the <code>InputStream</code> to read from
     * @param charset the <code>Charset</code>
     * @return the requested String
     * @throws NullPointerException if the input is null
     */
    public static String readToString(@Nullable InputStream input, Charset charset) {
        return IoUtil.readToString(input, charset);
    }
    /**
     * InputStream to bytes æ•°ç»„
     *
     * @param input InputStream
     * @return the requested byte array
     */
    public static byte[] readToByteArray(@Nullable InputStream input) {
        return IoUtil.readToByteArray(input);
    }
    /**
     * è¯»å–文件为字符串
     *
     * @param file the file to read, must not be {@code null}
     * @return the file contents, never {@code null}
     */
    public static String readToString(final File file) {
        return FileUtil.readToString(file);
    }
    /**
     * è¯»å–文件为字符串
     *
     * @param file     the file to read, must not be {@code null}
     * @param encoding the encoding to use, {@code null} means platform default
     * @return the file contents, never {@code null}
     */
    public static String readToString(File file, Charset encoding) {
        return FileUtil.readToString(file, encoding);
    }
    /**
     * è¯»å–文件为 byte æ•°ç»„
     *
     * @param file the file to read, must not be {@code null}
     * @return the file contents, never {@code null}
     */
    public static byte[] readToByteArray(File file) {
        return FileUtil.readToByteArray(file);
    }
    /**
     * å°†å¯¹è±¡åºåˆ—化成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>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(byte[] bytes, Class<T> valueType) {
        return JsonUtil.parse(bytes, valueType);
    }
    /**
     * å°†json反序列化成对象
     *
     * @param jsonString jsonString
     * @param valueType  class
     * @param <T>        T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(String jsonString, Class<T> valueType) {
        return JsonUtil.parse(jsonString, valueType);
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in        InputStream
     * @param valueType class
     * @param <T>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(InputStream in, Class<T> valueType) {
        return JsonUtil.parse(in, valueType);
    }
    /**
     * å°†json反序列化成对象
     *
     * @param bytes         bytes
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(byte[] bytes, TypeReference<T> typeReference) {
        return JsonUtil.parse(bytes, typeReference);
    }
    /**
     * å°†json反序列化成对象
     *
     * @param jsonString    jsonString
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(String jsonString, TypeReference<T> typeReference) {
        return JsonUtil.parse(jsonString, typeReference);
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in            InputStream
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T readJson(InputStream in, TypeReference<T> typeReference) {
        return JsonUtil.parse(in, typeReference);
    }
    /**
     * url ç¼–码
     *
     * @param source the String to be encoded
     * @return the encoded String
     */
    public static String urlEncode(String source) {
        return UrlUtil.encode(source, Charsets.UTF_8);
    }
    /**
     * url ç¼–码
     *
     * @param source  the String to be encoded
     * @param charset the character encoding to encode to
     * @return the encoded String
     */
    public static String urlEncode(String source, Charset charset) {
        return UrlUtil.encode(source, charset);
    }
    /**
     * url è§£ç 
     *
     * @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 urlDecode(String source) {
        return StringUtils.uriDecode(source, Charsets.UTF_8);
    }
    /**
     * url è§£ç 
     *
     * @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 urlDecode(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);
    }
    /**
     * å¯¹è±¡æ ¼å¼åŒ– æ”¯æŒæ•°å­—,date,java8时间
     *
     * @param object  æ ¼å¼åŒ–对象
     * @param pattern è¡¨è¾¾å¼
     * @return æ ¼å¼åŒ–后的字符串
     */
    public static String format(Object object, String pattern) {
        if (object instanceof Number) {
            DecimalFormat decimalFormat = new DecimalFormat(pattern);
            return decimalFormat.format(object);
        } else if (object instanceof Date) {
            return DateUtil.format((Date) object, pattern);
        } else if (object instanceof TemporalAccessor) {
            return DateTimeUtil.format((TemporalAccessor) object, pattern);
        }
        throw new IllegalArgumentException("未支持的对象:" + object + ",格式:" + object);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @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 dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
        return DateTimeUtil.parseDateTime(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalDateTime parseDateTime(String dateStr) {
        return DateTimeUtil.parseDateTime(dateStr);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
        return DateTimeUtil.parseDate(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为日期
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalDate parseDate(String dateStr) {
        return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr   æ—¶é—´å­—符串
     * @param formatter DateTimeFormatter
     * @return æ—¶é—´
     */
    public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
        return DateTimeUtil.parseTime(dateStr, formatter);
    }
    /**
     * å°†å­—符串转换为时间
     *
     * @param dateStr æ—¶é—´å­—符串
     * @return æ—¶é—´
     */
    public static LocalTime parseTime(String dateStr) {
        return DateTimeUtil.parseTime(dateStr);
    }
    /**
     * æ—¶é—´æ¯”较
     *
     * @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);
    }
    /**
     * æ¯”较2个 æ—¶é—´å·®
     *
     * @param startDate å¼€å§‹æ—¶é—´
     * @param endDate   ç»“束时间
     * @return æ—¶é—´é—´éš”
     */
    public static Duration between(Date startDate, Date endDate) {
        return DateUtil.between(startDate, endDate);
    }
    /**
     * å¯¹è±¡ç±»åž‹è½¬æ¢
     *
     * @param source     the source object
     * @param targetType the target type
     * @param <T>        æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     *                                  or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, Class<T> targetType) {
        return ConvertUtil.convert(source, targetType);
    }
    /**
     * å¯¹è±¡ç±»åž‹è½¬æ¢
     *
     * @param source     the source object
     * @param sourceType the source type
     * @param targetType the target type
     * @param <T>        æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     *                                  or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        return ConvertUtil.convert(source, sourceType, targetType);
    }
    /**
     * å¯¹è±¡ç±»åž‹è½¬æ¢
     *
     * @param source     the source object
     * @param targetType the target type
     * @param <T>        æ³›åž‹æ ‡è®°
     * @return the converted value
     * @throws IllegalArgumentException if targetType is {@code null},
     *                                  or sourceType is {@code null} but source is not {@code null}
     */
    @Nullable
    public static <T> T convert(@Nullable Object source, TypeDescriptor targetType) {
        return ConvertUtil.convert(source, targetType);
    }
    /**
     * èŽ·å–æ–¹æ³•å‚æ•°ä¿¡æ¯
     *
     * @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 <A>              æ³›åž‹æ ‡è®°
     * @return {Annotation}
     */
    @Nullable
    public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
        return AnnotatedElementUtils.findMergedAnnotation(annotatedElement, annotationType);
    }
    /**
     * èŽ·å–Annotation,先找方法,没有则再找方法上的类
     *
     * @param method         Method
     * @param annotationType æ³¨è§£ç±»
     * @param <A>            æ³›åž‹æ ‡è®°
     * @return {Annotation}
     */
    @Nullable
    public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
        return ClassUtil.getAnnotation(method, annotationType);
    }
    /**
     * èŽ·å–Annotation,先找HandlerMethod,没有则再找对应的类
     *
     * @param handlerMethod  HandlerMethod
     * @param annotationType æ³¨è§£ç±»
     * @param <A>            æ³›åž‹æ ‡è®°
     * @return {Annotation}
     */
    @Nullable
    public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
        return ClassUtil.getAnnotation(handlerMethod, annotationType);
    }
    /**
     * å®žä¾‹åŒ–对象
     *
     * @param clazz ç±»
     * @param <T>   æ³›åž‹æ ‡è®°
     * @return å¯¹è±¡
     */
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> clazz) {
        return (T) BeanUtil.instantiateClass(clazz);
    }
    /**
     * å®žä¾‹åŒ–对象
     *
     * @param clazzStr ç±»å
     * @param <T>      æ³›åž‹æ ‡è®°
     * @return å¯¹è±¡
     */
    public static <T> T newInstance(String clazzStr) {
        return BeanUtil.newInstance(clazzStr);
    }
    /**
     * èŽ·å–Bean的属性
     *
     * @param bean         bean
     * @param propertyName å±žæ€§å
     * @return å±žæ€§å€¼
     */
    @Nullable
    public static Object getProperty(@Nullable 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);
    }
    /**
     * æµ…复制
     *
     * @param source æºå¯¹è±¡
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T clone(@Nullable T source) {
        return BeanUtil.clone(source);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œæ”¯æŒ Map å’Œ Bean
     *
     * @param source æºå¯¹è±¡
     * @param clazz  ç±»å
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copy(@Nullable Object source, Class<T> clazz) {
        return BeanUtil.copy(source, clazz);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œæ”¯æŒ Map å’Œ Bean
     *
     * @param source     æºå¯¹è±¡
     * @param targetBean éœ€è¦èµ‹å€¼çš„对象
     */
    public static void copy(@Nullable Object source, @Nullable Object targetBean) {
        BeanUtil.copy(source, targetBean);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œsource å¯¹è±¡å±žæ€§åšéž null åˆ¤æ–­
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param source     æºå¯¹è±¡
     * @param targetBean éœ€è¦èµ‹å€¼çš„对象
     */
    public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) {
        BeanUtil.copyNonNull(source, targetBean);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œå¹¶å¯¹ä¸åŒç±»åž‹å±žæ€§è¿›è¡Œè½¬æ¢
     *
     * @param source æºå¯¹è±¡
     * @param clazz  ç±»å
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     */
    @Nullable
    public static <T> T copyWithConvert(@Nullable Object source, Class<T> clazz) {
        return BeanUtil.copyWithConvert(source, clazz);
    }
    /**
     * æ‹·è´åˆ—表对象
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param sourceList  æºåˆ—表
     * @param targetClazz è½¬æ¢æˆçš„类型
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return T
     */
    public static <T> List<T> copy(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
        return BeanUtil.copy(sourceList, targetClazz);
    }
    /**
     * æ‹·è´åˆ—表对象,并对不同类型属性进行转换
     *
     * <p>
     * æ”¯æŒ map bean copy
     * </p>
     *
     * @param sourceList  æºå¯¹è±¡åˆ—表
     * @param targetClazz è½¬æ¢æˆçš„ç±»
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return List
     */
    public static <T> List<T> copyWithConvert(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
        return BeanUtil.copyWithConvert(sourceList, targetClazz);
    }
    /**
     * æ‹·è´å¯¹è±¡ï¼Œæ‰©å±• Spring çš„æ‹·è´æ–¹æ³•
     *
     * @param source the source bean
     * @param clazz  the target bean class
     * @param <T>    æ³›åž‹æ ‡è®°
     * @return T
     * @throws BeansException if the copying failed
     */
    @Nullable
    public static <T> T copyProperties(@Nullable Object source, Class<T> clazz) throws BeansException {
        return BeanUtil.copyProperties(source, clazz);
    }
    /**
     * æ‹·è´åˆ—表对象,扩展 Spring çš„æ‹·è´æ–¹æ³•
     *
     * @param sourceList  the source list bean
     * @param targetClazz the target bean class
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return List
     * @throws BeansException if the copying failed
     */
    public static <T> List<T> copyProperties(@Nullable Collection<?> sourceList, Class<T> targetClazz) throws BeansException {
        return BeanUtil.copyProperties(sourceList, targetClazz);
    }
    /**
     * å°†å¯¹è±¡è£…成map形式
     *
     * @param bean æºå¯¹è±¡
     * @return {Map}
     */
    public static Map<String, Object> toMap(@Nullable Object bean) {
        return BeanUtil.toMap(bean);
    }
    /**
     * å°†map è½¬ä¸º bean
     *
     * @param beanMap   map
     * @param valueType å¯¹è±¡ç±»åž‹
     * @param <T>       æ³›åž‹æ ‡è®°
     * @return {T}
     */
    public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) {
        return BeanUtil.toBean(beanMap, valueType);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.vci.web.util;
import java.security.SecureRandom;
import java.util.Random;
/**
 * ä¸€äº›å¸¸ç”¨çš„单例对象
 *
 * @author L.cm
 */
public class Holder {
    /**
     * RANDOM
     */
    public final static Random RANDOM = new Random();
    /**
     * SECURE_RANDOM
     */
    public final static SecureRandom SECURE_RANDOM = new SecureRandom();
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import org.springframework.lang.Nullable;
import java.io.*;
import java.nio.charset.Charset;
/**
 * æµå·¥å…·ç±»
 *
 * @author L.cm
 */
public class IoUtil extends org.springframework.util.StreamUtils {
    /**
     * closeQuietly
     *
     * @param closeable è‡ªåЍ关闭
     */
    public static void closeQuietly(@Nullable Closeable closeable) {
        if (closeable == null) {
            return;
        }
        if (closeable instanceof Flushable) {
            try {
                ((Flushable) closeable).flush();
            } catch (IOException ignored) {
                // ignore
            }
        }
        try {
            closeable.close();
        } catch (IOException ignored) {
            // ignore
        }
    }
    /**
     * InputStream to String utf-8
     *
     * @param input the <code>InputStream</code> to read from
     * @return the requested String
     */
    public static String readToString(InputStream input) {
        return readToString(input, Charsets.UTF_8);
    }
    /**
     * InputStream to String
     *
     * @param input   the <code>InputStream</code> to read from
     * @param charset the <code>Charset</code>
     * @return the requested String
     */
    public static String readToString(@Nullable InputStream input, Charset charset) {
        try {
            return IoUtil.copyToString(input, charset);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        } finally {
            IoUtil.closeQuietly(input);
        }
    }
    public static byte[] readToByteArray(@Nullable InputStream input) {
        try {
            return IoUtil.copyToByteArray(input);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        } finally {
            IoUtil.closeQuietly(input);
        }
    }
    /**
     * Writes chars from a <code>String</code> to bytes on an
     * <code>OutputStream</code> using the specified character encoding.
     * <p>
     * This method uses {@link String#getBytes(String)}.
     * </p>
     * @param data     the <code>String</code> to write, null ignored
     * @param output   the <code>OutputStream</code> to write to
     * @param encoding the encoding to use, null means platform default
     * @throws NullPointerException if output is null
     * @throws IOException          if an I/O error occurs
     */
    public static void write(@Nullable final String data, final OutputStream output, final Charset encoding) throws IOException {
        if (data != null) {
            output.write(data.getBytes(encoding));
        }
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,195 @@
package com.vci.web.util;
import org.springframework.lang.Nullable;
/**
 * æ•°å­—类型工具类
 *
 * @author L.cm
 */
public class NumberUtil extends org.springframework.util.NumberUtils {
    //-----------------------------------------------------------------------
    /**
     * <p>Convert a <code>String</code> to an <code>int</code>, returning
     * <code>zero</code> if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
     *
     * <pre>
     *   NumberUtil.toInt(null) = 0
     *   NumberUtil.toInt("")   = 0
     *   NumberUtil.toInt("1")  = 1
     * </pre>
     *
     * @param str the string to convert, may be null
     * @return the int represented by the string, or <code>zero</code> if
     * conversion fails
     */
    public static int toInt(final String str) {
        return toInt(str, -1);
    }
    /**
     * <p>Convert a <code>String</code> to an <code>int</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   NumberUtil.toInt(null, 1) = 1
     *   NumberUtil.toInt("", 1)   = 1
     *   NumberUtil.toInt("1", 0)  = 1
     * </pre>
     *
     * @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;
        }
    }
    /**
     * <p>Convert a <code>String</code> to a <code>long</code>, returning
     * <code>zero</code> if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
     *
     * <pre>
     *   NumberUtil.toLong(null) = 0L
     *   NumberUtil.toLong("")   = 0L
     *   NumberUtil.toLong("1")  = 1L
     * </pre>
     *
     * @param str the string to convert, may be null
     * @return the long represented by the string, or <code>0</code> if
     * conversion fails
     */
    public static long toLong(final String str) {
        return toLong(str, 0L);
    }
    /**
     * <p>Convert a <code>String</code> to a <code>long</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   NumberUtil.toLong(null, 1L) = 1L
     *   NumberUtil.toLong("", 1L)   = 1L
     *   NumberUtil.toLong("1", 0L)  = 1L
     * </pre>
     *
     * @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;
        }
    }
    /**
     * <p>Convert a <code>String</code> to a <code>Double</code>
     *
     * @param value value
     * @return double value
     */
    public static Double toDouble(String value) {
        return toDouble(value, null);
    }
    /**
     * <p>Convert a <code>String</code> to a <code>Double</code>
     *
     * @param value 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;
    }
    /**
     * <p>Convert a <code>String</code> to a <code>Double</code>
     *
     * @param value value
     * @return double value
     */
    public static Float toFloat(String value) {
        return toFloat(value, null);
    }
    /**
     * <p>Convert a <code>String</code> to a <code>Double</code>
     *
     * @param value 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));
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.vci.web.util;
import org.springframework.lang.Nullable;
/**
 * å¯¹è±¡å·¥å…·ç±»
 *
 * @author L.cm
 */
public class ObjectUtil extends org.springframework.util.ObjectUtils {
    /**
     * åˆ¤æ–­å…ƒç´ ä¸ä¸ºç©º
     * @param obj object
     * @return boolean
     */
    public static boolean isNotEmpty(@Nullable Object obj) {
        return !ObjectUtil.isEmpty(obj);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/PlatformClientUtil.java
@@ -105,7 +105,6 @@
       return BOFactoryServiceHelper.narrow(jacorbClientConnector.getCorbaServiceObjectByServiceName(BO_FACTORY_SERVICE_NAME));
    }
    /**
     * èŽ·å–ç™»å½•ä¸»æœåŠ¡
     * @return æœåŠ¡çš„å¯¹è±¡
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.vci.web.util;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
 * ç”Ÿæˆçš„随机数类型
 *
 * @author L.cm
 */
@Getter
@RequiredArgsConstructor
public enum RandomType {
    /**
     * INT STRING ALL
     */
    INT(RandomType.INT_STR),
    STRING(RandomType.STR_STR),
    ALL(RandomType.ALL_STR);
    private final String factor;
    /**
     * éšæœºå­—符串因子
     */
    private static final String INT_STR = "0123456789";
    private static final String STR_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final String ALL_STR = INT_STR + STR_STR;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ReflectUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,180 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import org.springframework.beans.BeansException;
import org.springframework.cglib.core.CodeGenerationException;
import org.springframework.core.convert.Property;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
 * åå°„工具类
 *
 * @author L.cm
 */
public class ReflectUtil extends ReflectionUtils {
    /**
     * èŽ·å– Bean çš„æ‰€æœ‰ get方法
     *
     * @param type ç±»
     * @return PropertyDescriptor数组
     */
    public static PropertyDescriptor[] getBeanGetters(Class type) {
        return getPropertiesHelper(type, true, false);
    }
    /**
     * èŽ·å– Bean çš„æ‰€æœ‰ set方法
     *
     * @param type ç±»
     * @return PropertyDescriptor数组
     */
    public static PropertyDescriptor[] getBeanSetters(Class type) {
        return getPropertiesHelper(type, false, true);
    }
    /**
     * èŽ·å– Bean çš„æ‰€æœ‰ PropertyDescriptor
     *
     * @param type ç±»
     * @param read è¯»å–方法
     * @param write å†™æ–¹æ³•
     * @return PropertyDescriptor数组
     */
    public static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) {
        try {
            PropertyDescriptor[] all = BeanUtil.getPropertyDescriptors(type);
            if (read && write) {
                return all;
            } else {
                List<PropertyDescriptor> properties = new ArrayList<>(all.length);
                for (PropertyDescriptor pd : all) {
                    if (read && pd.getReadMethod() != null) {
                        properties.add(pd);
                    } else if (write && pd.getWriteMethod() != null) {
                        properties.add(pd);
                    }
                }
                return properties.toArray(new PropertyDescriptor[0]);
            }
        } catch (BeansException ex) {
            throw new CodeGenerationException(ex);
        }
    }
    /**
     * èŽ·å– bean çš„属性信息
     * @param propertyType ç±»åž‹
     * @param propertyName å±žæ€§å
     * @return {Property}
     */
    @Nullable
    public static Property getProperty(Class<?> propertyType, String propertyName) {
        PropertyDescriptor propertyDescriptor = BeanUtil.getPropertyDescriptor(propertyType, propertyName);
        if (propertyDescriptor == null) {
            return null;
        }
        return ReflectUtil.getProperty(propertyType, propertyDescriptor, propertyName);
    }
    /**
     * èŽ·å– bean çš„属性信息
     * @param propertyType ç±»åž‹
     * @param propertyDescriptor PropertyDescriptor
     * @param propertyName å±žæ€§å
     * @return {Property}
     */
    public static Property getProperty(Class<?> propertyType, PropertyDescriptor propertyDescriptor, String propertyName) {
        Method readMethod = propertyDescriptor.getReadMethod();
        Method writeMethod = propertyDescriptor.getWriteMethod();
        return new Property(propertyType, readMethod, writeMethod, propertyName);
    }
    /**
     * èŽ·å– bean çš„属性信息
     * @param propertyType ç±»åž‹
     * @param propertyName å±žæ€§å
     * @return {Property}
     */
    @Nullable
    public static TypeDescriptor getTypeDescriptor(Class<?> propertyType, String propertyName) {
        Property property = ReflectUtil.getProperty(propertyType, propertyName);
        if (property == null) {
            return null;
        }
        return new TypeDescriptor(property);
    }
    /**
     * èŽ·å– ç±»å±žæ€§ä¿¡æ¯
     * @param propertyType ç±»åž‹
     * @param propertyDescriptor PropertyDescriptor
     * @param propertyName å±žæ€§å
     * @return {Property}
     */
    public static TypeDescriptor getTypeDescriptor(Class<?> propertyType, PropertyDescriptor propertyDescriptor, String propertyName) {
        Method readMethod = propertyDescriptor.getReadMethod();
        Method writeMethod = propertyDescriptor.getWriteMethod();
        Property property = new Property(propertyType, readMethod, writeMethod, propertyName);
        return new TypeDescriptor(property);
    }
    /**
     * èŽ·å– ç±»å±žæ€§
     * @param clazz ç±»ä¿¡æ¯
     * @param fieldName å±žæ€§å
     * @return Field
     */
    @Nullable
    public static Field getField(Class<?> clazz, String fieldName) {
        while (clazz != Object.class) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
        }
        return null;
    }
    /**
     * èŽ·å– æ‰€æœ‰ field å±žæ€§ä¸Šçš„æ³¨è§£
     * @param clazz ç±»
     * @param fieldName å±žæ€§å
     * @param annotationClass æ³¨è§£
     * @param <T> æ³¨è§£æ³›åž‹
     * @return æ³¨è§£
     */
    @Nullable
    public static <T extends Annotation> T getAnnotation(Class<?> clazz, String fieldName, Class<T> annotationClass) {
        Field field = ReflectUtil.getField(clazz, fieldName);
        if (field == null) {
            return null;
        }
        return field.getAnnotation(annotationClass);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.vci.web.util;
/**
 * é™æ€ String æ± 
 *
 * @author L.cm
 */
public interface StringPool {
    String AMPERSAND        = "&";
    String AND                = "and";
    String AT                = "@";
    String ASTERISK            = "*";
    String STAR                = ASTERISK;
    String SLASH            = "/";
    String BACK_SLASH        = "\\";
    String DOUBLE_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 MINUS_ONE        = "-1";
    String DOLLAR_LEFT_BRACE= "${";
    String UNKNOWN            = "unknown";
    String GET                = "GET";
    String POST                = "POST";
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1560 @@
package com.vci.web.util;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.util.HtmlUtils;
import com.vci.web.support.StrSpliter;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
 * ç»§æ‰¿è‡ªSpring util的工具类,减少jar依赖
 *
 * @author L.cm
 */
public class StringUtil extends org.springframework.util.StringUtils {
    public static final int INDEX_NOT_FOUND = -1;
    // public static final int INDEX_NOT_FOUND = 0;
    /**
     * Check whether the given {@code CharSequence} contains actual <em>text</em>.
     * <p>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.
     * <pre class="code">
     * StringUtil.isBlank(null) = true
     * StringUtil.isBlank("") = true
     * StringUtil.isBlank(" ") = true
     * StringUtil.isBlank("12345") = false
     * StringUtil.isBlank(" 12345 ") = false
     * </pre>
     *
     * @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);
    }
    /**
     * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
     * <pre>
     * StringUtil.isNotBlank(null)      = false
     * StringUtil.isNotBlank("")        = false
     * StringUtil.isNotBlank(" ")       = false
     * StringUtil.isNotBlank("bob")     = true
     * StringUtil.isNotBlank("  bob  ") = true
     * </pre>
     *
     * @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);
    }
    /**
     * æ˜¯å¦å…¨ä¸º Blank
     *
     * @param css CharSequence
     * @return boolean
     */
    public static boolean isAllBlank(final CharSequence... css) {
        return Stream.of(css).allMatch(StringUtil::isBlank);
    }
    /**
     * åˆ¤æ–­ä¸€ä¸ªå­—符串是否是数字
     *
     * @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;
    }
    /**
     * å°†å­—符串中特定模式的字符转换成map中对应的值
     * <p>
     * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
     *
     * @param message éœ€è¦è½¬æ¢çš„字符串
     * @param params  è½¬æ¢æ‰€éœ€çš„键值对集合
     * @return è½¬æ¢åŽçš„字符串
     */
    public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
        // message ä¸º null è¿”回空字符串
        if (message == null) {
            return StringPool.EMPTY;
        }
        // å‚数为 null æˆ–者为空
        if (params == null || params.isEmpty()) {
            return message;
        }
        // æ›¿æ¢å˜é‡
        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
        int cursor = 0;
        for (int start, end; (start = message.indexOf(StringPool.DOLLAR_LEFT_BRACE, cursor)) != -1 && (end = message.indexOf(StringPool.RIGHT_BRACE, start)) != -1; ) {
            sb.append(message, cursor, start);
            String key = message.substring(start + 2, end);
            Object value = params.get(StringUtil.trimWhitespace(key));
            sb.append(value == null ? StringPool.EMPTY : value);
            cursor = end + 1;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }
    /**
     * åŒ log æ ¼å¼çš„ format è§„则
     * <p>
     * use: format("my name is {}, and i like {}!", "L.cm", "Java")
     *
     * @param message   éœ€è¦è½¬æ¢çš„字符串
     * @param arguments éœ€è¦æ›¿æ¢çš„变量
     * @return è½¬æ¢åŽçš„字符串
     */
    public static String format(@Nullable String message, @Nullable Object... arguments) {
        // message ä¸º null è¿”回空字符串
        if (message == null) {
            return StringPool.EMPTY;
        }
        // å‚数为 null æˆ–者为空
        if (arguments == null || arguments.length == 0) {
            return message;
        }
        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
        int cursor = 0;
        int index = 0;
        int argsLength = arguments.length;
        for (int start, end; (start = message.indexOf('{', cursor)) != -1 && (end = message.indexOf('}', start)) != -1 && index < argsLength; ) {
            sb.append(message, cursor, start);
            sb.append(arguments[index]);
            cursor = end + 1;
            index++;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }
    /**
     * æ ¼å¼åŒ–执行时间,单位为 ms å’Œ s,保留三位小数
     *
     * @param nanos çº³ç§’
     * @return æ ¼å¼åŒ–后的时间
     */
    public static String format(long nanos) {
        if (nanos < 1) {
            return "0ms";
        }
        double millis = (double) nanos / (1000 * 1000);
        // ä¸å¤Ÿ 1 ms,最小单位为 ms
        if (millis > 1000) {
            return String.format("%.3fs", millis / 1000);
        } else {
            return String.format("%.3fms", millis);
        }
    }
    /**
     * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV).
     * <p>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).
     * <p>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).
     * <p>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).
     * <p>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);
    }
    /**
     * å­—符串是否符合指定的 è¡¨è¾¾å¼
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param pattern è¡¨è¾¾å¼
     * @param str     å­—符串
     * @return æ˜¯å¦åŒ¹é…
     */
    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
        return PatternMatchUtils.simpleMatch(pattern, str);
    }
    /**
     * å­—符串是否符合指定的 è¡¨è¾¾å¼
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param patterns è¡¨è¾¾å¼ æ•°ç»„
     * @param str      å­—符串
     * @return æ˜¯å¦åŒ¹é…
     */
    public static boolean simpleMatch(@Nullable String[] patterns, String str) {
        return PatternMatchUtils.simpleMatch(patterns, str);
    }
    /**
     * ç”Ÿæˆ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 StringUtil.isBlank(html) ? StringPool.EMPTY : HtmlUtils.htmlEscape(html);
    }
    /**
     * æ¸…理字符串,清理出某些不可见字符
     *
     * @param txt å­—符串
     * @return {String}
     */
    public static String cleanChars(String txt) {
        return txt.replaceAll("[ ã€€`·•�\\f\\t\\v\\s]", "");
    }
    /**
     * ç‰¹æ®Šå­—符正则,sql特殊字符和空白符
     */
    private final static Pattern SPECIAL_CHARS_REGEX = Pattern.compile("[`'\"|/,;()-+*%#·•� \\s]");
    /**
     * æ¸…理字符串,清理出某些不可见字符和一些sql特殊字符
     *
     * @param txt æ–‡æœ¬
     * @return {String}
     */
    @Nullable
    public static String cleanText(@Nullable String txt) {
        if (txt == null) {
            return null;
        }
        return SPECIAL_CHARS_REGEX.matcher(txt).replaceAll(StringPool.EMPTY);
    }
    /**
     * èŽ·å–æ ‡è¯†ç¬¦ï¼Œç”¨äºŽå‚æ•°æ¸…ç†
     *
     * @param param å‚æ•°
     * @return æ¸…理后的标识符
     */
    @Nullable
    public static String cleanIdentifier(@Nullable String param) {
        if (param == null) {
            return null;
        }
        StringBuilder paramBuilder = new StringBuilder();
        for (int i = 0; i < param.length(); i++) {
            char c = param.charAt(i);
            if (Character.isJavaIdentifierPart(c)) {
                paramBuilder.append(c);
            }
        }
        return paramBuilder.toString();
    }
    /**
     * éšæœºæ•°ç”Ÿæˆ
     *
     * @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 StringPool.EMPTY;
        }
        Assert.isTrue(count > 0, "Requested random string length " + count + " is less than 0.");
        final Random random = Holder.SECURE_RANDOM;
        char[] buffer = new char[count];
        for (int i = 0; i < count; i++) {
            String factor = randomType.getFactor();
            buffer[i] = factor.charAt(random.nextInt(factor.length()));
        }
        return new String(buffer);
    }
    /**
     * æœ‰åºçš„æ ¼å¼åŒ–文本,使用{number}做为占位符<br>
     * ä¾‹ï¼š<br>
     * é€šå¸¸ä½¿ç”¨ï¼šformat("this is {0} for {1}", "a", "b") =》 this is a for b<br>
     *
     * @param pattern   æ–‡æœ¬æ ¼å¼
     * @param arguments å‚æ•°
     * @return æ ¼å¼åŒ–后的文本
     */
    public static String indexedFormat(CharSequence pattern, Object... arguments) {
        return MessageFormat.format(pattern.toString(), arguments);
    }
    /**
     * æ ¼å¼åŒ–文本,使用 {varName} å ä½<br>
     * 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<String> split(CharSequence str, char separator, int limit) {
        return split(str, separator, limit, false, false);
    }
    /**
     * åˆ†å‰² å­—符串 åˆ é™¤å¸¸è§ ç©ºç™½ç¬¦
     *
     * @param str       å­—符串
     * @param delimiter åˆ†å‰²ç¬¦
     * @return å­—符串数组
     */
    public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
        return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
    }
    /**
     * åˆ‡åˆ†å­—符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       è¢«åˆ‡åˆ†çš„字符串
     * @param separator åˆ†éš”符字符
     * @return åˆ‡åˆ†åŽçš„集合
     * @since 3.1.2
     */
    public static List<String> splitTrim(CharSequence str, char separator) {
        return splitTrim(str, separator, -1);
    }
    /**
     * åˆ‡åˆ†å­—符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       è¢«åˆ‡åˆ†çš„字符串
     * @param separator åˆ†éš”符字符
     * @return åˆ‡åˆ†åŽçš„集合
     * @since 3.2.0
     */
    public static List<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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;
    }
    /**
     * æ˜¯å¦åŒ…含特定字符,忽略大小写,如果给定两个参数都为<code>null</code>,返回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());
    }
    /**
     * æŸ¥æ‰¾æŒ‡å®šå­—符串是否包含指定字符串列表中的任意一个字符串<br>
     * å¿½ç•¥å¤§å°å†™
     *
     * @param str      æŒ‡å®šå­—符串
     * @param testStrs éœ€è¦æ£€æŸ¥çš„字符串数组
     * @return æ˜¯å¦åŒ…含任意一个字符串
     * @since 3.2.0
     */
    public static boolean containsAnyIgnoreCase(CharSequence str, CharSequence... testStrs) {
        return null != getContainsStrIgnoreCase(str, testStrs);
    }
    /**
     * æŸ¥æ‰¾æŒ‡å®šå­—符串是否包含指定字符串列表中的任意一个字符串,如果包含返回找到的第一个字符串<br>
     * å¿½ç•¥å¤§å°å†™
     *
     * @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<br>
     * index从0开始计算,最后一个字符为-1<br>
     * å¦‚æžœfrom和to位置一样,返回 "" <br>
     * å¦‚æžœfrom或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br>
     * å¦‚果经过修正的index中from大于to,则互换from和to example: <br>
     * abcdefgh 2 3 =》 c <br>
     * abcdefgh 2 -3 =》 cde <br>
     *
     * @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);
    }
    /**
     * æˆªå–分隔字符串之前的字符串,不包括分隔字符串<br>
     * å¦‚果给定的字符串为空串(null或"")或者分隔字符串为null,返回原字符串<br>
     * å¦‚果分隔字符串为空串"",则返回空串,如果分隔字符串未找到,返回原字符串
     * <p>
     * æ —子:
     *
     * <pre>
     * 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"
     * </pre>
     *
     * @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);
    }
    /**
     * æˆªå–分隔字符串之后的字符串,不包括分隔字符串<br>
     * å¦‚果给定的字符串为空串(null或""),返回原字符串<br>
     * å¦‚果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串
     * <p>
     * æ —子:
     *
     * <pre>
     * 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"
     * </pre>
     *
     * @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());
    }
    /**
     * æˆªå–指定字符串中间部分,不包括标识字符串<br>
     * <p>
     * æ —子:
     *
     * <pre>
     * 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"
     * </pre>
     *
     * @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;
    }
    /**
     * æˆªå–指定字符串中间部分,不包括标识字符串<br>
     * <p>
     * æ —子:
     *
     * <pre>
     * StringUtil.subBetween(null, *)            = null
     * StringUtil.subBetween("", "")             = ""
     * StringUtil.subBetween("", "tag")          = null
     * StringUtil.subBetween("tagabctag", null)  = null
     * StringUtil.subBetween("tagabctag", "")    = ""
     * StringUtil.subBetween("tagabctag", "tag") = "abc"
     * </pre>
     *
     * @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 firstCharToLower(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 firstCharToLower(String str) {
        char firstChar = str.charAt(0);
        if (firstChar >= CharPool.UPPER_A && firstChar <= CharPool.UPPER_Z) {
            char[] arr = str.toCharArray();
            arr[0] += (CharPool.LOWER_A - CharPool.UPPER_A);
            return new String(arr);
        }
        return str;
    }
    /**
     * é¦–字母变大写
     *
     * @param str å­—符串
     * @return {String}
     */
    public static String firstCharToUpper(String str) {
        char firstChar = str.charAt(0);
        if (firstChar >= CharPool.LOWER_A && firstChar <= CharPool.LOWER_Z) {
            char[] arr = str.toCharArray();
            arr[0] -= (CharPool.LOWER_A - CharPool.UPPER_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;
    }
    /**
     * æŒ‡å®šèŒƒå›´å†…查找字符串,忽略大小写<br>
     *
     * <pre>
     * 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
     * </pre>
     *
     * @param str       å­—符串
     * @param searchStr éœ€è¦æŸ¥æ‰¾ä½ç½®çš„字符串
     * @return ä½ç½®
     * @since 3.2.1
     */
    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
        return indexOfIgnoreCase(str, searchStr, 0);
    }
    /**
     * æŒ‡å®šèŒƒå›´å†…查找字符串
     *
     * <pre>
     * 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
     * </pre>
     *
     * @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;
    }
    /**
     * æŒ‡å®šèŒƒå›´å†…查找字符串,忽略大小写<br>
     *
     * @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());
    }
    /**
     * æŒ‡å®šèŒƒå›´å†…查找字符串,忽略大小写<br>
     *
     * @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);
    }
    /**
     * æŒ‡å®šèŒƒå›´å†…查找字符串<br>
     *
     * @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 æ¬¡å‡ºçŽ°çš„ä½ç½®ã€‚<br>
     * æ­¤æ–¹æ³•来自:Apache-Commons-Lang
     * <p>
     * æ —子(*代表任意字符):
     *
     * <pre>
     * 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
     * </pre>
     *
     * @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;
    }
    /**
     * æˆªå–两个字符串的不同部分(长度一致),判断截取的子串是否相同<br>
     * ä»»æ„ä¸€ä¸ªå­—符串为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);
    }
    /**
     * æ¯”较两个字符串(大小写敏感)。
     *
     * <pre>
     * equalsIgnoreCase(null, null)   = true
     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
     * </pre>
     *
     * @param str1 è¦æ¯”较的字符串1
     * @param str2 è¦æ¯”较的字符串2
     * @return å¦‚果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     */
    public static boolean equals(CharSequence str1, CharSequence str2) {
        return equals(str1, str2, false);
    }
    /**
     * æ¯”较两个字符串(大小写不敏感)。
     *
     * <pre>
     * equalsIgnoreCase(null, null)   = true
     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
     * </pre>
     *
     * @param str1 è¦æ¯”较的字符串1
     * @param str2 è¦æ¯”较的字符串2
     * @return å¦‚果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     */
    public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
        return equals(str1, str2, true);
    }
    /**
     * æ¯”较两个字符串是否相等。
     *
     * @param str1       è¦æ¯”较的字符串1
     * @param str2       è¦æ¯”较的字符串2
     * @param ignoreCase æ˜¯å¦å¿½ç•¥å¤§å°å†™
     * @return å¦‚果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     * @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 {String}Builder对象
     */
    public static StringBuilder builder() {
        return new StringBuilder();
    }
    /**
     * åˆ›å»ºStringBuilder对象
     *
     * @param capacity åˆå§‹å¤§å°
     * @return {String}Builder对象
     */
    public static StringBuilder builder(int capacity) {
        return new StringBuilder(capacity);
    }
    /**
     * åˆ›å»ºStringBuilder对象
     *
     * @param strs åˆå§‹å­—符串列表
     * @return {String}Builder对象
     */
    public static StringBuilder builder(CharSequence... strs) {
        final StringBuilder sb = new StringBuilder();
        for (CharSequence str : strs) {
            sb.append(str);
        }
        return sb;
    }
    /**
     * åˆ›å»ºStringBuilder对象
     *
     * @param sb   åˆå§‹StringBuilder
     * @param strs åˆå§‹å­—符串列表
     * @return {String}Builder对象
     */
    public static StringBuilder appendBuilder(StringBuilder sb, CharSequence... strs) {
        for (CharSequence str : strs) {
            sb.append(str);
        }
        return sb;
    }
    /**
     * èŽ·å¾—StringReader
     *
     * @param str å­—符串
     * @return {String}Reader
     */
    public static StringReader getReader(CharSequence str) {
        if (null == str) {
            return null;
        }
        return new StringReader(str.toString());
    }
    /**
     * èŽ·å¾—StringWriter
     *
     * @return {String}Writer
     */
    public static StringWriter getWriter() {
        return new StringWriter();
    }
    /**
     * ç»Ÿè®¡æŒ‡å®šå†…容中包含指定字符串的数量<br>
     * å‚数为 {@code null} æˆ–者 "" è¿”回 {@code 0}.
     *
     * <pre>
     * 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
     * </pre>
     *
     * @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;
    }
    /**
     * ä¸‹åˆ’线转驼峰
     *
     * @param para å­—符串
     * @return {String}
     */
    public static String underlineToHump(String para) {
        if (isBlank(para)) {
            return StringPool.EMPTY;
        }
        StringBuilder result = new StringBuilder();
        String[] a = para.split("_");
        for (String s : a) {
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }
    /**
     * é©¼å³°è½¬ä¸‹åˆ’线
     *
     * @param para å­—符串
     * @return {String}
     */
    public static String humpToUnderline(String para) {
        if (isBlank(para)) {
            return StringPool.EMPTY;
        }
        para = firstCharToLower(para);
        StringBuilder sb = new StringBuilder(para);
        int temp = 0;
        for (int i = 0; i < para.length(); i++) {
            if (Character.isUpperCase(para.charAt(i))) {
                sb.insert(i + temp, "_");
                temp += 1;
            }
        }
        return sb.toString().toLowerCase();
    }
    /**
     * æ¨ªçº¿è½¬é©¼å³°
     *
     * @param para å­—符串
     * @return {String}
     */
    public static String lineToHump(String para) {
        if (isBlank(para)) {
            return StringPool.EMPTY;
        }
        StringBuilder result = new StringBuilder();
        String[] a = para.split("-");
        for (String s : a) {
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }
    /**
     * é©¼å³°è½¬æ¨ªçº¿
     *
     * @param para å­—符串
     * @return {String}
     */
    public static String humpToLine(String para) {
        if (isBlank(para)) {
            return StringPool.EMPTY;
        }
        para = firstCharToLower(para);
        StringBuilder sb = new StringBuilder(para);
        int temp = 0;
        for (int i = 0; i < para.length(); i++) {
            if (Character.isUpperCase(para.charAt(i))) {
                sb.insert(i + temp, "-");
                temp += 1;
            }
        }
        return sb.toString().toLowerCase();
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Unchecked.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import com.vci.web.util.function.*;
import java.util.Comparator;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
 * Lambda å—检异常处理
 *
 * <p>
 * https://segmentfault.com/a/1190000007832130
 * https://github.com/jOOQ/jOOL
 * </p>
 *
 * @author L.cm
 */
public class Unchecked {
    public static <T, R> Function<T, R> function(CheckedFunction<T, R> mapper) {
        Objects.requireNonNull(mapper);
        return t -> {
            try {
                return mapper.apply(t);
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
    public static <T> Consumer<T> consumer(CheckedConsumer<T> mapper) {
        Objects.requireNonNull(mapper);
        return t -> {
            try {
                mapper.accept(t);
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
    public static <T> Supplier<T> supplier(CheckedSupplier<T> mapper) {
        Objects.requireNonNull(mapper);
        return () -> {
            try {
                return mapper.get();
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
    public static Runnable runnable(CheckedRunnable runnable) {
        Objects.requireNonNull(runnable);
        return () -> {
            try {
                runnable.run();
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
    public static <T> Callable<T> callable(CheckedCallable<T> callable) {
        Objects.requireNonNull(callable);
        return () -> {
            try {
                return callable.call();
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
    public static <T> Comparator<T> comparator(CheckedComparator<T> comparator) {
        Objects.requireNonNull(comparator);
        return (T o1, T o2) -> {
            try {
                return comparator.compare(o1, o2);
            } catch (Throwable e) {
                throw Exceptions.unchecked(e);
            }
        };
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/UrlUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
/**
 * url处理工具类
 *
 * @author L.cm
 */
public class UrlUtil extends org.springframework.web.util.UriUtils {
    /**
     * url ç¼–码
     *
     * @param source source
     * @return sourced String
     */
    public static String encode(String source) {
        return UrlUtil.encode(source, Charsets.UTF_8);
    }
    /**
     * url è§£ç 
     *
     * @param source source
     * @return decoded String
     */
    public static String decode(String source) {
        return UrlUtil.decode(source, Charsets.UTF_8);
    }
    /**
     * url ç¼–码
     *
     * @param source  url
     * @param charset å­—符集
     * @return ç¼–码后的url
     */
    @Deprecated
    public static String encodeURL(String source, Charset charset) {
        return UrlUtil.encode(source, charset.name());
    }
    /**
     * url è§£ç 
     *
     * @param source  url
     * @param charset å­—符集
     * @return è§£ç url
     */
    @Deprecated
    public static String decodeURL(String source, Charset charset) {
        return UrlUtil.decode(source, charset.name());
    }
    /**
     * èŽ·å–url路径
     *
     * @param uriStr è·¯å¾„
     * @return url路径
     */
    public static String getPath(String uriStr) {
        URI uri;
        try {
            uri = new URI(uriStr);
        } catch (URISyntaxException var3) {
            throw new RuntimeException(var3);
        }
        return uri.getPath();
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BeanProperty.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.vci.web.util.beans;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * Bean属性
 *
 * @author Chill
 */
@Getter
@AllArgsConstructor
public class BeanProperty {
    private final String name;
    private final Class<?> type;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanCopier.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,404 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.beans;
import com.vci.web.util.BeanUtil;
import com.vci.web.util.ClassUtil;
import com.vci.web.util.ReflectUtil;
import com.vci.web.util.StringUtil;
import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Label;
import org.springframework.asm.Opcodes;
import org.springframework.asm.Type;
import org.springframework.cglib.core.*;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
 * spring cglib é­”改
 *
 * <p>
 *     1. æ”¯æŒé“¾å¼ bean,支持 map
 *     2. ClassLoader è·Ÿ target ä¿æŒä¸€è‡´
 * </p>
 *
 * @author L.cm
 */
public abstract class BladeBeanCopier {
    private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter");
    private static final Type BEAN_COPIER = TypeUtils.parseType(BladeBeanCopier.class.getName());
    private static final Type BEAN_MAP = TypeUtils.parseType(Map.class.getName());
    private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER});
    private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)");
    private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object)");
    private static final Type CLASS_UTILS = TypeUtils.parseType(ClassUtils.class.getName());
    private static final Signature IS_ASSIGNABLE_VALUE = TypeUtils.parseSignature("boolean isAssignableValue(Class, Object)");
    /**
     * The map to store {@link BladeBeanCopier} of source type and class type for copy.
     */
    private static final ConcurrentMap<BladeBeanCopierKey, BladeBeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();
    public static BladeBeanCopier create(Class source, Class target, boolean useConverter) {
        return BladeBeanCopier.create(source, target, useConverter, false);
    }
    public static BladeBeanCopier create(Class source, Class target, boolean useConverter, boolean nonNull) {
        BladeBeanCopierKey copierKey = new BladeBeanCopierKey(source, target, useConverter, nonNull);
        // åˆ©ç”¨ ConcurrentMap ç¼“å­˜ æé«˜æ€§èƒ½ï¼ŒæŽ¥è¿‘ ç›´æŽ¥ get set
        return BEAN_COPIER_MAP.computeIfAbsent(copierKey, key -> {
            Generator gen = new Generator();
            gen.setSource(key.getSource());
            gen.setTarget(key.getTarget());
            gen.setUseConverter(key.isUseConverter());
            gen.setNonNull(key.isNonNull());
            return gen.create(key);
        });
    }
    /**
     * Bean copy
     *
     * @param from from Bean
     * @param to to Bean
     * @param converter Converter
     */
    abstract public void copy(Object from, Object to, @Nullable Converter converter);
    public static class Generator extends AbstractClassGenerator {
        private static final Source SOURCE = new Source(BladeBeanCopier.class.getName());
        private Class source;
        private Class target;
        private boolean useConverter;
        private boolean nonNull;
        Generator() {
            super(SOURCE);
        }
        public void setSource(Class source) {
            if (!Modifier.isPublic(source.getModifiers())) {
                setNamePrefix(source.getName());
            }
            this.source = source;
        }
        public void setTarget(Class target) {
            if (!Modifier.isPublic(target.getModifiers())) {
                setNamePrefix(target.getName());
            }
            this.target = target;
        }
        public void setUseConverter(boolean useConverter) {
            this.useConverter = useConverter;
        }
        public void setNonNull(boolean nonNull) {
            this.nonNull = nonNull;
        }
        @Override
        protected ClassLoader getDefaultClassLoader() {
            // L.cm ä¿è¯ å’Œ è¿”回使用同一个 ClassLoader
            return target.getClassLoader();
        }
        @Override
        protected ProtectionDomain getProtectionDomain() {
            return ReflectUtils.getProtectionDomain(source);
        }
        @Override
        public BladeBeanCopier create(Object key) {
            return (BladeBeanCopier) super.create(key);
        }
        @Override
        public void generateClass(ClassVisitor v) {
            Type sourceType = Type.getType(source);
            Type targetType = Type.getType(target);
            ClassEmitter ce = new ClassEmitter(v);
            ce.begin_class(Constants.V1_2,
                Constants.ACC_PUBLIC,
                getClassName(),
                BEAN_COPIER,
                null,
                Constants.SOURCE_FILE);
            EmitUtils.null_constructor(ce);
            CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
            // map å•独处理
            if (Map.class.isAssignableFrom(source)) {
                generateClassFormMap(ce, e, sourceType, targetType);
                return;
            }
            // 2018.12.27 by L.cm æ”¯æŒé“¾å¼ bean
            // æ³¨æ„ï¼šæ­¤å¤„需兼容链式bean ä½¿ç”¨äº† spring çš„æ–¹æ³•,比较耗时
            PropertyDescriptor[] getters = ReflectUtil.getBeanGetters(source);
            PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(target);
            Map<String, PropertyDescriptor> names = new HashMap<>(16);
            for (PropertyDescriptor getter : getters) {
                names.put(getter.getName(), getter);
            }
            Local targetLocal = e.make_local();
            Local sourceLocal = e.make_local();
            e.load_arg(1);
            e.checkcast(targetType);
            e.store_local(targetLocal);
            e.load_arg(0);
            e.checkcast(sourceType);
            e.store_local(sourceLocal);
            for (PropertyDescriptor setter : setters) {
                String propName = setter.getName();
                CopyProperty targetIgnoreCopy = ReflectUtil.getAnnotation(target, propName, CopyProperty.class);
                // set ä¸Šæœ‰å¿½ç•¥çš„ æ³¨è§£
                if (targetIgnoreCopy != null) {
                    if (targetIgnoreCopy.ignore()) {
                        continue;
                    }
                    // æ³¨è§£ä¸Šçš„别名,如果别名不为空,使用别名
                    String aliasTargetPropName = targetIgnoreCopy.value();
                    if (StringUtil.isNotBlank(aliasTargetPropName)) {
                        propName = aliasTargetPropName;
                    }
                }
                // æ‰¾åˆ°å¯¹åº”çš„ get
                PropertyDescriptor getter = names.get(propName);
                // æ²¡æœ‰ get è·³å‡º
                if (getter == null) {
                    continue;
                }
                MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
                Method writeMethod = setter.getWriteMethod();
                MethodInfo write = ReflectUtils.getMethodInfo(writeMethod);
                Type returnType = read.getSignature().getReturnType();
                Type setterType = write.getSignature().getArgumentTypes()[0];
                Class<?> getterPropertyType = getter.getPropertyType();
                Class<?> setterPropertyType = setter.getPropertyType();
                // L.cm 2019.01.12 ä¼˜åŒ–逻辑,先判断类型,类型一致直接 set,不同再判断 æ˜¯å¦ ç±»åž‹è½¬æ¢
                // nonNull Label
                Label l0 = e.make_label();
                // åˆ¤æ–­ç±»åž‹æ˜¯å¦ä¸€è‡´ï¼ŒåŒ…括 åŒ…装类型
                if (ClassUtil.isAssignable(setterPropertyType, getterPropertyType)) {
                    // 2018.12.27 by L.cm æ”¯æŒé“¾å¼ bean
                    e.load_local(targetLocal);
                    e.load_local(sourceLocal);
                    e.invoke(read);
                    boolean getterIsPrimitive = getterPropertyType.isPrimitive();
                    boolean setterIsPrimitive = setterPropertyType.isPrimitive();
                    if (nonNull) {
                        // éœ€è¦è½æ ˆï¼Œå¼ºåˆ¶è£…ç®±
                        e.box(returnType);
                        Local var = e.make_local();
                        e.store_local(var);
                        e.load_local(var);
                        // nonNull Label
                        e.ifnull(l0);
                        e.load_local(targetLocal);
                        e.load_local(var);
                        // éœ€è¦è½æ ˆï¼Œå¼ºåˆ¶æ‹†ç®±
                        e.unbox_or_zero(setterType);
                    } else {
                        // å¦‚æžœ get ä¸ºåŽŸå§‹ç±»åž‹ï¼Œéœ€è¦è£…ç®±
                        if (getterIsPrimitive && !setterIsPrimitive) {
                            e.box(returnType);
                        }
                        // å¦‚æžœ set ä¸ºåŽŸå§‹ç±»åž‹ï¼Œéœ€è¦æ‹†ç®±
                        if (!getterIsPrimitive && setterIsPrimitive) {
                            e.unbox_or_zero(setterType);
                        }
                    }
                    // æž„造 set æ–¹æ³•
                    invokeWrite(e, write, writeMethod, nonNull, l0);
                } else if (useConverter) {
                    e.load_local(targetLocal);
                    e.load_arg(2);
                    e.load_local(sourceLocal);
                    e.invoke(read);
                    e.box(returnType);
                    if (nonNull) {
                        Local var = e.make_local();
                        e.store_local(var);
                        e.load_local(var);
                        e.ifnull(l0);
                        e.load_local(targetLocal);
                        e.load_arg(2);
                        e.load_local(var);
                    }
                    EmitUtils.load_class(e, setterType);
                    // æ›´æ”¹æˆäº†å±žæ€§åï¼Œä¹‹å‰æ˜¯ set æ–¹æ³•名
                    e.push(propName);
                    e.invoke_interface(CONVERTER, CONVERT);
                    e.unbox_or_zero(setterType);
                    // æž„造 set æ–¹æ³•
                    invokeWrite(e, write, writeMethod, nonNull, l0);
                }
            }
            e.return_value();
            e.end_method();
            ce.end_class();
        }
        private static void invokeWrite(CodeEmitter e, MethodInfo write, Method writeMethod, boolean nonNull, Label l0) {
            // è¿”回值,判断 é“¾å¼ bean
            Class<?> returnType = writeMethod.getReturnType();
            e.invoke(write);
            // é“¾å¼ bean,有返回值需要 pop
            if (!returnType.equals(Void.TYPE)) {
                e.pop();
            }
            if (nonNull) {
                e.visitLabel(l0);
            }
        }
        @Override
        protected Object firstInstance(Class type) {
            return BeanUtil.newInstance(type);
        }
        @Override
        protected Object nextInstance(Object instance) {
            return instance;
        }
        /**
         * å¤„理 map çš„ copy
         * @param ce ClassEmitter
         * @param e CodeEmitter
         * @param sourceType sourceType
         * @param targetType targetType
         */
        public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType, Type targetType) {
            // 2018.12.27 by L.cm æ”¯æŒé“¾å¼ bean
            PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(target);
            // å…¥å£å˜é‡
            Local targetLocal = e.make_local();
            Local sourceLocal = e.make_local();
            e.load_arg(1);
            e.checkcast(targetType);
            e.store_local(targetLocal);
            e.load_arg(0);
            e.checkcast(sourceType);
            e.store_local(sourceLocal);
            Type mapBox = Type.getType(Object.class);
            for (PropertyDescriptor setter : setters) {
                String propName = setter.getName();
                // set ä¸Šæœ‰å¿½ç•¥çš„ æ³¨è§£
                CopyProperty targetIgnoreCopy = ReflectUtil.getAnnotation(target, propName, CopyProperty.class);
                if (targetIgnoreCopy != null) {
                    if (targetIgnoreCopy.ignore()) {
                        continue;
                    }
                    // æ³¨è§£ä¸Šçš„别名
                    String aliasTargetPropName = targetIgnoreCopy.value();
                    if (StringUtil.isNotBlank(aliasTargetPropName)) {
                        propName = aliasTargetPropName;
                    }
                }
                Method writeMethod = setter.getWriteMethod();
                MethodInfo write = ReflectUtils.getMethodInfo(writeMethod);
                Type setterType = write.getSignature().getArgumentTypes()[0];
                e.load_local(targetLocal);
                e.load_local(sourceLocal);
                e.push(propName);
                // æ‰§è¡Œ map get
                e.invoke_interface(BEAN_MAP, BEAN_MAP_GET);
                // box è£…箱,避免 array[] æ•°ç»„问题
                e.box(mapBox);
                // ç”Ÿæˆå˜é‡
                Local var = e.make_local();
                e.store_local(var);
                e.load_local(var);
                // å…ˆåˆ¤æ–­ ä¸ä¸ºnull,然后做类型判断
                Label l0 = e.make_label();
                e.ifnull(l0);
                EmitUtils.load_class(e, setterType);
                e.load_local(var);
                // ClassUtils.isAssignableValue(Integer.class, id)
                e.invoke_static(CLASS_UTILS, IS_ASSIGNABLE_VALUE);
                Label l1 = new Label();
                // è¿”回值,判断 é“¾å¼ bean
                Class<?> returnType = writeMethod.getReturnType();
                if (useConverter) {
                    e.if_jump(Opcodes.IFEQ, l1);
                    e.load_local(targetLocal);
                    e.load_local(var);
                    e.unbox_or_zero(setterType);
                    e.invoke(write);
                    if (!returnType.equals(Void.TYPE)) {
                        e.pop();
                    }
                    e.goTo(l0);
                    e.visitLabel(l1);
                    e.load_local(targetLocal);
                    e.load_arg(2);
                    e.load_local(var);
                    EmitUtils.load_class(e, setterType);
                    e.push(propName);
                    e.invoke_interface(CONVERTER, CONVERT);
                    e.unbox_or_zero(setterType);
                    e.invoke(write);
                } else {
                    e.if_jump(Opcodes.IFEQ, l0);
                    e.load_local(targetLocal);
                    e.load_local(var);
                    e.unbox_or_zero(setterType);
                    e.invoke(write);
                }
                // è¿”回值,判断 é“¾å¼ bean
                if (!returnType.equals(Void.TYPE)) {
                    e.pop();
                }
                e.visitLabel(l0);
            }
            e.return_value();
            e.end_method();
            ce.end_class();
        }
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanCopierKey.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.vci.web.util.beans;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
/**
 * copy key
 *
 * @author L.cm
 */
@Getter
@EqualsAndHashCode
@AllArgsConstructor
public class BladeBeanCopierKey {
    private final Class<?> source;
    private final Class<?> target;
    private final boolean useConverter;
    private final boolean nonNull;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMap.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
package com.vci.web.util.beans;
import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ReflectUtils;
import java.security.ProtectionDomain;
/**
 * é‡å†™ cglib BeanMap,支持链式bean
 *
 * @author L.cm
 */
public abstract class BladeBeanMap extends BeanMap {
    protected BladeBeanMap() {
    }
    protected BladeBeanMap(Object bean) {
        super(bean);
    }
    public static BladeBeanMap create(Object bean) {
        BladeGenerator gen = new BladeGenerator();
        gen.setBean(bean);
        return gen.create();
    }
    /**
     * newInstance
     *
     * @param o Object
     * @return BladeBeanMap
     */
    @Override
    public abstract BladeBeanMap newInstance(Object o);
    public static class BladeGenerator extends AbstractClassGenerator {
        private static final Source SOURCE = new Source(BladeBeanMap.class.getName());
        private Object bean;
        private Class beanClass;
        private int require;
        public BladeGenerator() {
            super(SOURCE);
        }
        /**
         * Set the bean that the generated map should reflect. The bean may be swapped
         * out for another bean of the same type using {@link #setBean}.
         * Calling this method overrides any value previously set using {@link #setBeanClass}.
         * You must call either this method or {@link #setBeanClass} before {@link #create}.
         *
         * @param bean the initial bean
         */
        public void setBean(Object bean) {
            this.bean = bean;
            if (bean != null) {
                beanClass = bean.getClass();
            }
        }
        /**
         * Set the class of the bean that the generated map should support.
         * You must call either this method or {@link #setBeanClass} before {@link #create}.
         *
         * @param beanClass the class of the bean
         */
        public void setBeanClass(Class beanClass) {
            this.beanClass = beanClass;
        }
        /**
         * Limit the properties reflected by the generated map.
         *
         * @param require any combination of {@link #REQUIRE_GETTER} and
         *                {@link #REQUIRE_SETTER}; default is zero (any property allowed)
         */
        public void setRequire(int require) {
            this.require = require;
        }
        @Override
        protected ClassLoader getDefaultClassLoader() {
            return beanClass.getClassLoader();
        }
        @Override
        protected ProtectionDomain getProtectionDomain() {
            return ReflectUtils.getProtectionDomain(beanClass);
        }
        /**
         * Create a new instance of the <code>BeanMap</code>. An existing
         * generated class will be reused if possible.
         *
         * @return {BladeBeanMap}
         */
        public BladeBeanMap create() {
            if (beanClass == null) {
                throw new IllegalArgumentException("Class of bean unknown");
            }
            setNamePrefix(beanClass.getName());
            BladeBeanMapKey key = new BladeBeanMapKey(beanClass, require);
            return (BladeBeanMap) super.create(key);
        }
        @Override
        public void generateClass(ClassVisitor v) throws Exception {
            new BladeBeanMapEmitter(v, getClassName(), beanClass, require);
        }
        @Override
        protected Object firstInstance(Class type) {
            return ((BeanMap) ReflectUtils.newInstance(type)).newInstance(bean);
        }
        @Override
        protected Object nextInstance(Object instance) {
            return ((BeanMap) instance).newInstance(bean);
        }
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMapEmitter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,192 @@
package com.vci.web.util.beans;
import com.vci.web.util.ReflectUtil;
import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Label;
import org.springframework.asm.Type;
import org.springframework.cglib.core.*;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
 * é‡å†™ cglib BeanMap å¤„理器
 *
 * @author L.cm
 */
class BladeBeanMapEmitter extends ClassEmitter {
    private static final Type BEAN_MAP = TypeUtils.parseType(BladeBeanMap.class.getName());
    private static final Type FIXED_KEY_SET = TypeUtils.parseType("org.springframework.cglib.beans.FixedKeySet");
    private static final Signature CSTRUCT_OBJECT = TypeUtils.parseConstructor("Object");
    private static final Signature CSTRUCT_STRING_ARRAY = TypeUtils.parseConstructor("String[]");
    private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object, Object)");
    private static final Signature BEAN_MAP_PUT = TypeUtils.parseSignature("Object put(Object, Object, Object)");
    private static final Signature KEY_SET = TypeUtils.parseSignature("java.util.Set keySet()");
    private static final Signature NEW_INSTANCE = new Signature("newInstance", BEAN_MAP, new Type[]{Constants.TYPE_OBJECT});
    private static final Signature GET_PROPERTY_TYPE = TypeUtils.parseSignature("Class getPropertyType(String)");
    public BladeBeanMapEmitter(ClassVisitor v, String className, Class type, int require) {
        super(v);
        begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BEAN_MAP, null, Constants.SOURCE_FILE);
        EmitUtils.null_constructor(this);
        EmitUtils.factory_method(this, NEW_INSTANCE);
        generateConstructor();
        Map<String, PropertyDescriptor> getters = makePropertyMap(ReflectUtil.getBeanGetters(type));
        Map<String, PropertyDescriptor> setters = makePropertyMap(ReflectUtil.getBeanSetters(type));
        Map<String, PropertyDescriptor> allProps = new HashMap<>(32);
        allProps.putAll(getters);
        allProps.putAll(setters);
        if (require != 0) {
            for (Iterator it = allProps.keySet().iterator(); it.hasNext(); ) {
                String name = (String) it.next();
                if ((((require & BladeBeanMap.REQUIRE_GETTER) != 0) && !getters.containsKey(name)) ||
                    (((require & BladeBeanMap.REQUIRE_SETTER) != 0) && !setters.containsKey(name))) {
                    it.remove();
                    getters.remove(name);
                    setters.remove(name);
                }
            }
        }
        generateGet(type, getters);
        generatePut(type, setters);
        String[] allNames = getNames(allProps);
        generateKeySet(allNames);
        generateGetPropertyType(allProps, allNames);
        end_class();
    }
    private Map<String, PropertyDescriptor> makePropertyMap(PropertyDescriptor[] props) {
        Map<String, PropertyDescriptor> names = new HashMap<>(16);
        for (PropertyDescriptor prop : props) {
            String propName = prop.getName();
            // è¿‡æ»¤ getClass,Spring çš„工具类会拿到该方法
            if (!"class".equals(propName)) {
                names.put(propName, prop);
            }
        }
        return names;
    }
    private String[] getNames(Map<String, PropertyDescriptor> propertyMap) {
        return propertyMap.keySet().toArray(new String[0]);
    }
    private void generateConstructor() {
        CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
        e.load_this();
        e.load_arg(0);
        e.super_invoke_constructor(CSTRUCT_OBJECT);
        e.return_value();
        e.end_method();
    }
    private void generateGet(Class type, final Map<String, PropertyDescriptor> getters) {
        final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
        e.load_arg(0);
        e.checkcast(Type.getType(type));
        e.load_arg(1);
        e.checkcast(Constants.TYPE_STRING);
        EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
            @Override
            public void processCase(Object key, Label end) {
                PropertyDescriptor pd = getters.get(key);
                MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
                e.invoke(method);
                e.box(method.getSignature().getReturnType());
                e.return_value();
            }
            @Override
            public void processDefault() {
                e.aconst_null();
                e.return_value();
            }
        });
        e.end_method();
    }
    private void generatePut(Class type, final Map<String, PropertyDescriptor> setters) {
        final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null);
        e.load_arg(0);
        e.checkcast(Type.getType(type));
        e.load_arg(1);
        e.checkcast(Constants.TYPE_STRING);
        EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
            @Override
            public void processCase(Object key, Label end) {
                PropertyDescriptor pd = setters.get(key);
                if (pd.getReadMethod() == null) {
                    e.aconst_null();
                } else {
                    MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod());
                    e.dup();
                    e.invoke(read);
                    e.box(read.getSignature().getReturnType());
                }
                // move old value behind bean
                e.swap();
                // new value
                e.load_arg(2);
                MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod());
                e.unbox(write.getSignature().getArgumentTypes()[0]);
                e.invoke(write);
                e.return_value();
            }
            @Override
            public void processDefault() {
                // fall-through
            }
        });
        e.aconst_null();
        e.return_value();
        e.end_method();
    }
    private void generateKeySet(String[] allNames) {
        // static initializer
        declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null);
        CodeEmitter e = begin_static();
        e.new_instance(FIXED_KEY_SET);
        e.dup();
        EmitUtils.push_array(e, allNames);
        e.invoke_constructor(FIXED_KEY_SET, CSTRUCT_STRING_ARRAY);
        e.putfield("keys");
        e.return_value();
        e.end_method();
        // keySet
        e = begin_method(Constants.ACC_PUBLIC, KEY_SET, null);
        e.load_this();
        e.getfield("keys");
        e.return_value();
        e.end_method();
    }
    private void generateGetPropertyType(final Map allProps, String[] allNames) {
        final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null);
        e.load_arg(0);
        EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
            @Override
            public void processCase(Object key, Label end) {
                PropertyDescriptor pd = (PropertyDescriptor) allProps.get(key);
                EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
                e.return_value();
            }
            @Override
            public void processDefault() {
                e.aconst_null();
                e.return_value();
            }
        });
        e.end_method();
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/BladeBeanMapKey.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.vci.web.util.beans;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
/**
 * bean map key,提高性能
 *
 * @author L.cm
 */
@EqualsAndHashCode
@AllArgsConstructor
public class BladeBeanMapKey {
    private final Class type;
    private final int require;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/beans/CopyProperty.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.vci.web.util.beans;
import java.lang.annotation.*;
/**
 * copy å­—段 é…ç½®
 *
 * @author L.cm
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CopyProperty {
    /**
     * å±žæ€§åï¼Œç”¨äºŽæŒ‡å®šåˆ«åï¼Œé»˜è®¤ä½¿ç”¨ï¼šfield name
     * @return å±žæ€§å
     */
    String value() default "";
    /**
     * å¿½ç•¥ï¼šé»˜è®¤ä¸º false
     * @return æ˜¯å¦å¿½ç•¥
     */
    boolean ignore() default false;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/BladeConversionService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.vci.web.util.convert;
import com.vci.web.util.convert.EnumToStringConverter;
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;
/**
 * ç±»åž‹ è½¬æ¢ æœåŠ¡ï¼Œæ·»åŠ äº† IEnum è½¬æ¢
 *
 * @author L.cm
 */
public class BladeConversionService extends ApplicationConversionService {
    @Nullable
    private static volatile BladeConversionService SHARED_INSTANCE;
    public BladeConversionService() {
        this(null);
    }
    public BladeConversionService(@Nullable StringValueResolver embeddedValueResolver) {
        super(embeddedValueResolver);
        super.addConverter(new EnumToStringConverter());
        super.addConverter(new StringToEnumConverter());
    }
    /**
     * Return a shared default application {@code ConversionService} instance, lazily
     * building it once needed.
     * <p>
     * Note: This method actually returns an {@link BladeConversionService}
     * instance. However, the {@code ConversionService} signature has been preserved for
     * binary compatibility.
     * @return the shared {@code BladeConversionService} instance (never{@code null})
     */
    public static GenericConversionService getInstance() {
        BladeConversionService sharedInstance = BladeConversionService.SHARED_INSTANCE;
        if (sharedInstance == null) {
            synchronized (BladeConversionService.class) {
                sharedInstance = BladeConversionService.SHARED_INSTANCE;
                if (sharedInstance == null) {
                    sharedInstance = new BladeConversionService();
                    BladeConversionService.SHARED_INSTANCE = sharedInstance;
                }
            }
        }
        return sharedInstance;
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/BladeConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.vci.web.util.convert;
import com.vci.web.util.ClassUtil;
import com.vci.web.util.ConvertUtil;
import com.vci.web.util.ReflectUtil;
import com.vci.web.util.Unchecked;
import com.vci.web.util.function.CheckedFunction;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.core.Converter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
 * ç»„合 spring cglib Converter å’Œ spring ConversionService
 *
 * @author L.cm
 */
@Slf4j
@AllArgsConstructor
public class BladeConverter implements Converter {
    private static final ConcurrentMap<String, TypeDescriptor> TYPE_CACHE = new ConcurrentHashMap<>();
    private final Class<?> sourceClazz;
    private final Class<?> targetClazz;
    /**
     * cglib convert
     *
     * @param value     æºå¯¹è±¡å±žæ€§
     * @param target    ç›®æ ‡å¯¹è±¡å±žæ€§ç±»
     * @param fieldName ç›®æ ‡çš„field名,原为 set æ–¹æ³•名,BladeBeanCopier é‡Œåšäº†æ›´æ”¹
     * @return {Object}
     */
    @Override
    @Nullable
    public Object convert(Object value, Class target, final Object fieldName) {
        if (value == null) {
            return null;
        }
        // ç±»åž‹ä¸€æ ·ï¼Œä¸éœ€è¦è½¬æ¢
        if (ClassUtil.isAssignableValue(target, value)) {
            return value;
        }
        try {
            TypeDescriptor targetDescriptor = BladeConverter.getTypeDescriptor(targetClazz, (String) fieldName);
            // 1. åˆ¤æ–­ sourceClazz ä¸º Map
            if (Map.class.isAssignableFrom(sourceClazz)) {
                return ConvertUtil.convert(value, targetDescriptor);
            } else {
                TypeDescriptor sourceDescriptor = BladeConverter.getTypeDescriptor(sourceClazz, (String) fieldName);
                return ConvertUtil.convert(value, sourceDescriptor, targetDescriptor);
            }
        } catch (Throwable e) {
            log.warn("BladeConverter error", e);
            return null;
        }
    }
    private static TypeDescriptor getTypeDescriptor(final Class<?> clazz, final String fieldName) {
        String srcCacheKey = clazz.getName() + fieldName;
        // å¿½ç•¥æŠ›å‡ºå¼‚常的函数,定义完整泛型,避免编译问题
        CheckedFunction<String, TypeDescriptor> uncheckedFunction = (key) -> {
            // è¿™é‡Œ property ç†è®ºä¸Šä¸ä¼šä¸º null
            Field field = ReflectUtil.getField(clazz, fieldName);
            if (field == null) {
                throw new NoSuchFieldException(fieldName);
            }
            return new TypeDescriptor(field);
        };
        return TYPE_CACHE.computeIfAbsent(srcCacheKey, Unchecked.function(uncheckedFunction));
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/EnumToStringConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.convert;
import com.fasterxml.jackson.annotation.JsonValue;
import com.vci.web.util.ConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.lang.Nullable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
 * æŽ¥æ”¶å‚æ•° åŒ jackson Enum -》 String è½¬æ¢
 *
 * @author L.cm
 */
@Slf4j
public class EnumToStringConverter implements ConditionalGenericConverter {
    /**
     * ç¼“å­˜ Enum ç±»ä¿¡æ¯ï¼Œæä¾›æ€§èƒ½
     */
    private static final ConcurrentMap<Class<?>, AccessibleObject> ENUM_CACHE_MAP = new ConcurrentHashMap<>(8);
    @Nullable
    private static AccessibleObject getAnnotation(Class<?> clazz) {
        Set<AccessibleObject> accessibleObjects = new HashSet<>();
        // JsonValue METHOD, FIELD
        Field[] fields = clazz.getDeclaredFields();
        Collections.addAll(accessibleObjects, fields);
        // methods
        Method[] methods = clazz.getDeclaredMethods();
        Collections.addAll(accessibleObjects, methods);
        for (AccessibleObject accessibleObject : accessibleObjects) {
            // å¤ç”¨ jackson çš„ JsonValue æ³¨è§£
            JsonValue jsonValue = accessibleObject.getAnnotation(JsonValue.class);
            if (jsonValue != null && jsonValue.value()) {
                accessibleObject.setAccessible(true);
                return accessibleObject;
            }
        }
        return null;
    }
    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return true;
    }
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        Set<ConvertiblePair> pairSet = new HashSet<>(3);
        pairSet.add(new ConvertiblePair(Enum.class, String.class));
        pairSet.add(new ConvertiblePair(Enum.class, Integer.class));
        pairSet.add(new ConvertiblePair(Enum.class, Long.class));
        return Collections.unmodifiableSet(pairSet);
    }
    @Override
    public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        if (source == null) {
            return null;
        }
        Class<?> sourceClazz = sourceType.getType();
        AccessibleObject accessibleObject = ENUM_CACHE_MAP.computeIfAbsent(sourceClazz, EnumToStringConverter::getAnnotation);
        Class<?> targetClazz = targetType.getType();
        // å¦‚果为null,走默认的转换
        if (accessibleObject == null) {
            if (String.class == targetClazz) {
                return ((Enum) source).name();
            }
            int ordinal = ((Enum) source).ordinal();
            return ConvertUtil.convert(ordinal, targetClazz);
        }
        try {
            return EnumToStringConverter.invoke(sourceClazz, accessibleObject, source, targetClazz);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
    @Nullable
    private static Object invoke(Class<?> clazz, AccessibleObject accessibleObject, Object source, Class<?> targetClazz)
        throws IllegalAccessException, InvocationTargetException {
        Object value = null;
        if (accessibleObject instanceof Field) {
            Field field = (Field) accessibleObject;
            value = field.get(source);
        } else if (accessibleObject instanceof Method) {
            Method method = (Method) accessibleObject;
            Class<?> paramType = method.getParameterTypes()[0];
            // ç±»åž‹è½¬æ¢
            Object object = ConvertUtil.convert(source, paramType);
            value = method.invoke(clazz, object);
        }
        if (value == null) {
            return null;
        }
        return ConvertUtil.convert(value, targetClazz);
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/convert/StringToEnumConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.convert;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.vci.web.util.ConvertUtil;
import com.vci.web.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.lang.Nullable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
 * æŽ¥æ”¶å‚æ•° åŒ jackson String -》 Enum è½¬æ¢
 *
 * @author L.cm
 */
@Slf4j
public class StringToEnumConverter implements ConditionalGenericConverter {
    /**
     * ç¼“å­˜ Enum ç±»ä¿¡æ¯ï¼Œæä¾›æ€§èƒ½
     */
    private static final ConcurrentMap<Class<?>, AccessibleObject> ENUM_CACHE_MAP = new ConcurrentHashMap<>(8);
    @Nullable
    private static AccessibleObject getAnnotation(Class<?> clazz) {
        Set<AccessibleObject> accessibleObjects = new HashSet<>();
        // JsonCreator METHOD, CONSTRUCTOR
        Constructor<?>[] constructors = clazz.getConstructors();
        Collections.addAll(accessibleObjects, constructors);
        // methods
        Method[] methods = clazz.getDeclaredMethods();
        Collections.addAll(accessibleObjects, methods);
        for (AccessibleObject accessibleObject : accessibleObjects) {
            // å¤ç”¨ jackson çš„ JsonCreator注解
            JsonCreator jsonCreator = accessibleObject.getAnnotation(JsonCreator.class);
            if (jsonCreator != null && JsonCreator.Mode.DISABLED != jsonCreator.mode()) {
                accessibleObject.setAccessible(true);
                return accessibleObject;
            }
        }
        return null;
    }
    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return true;
    }
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return Collections.singleton(new ConvertiblePair(String.class, Enum.class));
    }
    @Nullable
    @Override
    public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        if (StringUtil.isBlank((String) source)) {
            return null;
        }
        Class<?> clazz = targetType.getType();
        AccessibleObject accessibleObject = ENUM_CACHE_MAP.computeIfAbsent(clazz, StringToEnumConverter::getAnnotation);
        String value = ((String) source).trim();
        // å¦‚果为null,走默认的转换
        if (accessibleObject == null) {
            return valueOf(clazz, value);
        }
        try {
            return StringToEnumConverter.invoke(clazz, accessibleObject, value);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
    @SuppressWarnings("unchecked")
    private static <T extends Enum<T>> T valueOf(Class<?> clazz, String value){
        return Enum.valueOf((Class<T>) clazz, value);
    }
    @Nullable
    private static Object invoke(Class<?> clazz, AccessibleObject accessibleObject, String value)
        throws IllegalAccessException, InvocationTargetException, InstantiationException {
        if (accessibleObject instanceof Constructor) {
            Constructor constructor = (Constructor) accessibleObject;
            Class<?> paramType = constructor.getParameterTypes()[0];
            // ç±»åž‹è½¬æ¢
            Object object = ConvertUtil.convert(value, paramType);
            return constructor.newInstance(object);
        }
        if (accessibleObject instanceof Method) {
            Method method = (Method) accessibleObject;
            Class<?> paramType = method.getParameterTypes()[0];
            // ç±»åž‹è½¬æ¢
            Object object = ConvertUtil.convert(value, paramType);
            return method.invoke(clazz, object);
        }
        return null;
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedCallable.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
import org.springframework.lang.Nullable;
/**
 * å—检的 Callable
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedCallable<T> {
    /**
     * Run this callable.
     *
     * @return result
     * @throws Throwable CheckedException
     */
    @Nullable
    T call() throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedComparator.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
/**
 * å—检的 Comparator
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedComparator<T> {
    /**
     * Compares its two arguments for order.
     *
     * @param o1 o1
     * @param o2 o2
     * @return int
     * @throws Throwable CheckedException
     */
    int compare(T o1, T o2) throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedConsumer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
import org.springframework.lang.Nullable;
/**
 * å—检的 Consumer
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedConsumer<T> {
    /**
     * Run the Consumer
     *
     * @param t T
     * @throws Throwable UncheckedException
     */
    @Nullable
    void accept(@Nullable T t) throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedFunction.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
import org.springframework.lang.Nullable;
/**
 * å—检的 function
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedFunction<T, R> {
    /**
     * Run the Function
     *
     * @param t T
     * @return R R
     * @throws Throwable CheckedException
     */
    @Nullable
    R apply(@Nullable T t) throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedRunnable.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
/**
 * å—检的 runnable
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedRunnable {
    /**
     * Run this runnable.
     *
     * @throws Throwable CheckedException
     */
    void run() throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/function/CheckedSupplier.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package com.vci.web.util.function;
import org.springframework.lang.Nullable;
/**
 * å—检的 Supplier
 *
 * @author L.cm
 */
@FunctionalInterface
public interface CheckedSupplier<T> {
    /**
     * Run the Supplier
     *
     * @return T
     * @throws Throwable CheckedException
     */
    @Nullable
    T get() throws Throwable;
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.vci.web.util.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 com.vci.web.util.DateTimeUtil;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
 * java 8 æ—¶é—´é»˜è®¤åºåˆ—化
 *
 * @author L.cm
 */
public class BladeJavaTimeModule extends SimpleModule {
    public static final BladeJavaTimeModule INSTANCE = new BladeJavaTimeModule();
    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));
    }
}
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,705 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.web.util.jackson;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.fasterxml.jackson.databind.type.MapType;
import com.vci.web.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.*;
/**
 * Jackson工具类
 *
 * @author Chill
 */
@Slf4j
public class JsonUtil {
    /**
     * å°†å¯¹è±¡åºåˆ—化成json字符串
     *
     * @param value javaBean
     * @return jsonString json字符串
     */
    public static <T> 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>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(String content, Class<T> 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>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(String content, TypeReference<T> 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>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(byte[] bytes, Class<T> valueType) {
        try {
            return getInstance().readValue(bytes, valueType);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param bytes         bytes
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
        try {
            return getInstance().readValue(bytes, typeReference);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in        InputStream
     * @param valueType class
     * @param <T>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(InputStream in, Class<T> valueType) {
        try {
            return getInstance().readValue(in, valueType);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in            InputStream
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
        try {
            return getInstance().readValue(in, typeReference);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成List对象
     *
     * @param content      content
     * @param valueTypeRef class
     * @param <T>          T æ³›åž‹æ ‡è®°
     * @return List<T>
     */
    public static <T> List<T> parseArray(String content, Class<T> valueTypeRef) {
        try {
            if (!StringUtil.startsWithIgnoreCase(content, StringPool.LEFT_SQ_BRACKET)) {
                content = StringPool.LEFT_SQ_BRACKET + content + StringPool.RIGHT_SQ_BRACKET;
            }
            List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
            });
            List<T> result = new ArrayList<>();
            for (Map<String, Object> map : list) {
                result.add(toPojo(map, valueTypeRef));
            }
            return result;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
    /**
     * å°†json字符串转成 JsonNode
     *
     * @param jsonString jsonString
     * @return jsonString json字符串
     */
    public static JsonNode readTree(String jsonString) {
        Objects.requireNonNull(jsonString, "jsonString is null");
        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) {
        Objects.requireNonNull(in, "InputStream in is null");
        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) {
        Objects.requireNonNull(content, "byte[] content is null");
        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) {
        Objects.requireNonNull(jsonParser, "jsonParser is null");
        try {
            return getInstance().readTree(jsonParser);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json byte æ•°ç»„反序列化成对象
     *
     * @param content   json bytes
     * @param valueType class
     * @param <T>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable byte[] content, Class<T> valueType) {
        if (ObjectUtil.isEmpty(content)) {
            return null;
        }
        try {
            return getInstance().readValue(content, valueType);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param jsonString jsonString
     * @param valueType  class
     * @param <T>        T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable String jsonString, Class<T> valueType) {
        if (StringUtil.isBlank(jsonString)) {
            return null;
        }
        try {
            return getInstance().readValue(jsonString, valueType);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in        InputStream
     * @param valueType class
     * @param <T>       T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable InputStream in, Class<T> valueType) {
        if (in == null) {
            return null;
        }
        try {
            return getInstance().readValue(in, valueType);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param content       bytes
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable byte[] content, TypeReference<T> typeReference) {
        if (ObjectUtil.isEmpty(content)) {
            return null;
        }
        try {
            return getInstance().readValue(content, typeReference);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param jsonString    jsonString
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable String jsonString, TypeReference<T> typeReference) {
        if (StringUtil.isBlank(jsonString)) {
            return null;
        }
        try {
            return getInstance().readValue(jsonString, typeReference);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°†json反序列化成对象
     *
     * @param in            InputStream
     * @param typeReference æ³›åž‹ç±»åž‹
     * @param <T>           T æ³›åž‹æ ‡è®°
     * @return Bean
     */
    @Nullable
    public static <T> T readValue(@Nullable InputStream in, TypeReference<T> typeReference) {
        if (in == null) {
            return null;
        }
        try {
            return getInstance().readValue(in, typeReference);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å°è£… map type
     *
     * @param keyClass   key ç±»åž‹
     * @param valueClass value ç±»åž‹
     * @return MapType
     */
    public static MapType getMapType(Class<?> keyClass, Class<?> valueClass) {
        return getInstance().getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
    }
    /**
     * å°è£… map type
     *
     * @param elementClass é›†åˆå€¼ç±»åž‹
     * @return CollectionLikeType
     */
    public static CollectionLikeType getListType(Class<?> elementClass) {
        return getInstance().getTypeFactory().constructCollectionLikeType(List.class, elementClass);
    }
    /**
     * è¯»å–集合
     *
     * @param content      bytes
     * @param elementClass elementClass
     * @param <T>          æ³›åž‹
     * @return é›†åˆ
     */
    public static <T> List<T> readList(@Nullable byte[] content, Class<T> elementClass) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyList();
        }
        try {
            return getInstance().readValue(content, getListType(elementClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content      InputStream
     * @param elementClass elementClass
     * @param <T>          æ³›åž‹
     * @return é›†åˆ
     */
    public static <T> List<T> readList(@Nullable InputStream content, Class<T> elementClass) {
        if (content == null) {
            return Collections.emptyList();
        }
        try {
            return getInstance().readValue(content, getListType(elementClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content      bytes
     * @param elementClass elementClass
     * @param <T>          æ³›åž‹
     * @return é›†åˆ
     */
    public static <T> List<T> readList(@Nullable String content, Class<T> elementClass) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyList();
        }
        try {
            return getInstance().readValue(content, getListType(elementClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content    bytes
     * @param keyClass   key类型
     * @param valueClass å€¼ç±»åž‹
     * @param <K>        æ³›åž‹
     * @param <V>        æ³›åž‹
     * @return é›†åˆ
     */
    public static <K, V> Map<K, V> readMap(@Nullable byte[] content, Class<?> keyClass, Class<?> valueClass) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyMap();
        }
        try {
            return getInstance().readValue(content, getMapType(keyClass, valueClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content    InputStream
     * @param keyClass   key类型
     * @param valueClass å€¼ç±»åž‹
     * @param <K>        æ³›åž‹
     * @param <V>        æ³›åž‹
     * @return é›†åˆ
     */
    public static <K, V> Map<K, V> readMap(@Nullable InputStream content, Class<?> keyClass, Class<?> valueClass) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyMap();
        }
        try {
            return getInstance().readValue(content, getMapType(keyClass, valueClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content    bytes
     * @param keyClass   key类型
     * @param valueClass å€¼ç±»åž‹
     * @param <K>        æ³›åž‹
     * @param <V>        æ³›åž‹
     * @return é›†åˆ
     */
    public static <K, V> Map<K, V> readMap(@Nullable String content, Class<?> keyClass, Class<?> valueClass) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyMap();
        }
        try {
            return getInstance().readValue(content, getMapType(keyClass, valueClass));
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * è¯»å–集合
     *
     * @param content bytes
     * @return é›†åˆ
     */
    public static Map<String, Object> readMap(@Nullable String content) {
        return readMap(content, String.class, Object.class);
    }
    /**
     * è¯»å–集合
     *
     * @param content bytes
     * @return é›†åˆ
     */
    public static List<Map<String, Object>> readListMap(@Nullable String content) {
        if (ObjectUtil.isEmpty(content)) {
            return Collections.emptyList();
        }
        try {
            return getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
            });
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * jackson çš„类型转换
     *
     * @param fromValue   æ¥æºå¯¹è±¡
     * @param toValueType è½¬æ¢çš„类型
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return è½¬æ¢ç»“æžœ
     */
    public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
        return getInstance().convertValue(fromValue, toValueType);
    }
    /**
     * jackson çš„类型转换
     *
     * @param fromValue   æ¥æºå¯¹è±¡
     * @param toValueType è½¬æ¢çš„类型
     * @param <T>         æ³›åž‹æ ‡è®°
     * @return è½¬æ¢ç»“æžœ
     */
    public static <T> T convertValue(Object fromValue, JavaType toValueType) {
        return getInstance().convertValue(fromValue, toValueType);
    }
    /**
     * jackson çš„类型转换
     *
     * @param fromValue      æ¥æºå¯¹è±¡
     * @param toValueTypeRef æ³›åž‹ç±»åž‹
     * @param <T>            æ³›åž‹æ ‡è®°
     * @return è½¬æ¢ç»“æžœ
     */
    public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
        return getInstance().convertValue(fromValue, toValueTypeRef);
    }
    /**
     * tree è½¬å¯¹è±¡
     *
     * @param treeNode  TreeNode
     * @param valueType valueType
     * @param <T>       æ³›åž‹æ ‡è®°
     * @return è½¬æ¢ç»“æžœ
     */
    public static <T> T treeToValue(TreeNode treeNode, Class<T> valueType) {
        try {
            return getInstance().treeToValue(treeNode, valueType);
        } catch (JsonProcessingException e) {
            throw Exceptions.unchecked(e);
        }
    }
    /**
     * å¯¹è±¡è½¬ä¸º json node
     *
     * @param value å¯¹è±¡
     * @return JsonNode
     */
    public static JsonNode valueToTree(@Nullable Object value) {
        return getInstance().valueToTree(value);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦å¯ä»¥åºåˆ—化
     *
     * @param value å¯¹è±¡
     * @return æ˜¯å¦å¯ä»¥åºåˆ—化
     */
    public static boolean canSerialize(@Nullable Object value) {
        if (value == null) {
            return true;
        }
        return getInstance().canSerialize(value.getClass());
    }
    public static Map<String, Object> toMap(String content) {
        try {
            return getInstance().readValue(content, Map.class);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
    public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
        try {
            Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
            });
            Map<String, T> result = new HashMap<>(16);
            for (Map.Entry<String, Map<String, Object>> 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> T toPojo(Map fromValue, Class<T> toValueType) {
        return getInstance().convertValue(fromValue, toValueType);
    }
    public static ObjectMapper getInstance() {
        return JacksonHolder.INSTANCE;
    }
    private static class JacksonHolder {
        private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
    }
    private static class JacksonObjectMapper extends ObjectMapper {
        private static final long serialVersionUID = 4288193147502386170L;
        private static final Locale CHINA = Locale.CHINA;
        public JacksonObjectMapper(ObjectMapper src) {
            super(src);
        }
        public JacksonObjectMapper() {
            super();
            //设置地点为中国
            super.setLocale(CHINA);
            //去掉默认的时间戳格式
            super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            //设置为中国上海时区
            super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
            //序列化时,日期的统一格式
            super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
            // å•引号
            super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
            // å…è®¸JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)
            super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
            super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
            super.findAndRegisterModules();
            //失败处理
            super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            //单引号处理
            super.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
            //反序列化时,属性不存在的兼容处理s
            super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            //日期格式化
            super.registerModule(new BladeJavaTimeModule());
            super.findAndRegisterModules();
        }
        @Override
        public ObjectMapper copy() {
            return new JacksonObjectMapper(this);
        }
    }
}