This commit is contained in:
Looly
2022-09-15 02:19:44 +08:00
parent 23c8d40ad0
commit a081bdc5e1
13 changed files with 170 additions and 47 deletions

View File

@@ -149,6 +149,19 @@ public class IdcardUtil {
return idCard18.toString(); return idCard18.toString();
} }
/**
* 将18位身份证号码转换为15位
*
* @param idCard 18位身份编码
* @return 15位身份编码
*/
public static String convert18To15(String idCard) {
if (StrUtil.isNotBlank(idCard) && IdcardUtil.isValidCard18(idCard)) {
return idCard.substring(0, 6) + idCard.substring(8, idCard.length() - 1);
}
return idCard;
}
/** /**
* 是否有效身份证号忽略X的大小写<br> * 是否有效身份证号忽略X的大小写<br>
* 如果身份证号码中含有空格始终返回{@code false} * 如果身份证号码中含有空格始终返回{@code false}

View File

@@ -46,6 +46,12 @@ public class IdcardUtilTest {
Assert.assertEquals("33010219200403064X", convert15To18Second); Assert.assertEquals("33010219200403064X", convert15To18Second);
} }
@Test
public void convert18To15Test() {
String idcard15 = IdcardUtil.convert18To15("150102198807303035");
Assert.assertEquals(ID_15, idcard15);
}
@Test @Test
public void getAgeTest() { public void getAgeTest() {
final DateTime date = DateUtil.parse("2017-04-10"); final DateTime date = DateUtil.parse("2017-04-10");

View File

@@ -229,6 +229,7 @@ public class Ftp extends AbstractFtp {
} }
this.client = client; this.client = client;
if (mode != null) { if (mode != null) {
//noinspection resource
setMode(mode); setMode(mode);
} }
return this; return this;
@@ -375,7 +376,7 @@ public class Ftp extends AbstractFtp {
String pwd = null; String pwd = null;
if (StrUtil.isNotBlank(path)) { if (StrUtil.isNotBlank(path)) {
pwd = pwd(); pwd = pwd();
if (false == isDir(path)) { if (false == cd(path)) {
throw new FtpException("Change dir to [{}] error, maybe path not exist!", path); throw new FtpException("Change dir to [{}] error, maybe path not exist!", path);
} }
} }
@@ -439,7 +440,7 @@ public class Ftp extends AbstractFtp {
final String pwd = pwd(); final String pwd = pwd();
final String fileName = FileUtil.getName(path); final String fileName = FileUtil.getName(path);
final String dir = StrUtil.removeSuffix(path, fileName); final String dir = StrUtil.removeSuffix(path, fileName);
if (false == isDir(dir)) { if (false == cd(dir)) {
throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path); throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path);
} }
@@ -557,7 +558,7 @@ public class Ftp extends AbstractFtp {
if (StrUtil.isNotBlank(destPath)) { if (StrUtil.isNotBlank(destPath)) {
mkDirs(destPath); mkDirs(destPath);
if (false == isDir(destPath)) { if (false == cd(destPath)) {
throw new FtpException("Change dir to [{}] error, maybe dir not exist!", destPath); throw new FtpException("Change dir to [{}] error, maybe dir not exist!", destPath);
} }
} }
@@ -665,7 +666,7 @@ public class Ftp extends AbstractFtp {
pwd = pwd(); pwd = pwd();
} }
if (false == isDir(path)) { if (false == cd(path)) {
throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path); throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path);
} }

View File

@@ -23,4 +23,11 @@ public interface TemplateEngine {
*/ */
Template getTemplate(String resource); Template getTemplate(String resource);
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return 对应模板实现的引擎对象
* @since 6.0.0
*/
Object getRawEngine();
} }

View File

@@ -72,6 +72,17 @@ public class BeetlEngine implements TemplateEngine {
return BeetlTemplate.wrap(engine.getTemplate(resource)); return BeetlTemplate.wrap(engine.getTemplate(resource));
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link GroupTemplate}
* @since 5.8.7
*/
@Override
public GroupTemplate getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *

View File

@@ -77,6 +77,17 @@ public class EnjoyEngine implements TemplateEngine {
return EnjoyTemplate.wrap(this.engine.getTemplate(resource)); return EnjoyTemplate.wrap(this.engine.getTemplate(resource));
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link com.jfinal.template.Engine}
* @since 5.8.7
*/
@Override
public com.jfinal.template.Engine getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *

View File

@@ -15,7 +15,7 @@ import java.io.IOException;
/** /**
* FreeMarker模板引擎封装<br> * FreeMarker模板引擎封装<br>
* 见https://freemarker.apache.org/ * 见:<a href="https://freemarker.apache.org/">https://freemarker.apache.org/</a>
* *
* @author looly * @author looly
*/ */
@@ -82,6 +82,17 @@ public class FreemarkerEngine implements TemplateEngine {
} }
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link Configuration}
* @since 5.8.7
*/
@Override
public Configuration getRawEngine() {
return this.cfg;
}
/** /**
* 创建配置项 * 创建配置项
* *

View File

@@ -66,6 +66,17 @@ public class JetbrickEngine implements TemplateEngine {
return JetbrickTemplate.wrap(engine.getTemplate(resource)); return JetbrickTemplate.wrap(engine.getTemplate(resource));
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link JetEngine}
* @since 5.8.7
*/
@Override
public JetEngine getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *

View File

@@ -1,11 +1,11 @@
package cn.hutool.extra.template.engine.rythm; package cn.hutool.extra.template.engine.rythm;
import java.util.Properties;
import cn.hutool.extra.template.Template; import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine; import cn.hutool.extra.template.TemplateEngine;
import java.util.Properties;
/** /**
* Rythm模板引擎<br> * Rythm模板引擎<br>
* 文档http://rythmengine.org/doc/index * 文档http://rythmengine.org/doc/index
@@ -67,6 +67,17 @@ public class RythmEngine implements TemplateEngine {
return RythmTemplate.wrap(this.engine.getTemplate(resource)); return RythmTemplate.wrap(this.engine.getTemplate(resource));
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link org.rythmengine.RythmEngine}
* @since 5.8.7
*/
@Override
public org.rythmengine.RythmEngine getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *

View File

@@ -25,10 +25,12 @@ public class ThymeleafEngine implements TemplateEngine {
TemplateConfig config; TemplateConfig config;
// --------------------------------------------------------------------------------- Constructor start // --------------------------------------------------------------------------------- Constructor start
/** /**
* 默认构造 * 默认构造
*/ */
public ThymeleafEngine() {} public ThymeleafEngine() {
}
/** /**
* 构造 * 构造
@@ -51,7 +53,7 @@ public class ThymeleafEngine implements TemplateEngine {
@Override @Override
public TemplateEngine init(TemplateConfig config) { public TemplateEngine init(TemplateConfig config) {
if(null == config){ if (null == config) {
config = TemplateConfig.DEFAULT; config = TemplateConfig.DEFAULT;
} }
this.config = config; this.config = config;
@@ -61,20 +63,32 @@ public class ThymeleafEngine implements TemplateEngine {
/** /**
* 初始化引擎 * 初始化引擎
*
* @param engine 引擎 * @param engine 引擎
*/ */
private void init(final org.thymeleaf.TemplateEngine engine){ private void init(final org.thymeleaf.TemplateEngine engine) {
this.engine = engine; this.engine = engine;
} }
@Override @Override
public Template getTemplate(final String resource) { public Template getTemplate(final String resource) {
if(null == this.engine){ if (null == this.engine) {
init(TemplateConfig.DEFAULT); init(TemplateConfig.DEFAULT);
} }
return ThymeleafTemplate.wrap(this.engine, resource, (null == this.config) ? null : this.config.getCharset()); return ThymeleafTemplate.wrap(this.engine, resource, (null == this.config) ? null : this.config.getCharset());
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link org.thymeleaf.TemplateEngine}
* @since 5.8.7
*/
@Override
public org.thymeleaf.TemplateEngine getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *
@@ -88,33 +102,33 @@ public class ThymeleafEngine implements TemplateEngine {
final ITemplateResolver resolver; final ITemplateResolver resolver;
switch (config.getResourceMode()) { switch (config.getResourceMode()) {
case CLASSPATH: case CLASSPATH:
final ClassLoaderTemplateResolver classLoaderResolver = new ClassLoaderTemplateResolver(); final ClassLoaderTemplateResolver classLoaderResolver = new ClassLoaderTemplateResolver();
classLoaderResolver.setCharacterEncoding(config.getCharsetStr()); classLoaderResolver.setCharacterEncoding(config.getCharsetStr());
classLoaderResolver.setTemplateMode(TemplateMode.HTML); classLoaderResolver.setTemplateMode(TemplateMode.HTML);
classLoaderResolver.setPrefix(StrUtil.addSuffixIfNot(config.getPath(), "/")); classLoaderResolver.setPrefix(StrUtil.addSuffixIfNot(config.getPath(), "/"));
resolver = classLoaderResolver; resolver = classLoaderResolver;
break; break;
case FILE: case FILE:
final FileTemplateResolver fileResolver = new FileTemplateResolver(); final FileTemplateResolver fileResolver = new FileTemplateResolver();
fileResolver.setCharacterEncoding(config.getCharsetStr()); fileResolver.setCharacterEncoding(config.getCharsetStr());
fileResolver.setTemplateMode(TemplateMode.HTML); fileResolver.setTemplateMode(TemplateMode.HTML);
fileResolver.setPrefix(StrUtil.addSuffixIfNot(config.getPath(), "/")); fileResolver.setPrefix(StrUtil.addSuffixIfNot(config.getPath(), "/"));
resolver = fileResolver; resolver = fileResolver;
break; break;
case WEB_ROOT: case WEB_ROOT:
final FileTemplateResolver webRootResolver = new FileTemplateResolver(); final FileTemplateResolver webRootResolver = new FileTemplateResolver();
webRootResolver.setCharacterEncoding(config.getCharsetStr()); webRootResolver.setCharacterEncoding(config.getCharsetStr());
webRootResolver.setTemplateMode(TemplateMode.HTML); webRootResolver.setTemplateMode(TemplateMode.HTML);
webRootResolver.setPrefix(StrUtil.addSuffixIfNot(FileUtil.getAbsolutePath(FileUtil.file(FileUtil.getWebRoot(), config.getPath())), "/")); webRootResolver.setPrefix(StrUtil.addSuffixIfNot(FileUtil.getAbsolutePath(FileUtil.file(FileUtil.getWebRoot(), config.getPath())), "/"));
resolver = webRootResolver; resolver = webRootResolver;
break; break;
case STRING: case STRING:
resolver = new StringTemplateResolver(); resolver = new StringTemplateResolver();
break; break;
default: default:
resolver = new DefaultTemplateResolver(); resolver = new DefaultTemplateResolver();
break; break;
} }
final org.thymeleaf.TemplateEngine engine = new org.thymeleaf.TemplateEngine(); final org.thymeleaf.TemplateEngine engine = new org.thymeleaf.TemplateEngine();

View File

@@ -70,6 +70,7 @@ public class VelocityEngine implements TemplateEngine {
* @return 原始引擎对象 * @return 原始引擎对象
* @since 5.5.8 * @since 5.5.8
*/ */
@Override
public org.apache.velocity.app.VelocityEngine getRawEngine() { public org.apache.velocity.app.VelocityEngine getRawEngine() {
return this.engine; return this.engine;
} }

View File

@@ -73,6 +73,17 @@ public class WitEngine implements TemplateEngine {
} }
} }
/**
* 获取原始引擎的钩子方法,用于自定义特殊属性,如插件等
*
* @return {@link Engine}
* @since 5.8.7
*/
@Override
public Engine getRawEngine() {
return this.engine;
}
/** /**
* 创建引擎 * 创建引擎
* *

View File

@@ -1,5 +1,15 @@
package cn.hutool.extra.template; package cn.hutool.extra.template;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.Dict;
import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.thymeleaf.context.Context;
import org.thymeleaf.standard.StandardDialect;
import org.thymeleaf.templateresolver.StringTemplateResolver;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -8,15 +18,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.StringTemplateResolver;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.Dict;
import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
/** /**
* Thymeleaf单元测试 * Thymeleaf单元测试
* *
@@ -25,6 +26,20 @@ import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
*/ */
public class ThymeleafTest { public class ThymeleafTest {
/**
* <a href="https://github.com/dromara/hutool/issues/2530">...</a>
* 自定义操作原始引擎
*/
@Test
@Ignore
public void addDialectTest(){
final TemplateEngine engine = TemplateUtil.createEngine();
if(engine instanceof ThymeleafEngine){
final org.thymeleaf.TemplateEngine rawEngine = ((ThymeleafEngine) engine).getRawEngine();
rawEngine.addDialect(new StandardDialect());
}
}
@Test @Test
public void thymeleafEngineTest() { public void thymeleafEngineTest() {
final Map<String, Object> map1 = new HashMap<>(); final Map<String, Object> map1 = new HashMap<>();