diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..69b29004874a5f9e67c270b1ed6bf3e2011f0f27 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,61 @@ +# Java Maven CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-java/ for more details +# +version: 2 +jobs: + build-job: + docker: + # specify the version you desire here + - image: circleci/openjdk:8-jdk + + working_directory: ~/repo + + environment: + # Customize the JVM maximum heap limit + MAVEN_OPTS: -Xmx3200m + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v1-dependencies-{{ checksum "pom.xml" }} + # fallback to using the latest cache if no exact match is found + - v1-dependencies- + + - run: mvn dependency:go-offline + + - save_cache: + paths: + - ~/.m2 + key: v1-dependencies-{{ checksum "pom.xml" }} + + # run tests! + - run: mvn -Dmaven.test.skip=true compile + deploy-job: + docker: + # specify the version you desire here + - image: circleci/openjdk:8-jdk + + working_directory: ~/repo + + environment: + # Customize the JVM maximum heap limit + MAVEN_OPTS: -Xmx1024m + + steps: + # trigger deploy + - run: curl "http://180.76.176.118:8601/deploy/trigger?name=$CIRCLE_PROJECT_REPONAME&token=$DEPLOY_TOKEN" +workflows: + version: 2 + build-deploy: + jobs: + - build-job + - deploy-job: + requires: + - build-job + filters: + branches: + only: master \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index e15bf2ec7e60ce1b2afa5ae4bccb66af112cb8da..a6d52d460772b2f54ad51c69df0c2a8583ea5132 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false language: java -script: mvn -Dmaven.test.skip=true clean source:jar deploy --settings mvn_settings.xml --fail-at-end +script: mvn -Dmaven.test.skip=true clean package jdk: - oraclejdk8 # whitelist diff --git a/README.md b/README.md index 9cf7fb158ae4a815e81e164f8f43dc71df795439..d409eddacc612dd3bd5da03d3027e7bc0204c7ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Nutz的插件与集成库 [![Build Status](https://travis-ci.org/nutzam/nutzmore.png?branch=master)](https://travis-ci.org/nutzam/nutzmore) +[![Circle CI](https://circleci.com/gh/nutzam/nutzmore/tree/master.svg?style=svg)](https://circleci.com/gh/nutzam/nutzmore/tree/master) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutzmore/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutzmore/) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) @@ -12,7 +13,7 @@ org.nutz 填nutz插件名 - 1.r.63 + 1.r.65 ``` @@ -74,10 +75,12 @@ https://jfrog.nutz.cn/artifactory/snapshots/org/nutz/ | [plugins-cache](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-cache) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-cache/badge.svg) | Shiro的CacheManager实现 | **生产** | wendal | | [plugins-daocache](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-daocache) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-daocache/badge.svg) | 为NutDao提供缓存支持,SQL级别的缓存 | **生产** | wendal | | [plugins-daomapping](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-daomapping) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-daomapping/badge.svg) | Dao接口无缝生成 | 试用 | wendal | -| [plugins-event](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-event) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-event/badge.svg) | 事件驱动和异步化插件,方便各模块间解耦 | 试用 | qinerg | +| [plugins-dict](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-dict) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-dict/badge.svg) | 针对java常量的全局字典生成 | 试用 | [邓华锋](http://dhf.ink) | +|[plugins-event](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-event) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-event/badge.svg) | 事件驱动和异步化插件,方便各模块间解耦 | 试用 | qinerg | | [plugins-hotplug](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-hotplug) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-hotplug/badge.svg) | 定义一套基础架构,实现可插拔系统 | **生产** | wendal | -| [plugins-iocloader](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-iocloader) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-iocloader/badge.svg) | 演示自定义IocLoader的用法 | 废弃 | wendal | -| [plugins-jsonrpc](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-jsonrpc) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-jsonrpc/badge.svg) | 完整实现jsonrpc, 用Mapper方式 | 废弃 | wendal | +| [plugins-iocloader](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-iocloader) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-iocloader/badge.svg) | 自定义IocLoader,及任务线程环境下使用ioc方式| 试用 | wendal、[邓华锋](http://dhf.ink) | +| [plugins-jqgrid](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-jqgrid) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-jqgrid/badge.svg) | 封装[jqGrid](http://http://blog.mn886.net/jqGrid/) dao层操作通用使用方法 | **生产** | [邓华锋](http://dhf.ink) | +|[plugins-jsonrpc](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-jsonrpc) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-jsonrpc/badge.svg) | 完整实现jsonrpc, 用Mapper方式 | 废弃 | wendal | | [plugins-mock](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-mock) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-mock/badge.svg) | 提供单元测试所需要的一切东西 | 试用 | wendal | | [plugins-multiview](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-multiview) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-multiview/badge.svg) | 集合N种模板引擎,可配置性强 | **生产** | [邓华锋](http://dhf.ink) | | [plugins-mongodb](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-mongodb) | ![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.nutz/nutz-plugins-mongodb/badge.svg) | Mongodb 薄封装 | **生产** | wendal | diff --git a/nutz-integration-activiti/demo/pom.xml b/nutz-integration-activiti/demo/pom.xml index 16c9e708c338815c2ad7b379a19ccf6b283c8fe7..84463754bdad5586111007cc28457a6149e20447 100644 --- a/nutz-integration-activiti/demo/pom.xml +++ b/nutz-integration-activiti/demo/pom.xml @@ -4,7 +4,7 @@ net.wendal nutz-activiti-demo war - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutzdemo Maven Webapp http://maven.apache.org @@ -58,7 +58,7 @@ org.nutz nutz-integration-activiti - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT javax.servlet diff --git a/nutz-integration-activiti/pom.xml b/nutz-integration-activiti/pom.xml index 3e5aee0eac088ee77075d45c14423f7f16fd81cc..fc82b06626e04c1e3c73aca10cbfda424f6c2f28 100644 --- a/nutz-integration-activiti/pom.xml +++ b/nutz-integration-activiti/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-activiti https://nutzam.com diff --git a/nutz-integration-autoloadcache/pom.xml b/nutz-integration-autoloadcache/pom.xml index 5a939d938884fbd3b0a7245b378389fb277c218d..70bd0db45d88ffa0483228a899dad240b3a1614f 100755 --- a/nutz-integration-autoloadcache/pom.xml +++ b/nutz-integration-autoloadcache/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-autoloadcache diff --git a/nutz-integration-bex5/pom.xml b/nutz-integration-bex5/pom.xml index 0d91e50630fce2c647b5d592e2883ad2338dcac5..70f9b7c8ee49181a73b581024fc94ff2ecc4db69 100644 --- a/nutz-integration-bex5/pom.xml +++ b/nutz-integration-bex5/pom.xml @@ -5,7 +5,7 @@ nutzmore org.nutz - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT 4.0.0 diff --git a/nutz-integration-cxf/pom.xml b/nutz-integration-cxf/pom.xml index 586c8849a87a9887a7902cd13e65ca402274089b..176cd8cacd548053dd2f3e4a0caabfa8e88b21d1 100644 --- a/nutz-integration-cxf/pom.xml +++ b/nutz-integration-cxf/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-cxf diff --git a/nutz-integration-cxf/src/main/java/org/nutz/integration/cxf/AbstractCxfModule.java b/nutz-integration-cxf/src/main/java/org/nutz/integration/cxf/AbstractCxfModule.java index 42205e6e019885e60109a2480bfcf8a0c94b7a51..e58f69b63932260bfa51da5d48aecfb420360345 100644 --- a/nutz-integration-cxf/src/main/java/org/nutz/integration/cxf/AbstractCxfModule.java +++ b/nutz-integration-cxf/src/main/java/org/nutz/integration/cxf/AbstractCxfModule.java @@ -10,6 +10,7 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; +import javax.xml.ws.Endpoint; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; @@ -45,12 +46,13 @@ public abstract class AbstractCxfModule extends CXFNonSpringServlet { @At("/*") public void service() throws Exception { - HttpServletRequest req = Mvcs.getReq(); + final HttpServletRequest req = Mvcs.getReq(); HttpServletResponse resp = Mvcs.getResp(); // 下面代码, 源于doFilter方法. // 因为原方法中的loader和controller均为private属性,无法直接获取,所以需要中转一下 ClassLoaderHolder origLoader = null; Bus origBus = null; + final int trimLen = req.getContextPath().length() + pathROOT.length(); try { if (_loader != null) { origLoader = ClassLoaderUtils.setThreadContextClassloader(_loader); @@ -61,7 +63,11 @@ public abstract class AbstractCxfModule extends CXFNonSpringServlet { if (_controller.filter(new HttpServletRequestWrapper(req) { @Override public String getServletPath() { - return "/cxf/"; + return pathROOT; + } + @Override + public String getPathInfo() { + return req.getRequestURI().substring(trimLen); } }, resp)) { return; @@ -134,9 +140,13 @@ public abstract class AbstractCxfModule extends CXFNonSpringServlet { continue; } log.debugf("add WebService addr=/%s type=%s", ws.serviceName(), klass.getName()); + //Endpoint.publish("/" + ws.serviceName(), ioc.get(klass)); JaxWsServerFactoryBean sfb = new JaxWsServerFactoryBean(); sfb.setServiceBean(ioc.get(klass)); + sfb.setBus(b); + sfb.setAddress("/" + ws.serviceName()); sfb.create(); + //System.out.println(sfb.getAddress()); } } diff --git a/nutz-integration-dubbo/pom.xml b/nutz-integration-dubbo/pom.xml index 8513ce006dc0d10aeb4ad955f4b09deabebca3b2..ce96c760fd07e8f6cf931b5f276a838b6f3b3449 100644 --- a/nutz-integration-dubbo/pom.xml +++ b/nutz-integration-dubbo/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-dubbo diff --git a/nutz-integration-dwr/pom.xml b/nutz-integration-dwr/pom.xml index e738f4c7f61ea71007af47a4396c386e62947931..2c4bb8a63e7681df8b19e5ca9916eb63f8939bd1 100644 --- a/nutz-integration-dwr/pom.xml +++ b/nutz-integration-dwr/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-dwr https://nutzam.com diff --git a/nutz-integration-grpc/pom.xml b/nutz-integration-grpc/pom.xml index 02cd5f7fb8bce3de0827a5db4d8e0d535ae1ec80..04528383031aeb20767f98c01d2219fe6199a744 100644 --- a/nutz-integration-grpc/pom.xml +++ b/nutz-integration-grpc/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-grpc diff --git a/nutz-integration-hasor/demo/pom.xml b/nutz-integration-hasor/demo/pom.xml index a5b880e7da9ac8ab7b13125912f18dcae5c91e97..8cc562667931d7b498b60c93a44202719e4d280d 100644 --- a/nutz-integration-hasor/demo/pom.xml +++ b/nutz-integration-hasor/demo/pom.xml @@ -63,7 +63,7 @@ org.nutz nutz-integration-hasor - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT diff --git a/nutz-integration-hasor/pom.xml b/nutz-integration-hasor/pom.xml index 3db93132c8acec968b75c3ad1d843172472f64b5..c6dd5439b5e4fb8c273ee0fa21435b0c29734e2a 100644 --- a/nutz-integration-hasor/pom.xml +++ b/nutz-integration-hasor/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-hasor nutz-integration-hasor diff --git a/nutz-integration-hessian/pom.xml b/nutz-integration-hessian/pom.xml index 3c923f650bd44b1de1b589551b91d47c54e58bc4..79bd801c6a986b04715e9e342137f285336bbcd5 100644 --- a/nutz-integration-hessian/pom.xml +++ b/nutz-integration-hessian/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-hessian https://nutzam.com diff --git a/nutz-integration-jcache/pom.xml b/nutz-integration-jcache/pom.xml index cba1f3b2ece1f75398ef1a2e5506405708f256a0..41c8b0d85671777d252e6356c24c0610ab94331e 100644 --- a/nutz-integration-jcache/pom.xml +++ b/nutz-integration-jcache/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jcache https://nutzam.com diff --git a/nutz-integration-jedis/pom.xml b/nutz-integration-jedis/pom.xml index 7a2b8e58fb18eaa551d2c253cde7db2e9bf069e5..9339cee82a6764cf7f3151cbe74a60ec7faa2469 100644 --- a/nutz-integration-jedis/pom.xml +++ b/nutz-integration-jedis/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jedis diff --git a/nutz-integration-jedisque/pom.xml b/nutz-integration-jedisque/pom.xml index 71b8aabf84c3f590a84acbe5f98d15133fca95f4..944d152f809d31ae556a8118e1f952ece4c57dff 100644 --- a/nutz-integration-jedisque/pom.xml +++ b/nutz-integration-jedisque/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jedisque diff --git a/nutz-integration-jsch/pom.xml b/nutz-integration-jsch/pom.xml index 3f9849721467264a9eb98b2b9d1c044b89339a75..addef24fcd8d1246ab40d7809964b7ccfc1f9e0d 100644 --- a/nutz-integration-jsch/pom.xml +++ b/nutz-integration-jsch/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jsch https://nutzam.com diff --git a/nutz-integration-jsf/pom.xml b/nutz-integration-jsf/pom.xml index 0743ecb84d6b7256846249d38a80961b6c8d4db2..835d1d3599366071b08b3ef16818af20bab5c3cc 100644 --- a/nutz-integration-jsf/pom.xml +++ b/nutz-integration-jsf/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jsf https://nutzam.com diff --git a/nutz-integration-json4excel/README.md b/nutz-integration-json4excel/README.md index 699f3048ff22e6ebb089a1312c0396c51cb03db2..2dbd7017344770f6f48cbb7d23266cae5b89666e 100644 --- a/nutz-integration-json4excel/README.md +++ b/nutz-integration-json4excel/README.md @@ -12,6 +12,12 @@ json4excel(简称j4e) POI封装了对Excel的基本读写操作,j4e是其基础上按照Nutz使用习惯封装了一套常见操作接口,目标就是简化这个操作过程,让我们可以更加专心书写业务代码。 +# 重要提示 + +当前J4E是基于POI3.1.x版本开发的,可以运行在JDK6以上程序中。 +POI马上要发布4.0.0版本,仅支持JDK8以上,所以准备当前3.1.x的仅仅维护不再添加新功能 + +J4E重写的第二个大版本计划于2018年春季放出,基于POI4.0 # 使用手册 diff --git a/nutz-integration-json4excel/pom.xml b/nutz-integration-json4excel/pom.xml index 2398335d2e42f06c6517a2b221c563e83449ef0d..d1688238ab3540c904f324cce4ad9dbe76932a89 100644 --- a/nutz-integration-json4excel/pom.xml +++ b/nutz-integration-json4excel/pom.xml @@ -6,7 +6,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-json4excel nutz-integration-json4excel @@ -37,7 +37,7 @@ UTF-8 - 3.15 + 3.17 diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4E.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4E.java index 78313159e5f6e3fd5f6da67c6f6c67cf3ef883f2..45c649589d4633a807e7928c3e181ce9f6f70d7f 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4E.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4E.java @@ -73,7 +73,7 @@ public class J4E { : new HSSFWorkbook(); OutputStream out = null; try { - out = new FileOutputStream(excel); + out = new FileOutputStream(excel); return toExcel(wb, out, dataList, j4eConf); } catch (FileNotFoundException e) { @@ -81,8 +81,8 @@ public class J4E { return false; } finally { - Streams.safeClose(wb); - Streams.safeClose(out); + Streams.safeClose(wb); + Streams.safeClose(out); } } @@ -132,13 +132,14 @@ public class J4E { } } } - int rnum = j4eConf.getPassRow(); + int passRow = j4eConf.getPassRow(); + int passColumn = j4eConf.getPassColumn(); int cindex = 0; if (j4eConf.isPassHead()) { - rnum++; + passRow++; } else { // 写入head - Row rhead = sheet.createRow(rnum++); + Row rhead = sheet.createRow(passRow++); for (J4EColumn jcol : j4eConf.getColumns()) { if (jcol.isIgnore()) { continue; @@ -157,12 +158,12 @@ public class J4E { if (log.isDebugEnabled()) { log.debugf("add Row : %s", Json.toJson(dval, JsonFormat.compact())); } - int crow = rnum++; + int crow = passRow++; Row row = sheet.getRow(crow); if (row == null) { row = sheet.createRow(crow); } - cindex = 0; + cindex = passColumn; for (J4EColumn jcol : j4eConf.getColumns()) { if (jcol.isIgnore()) { continue; @@ -175,35 +176,42 @@ public class J4E { c = row.createCell(ccin); } J4EColumnType columnType = jcol.getColumnType(); - if (columnType == J4EColumnType.STRING) { - c.setCellType(CellType.STRING); - } else if (columnType == J4EColumnType.NUMERIC) { + Object dfv = mc.getValue(dval, jfield); + // 数字 + if (columnType == J4EColumnType.NUMERIC) { c.setCellType(CellType.NUMERIC); - } else if (columnType == J4EColumnType.DATE) { - c.setCellType(CellType.STRING); - } else { - // TODO 根据field获取对应的类型 - c.setCellType(CellType.STRING); + int precision = jcol.getPrecision(); + if (precision == 0) { + Integer intRe = Castors.me().castTo(dfv, Integer.class); + if (intRe != null) { + c.setCellValue(intRe); + } + } else { + Double dbRe = Castors.me().castTo(dfv, Double.class); + if (dbRe != null) { + c.setCellValue(dbRe); + } + } } - Object dfv = mc.getValue(dval, jfield); - int ctp = c.getCellType(); - switch (ctp) { - case 1: // STRING - c.setCellValue(dfv != null ? Castors.me().castTo(dfv, String.class) : ""); - break; - case 0: // NUMERIC - Integer intRe = Castors.me().castTo(dfv, Integer.class); - if (intRe != null) { - c.setCellValue(intRe); + // 字符串 + else { + c.setCellType(CellType.STRING); + if (jcol.getToExcelFun() != null) { + J4ECellToExcel cellFun = jcol.getToExcelFun(); + Object setVal = cellFun.toExecl(dfv); + c.setCellValue(Castors.me().castTo(setVal, String.class)); + } else { + c.setCellValue(dfv != null ? Castors.me().castTo(dfv, String.class) + : ""); } - break; - default: - break; } - } } } + + if (out == null) { + return true; + } return saveExcel(out, wb); } @@ -255,39 +263,53 @@ public class J4E { List dataList = j4eConf.isNoReturn() ? null : new ArrayList(); Iterator rlist = sheet.rowIterator(); int passRow = j4eConf.getPassRow(); - int passColumn = j4eConf.getPassColumn(); int passContentRow = j4eConf.getPassContentRow(); + boolean passHead = j4eConf.isPassHead(); + long maxRead = j4eConf.getMaxRead(); + J4EEmptyRow emptyRowChecker = (J4EEmptyRow) j4eConf.getPassEmptyRow(); + boolean needCheckEmptyRow = emptyRowChecker != null; int currRow = 0; int currColumn = 0; boolean firstRow = true; + long readNum = 0; while (rlist.hasNext()) { + // 最大值 + if (maxRead > 0) { + if (readNum >= maxRead) { + break; + } + } Row row = rlist.next(); if (currRow >= passRow) { currColumn = 0; if (firstRow) { - // TODO passColumn的测试 - // 确定column的index - Iterator clist = row.cellIterator(); - int cindex = 0; - Map headIndexMap = new HashMap(); - while (clist.hasNext()) { - Cell chead = clist.next(); - headIndexMap.put(cellValue(chead, null), cindex++); + if (!passHead) { + // 确定column的index + Iterator clist = row.cellIterator(); + int cindex = 0; + Map headIndexMap = new HashMap(); + while (clist.hasNext()) { + Cell chead = clist.next(); + headIndexMap.put(cellValue(chead, null), cindex++); + } + for (J4EColumn jcol : j4eConf.getColumns()) { + if (null != headIndexMap.get(jcol.getColumnName())) { + // by columnName + jcol.setColumnIndex(headIndexMap.get(jcol.getColumnName())); + } else if (null != headIndexMap.get(jcol.getFieldName())) { + // by field + jcol.setColumnIndex(headIndexMap.get(jcol.getFieldName())); + } else if (null != jcol.getColumnIndex() + && jcol.getColumnIndex() >= 0) { + // 已经设置过的index ??? 这个提醒一下 + log.warnf("J4EColumn has already set index[%d], but not sure It is right", + jcol.getColumnIndex()); + } else { + jcol.setColumnIndex(null); + } + } } for (J4EColumn jcol : j4eConf.getColumns()) { - if (null != headIndexMap.get(jcol.getColumnName())) { - // by columnName - jcol.setColumnIndex(headIndexMap.get(jcol.getColumnName())); - } else if (null != headIndexMap.get(jcol.getFieldName())) { - // by field - jcol.setColumnIndex(headIndexMap.get(jcol.getFieldName())); - } else if (null != jcol.getColumnIndex() && jcol.getColumnIndex() >= 0) { - // 已经设置过的index ??? 这个提醒一下 - log.warnf("J4EColumn has already set index[%d], but not sure It is right", - jcol.getColumnIndex()); - } else { - jcol.setColumnIndex(null); - } // 查找field if (jcol.getColumnIndex() != null && jcol.getColumnIndex() >= 0) { try { @@ -323,6 +345,8 @@ public class J4E { passContentRow--; continue; } + + readNum++; // 开始读数据 T rVal = rowValue(row, j4eConf, mc); if (null != j4eConf.getEachPrepare()) { @@ -331,7 +355,13 @@ public class J4E { j4eConf.getEachModify().doEach(rVal, row, j4eConf.getColumns()); } if (!j4eConf.isNoReturn()) { - dataList.add(rVal); + if (needCheckEmptyRow) { + if (!emptyRowChecker.isEmpty(rVal)) { + dataList.add(rVal); + } + } else { + dataList.add(rVal); + } } } currRow++; @@ -367,14 +397,20 @@ public class J4E { for (J4EColumn jcol : j4eConf.getColumns()) { Field jfield = jcol.getField(); if (null != jfield) { - Cell cell = row.getCell(jcol.getColumnIndex()); + Cell cell = row.getCell(jcol.getColumnIndex() + j4eConf.getPassColumn()); if (null == cell) { log.warn(String.format("cell [%d, %d] has null, so value is ''", row.getRowNum(), jcol.getColumnIndex())); } String cVal = (null == cell ? "" : cellValue(cell, jcol)); - mc.setValue(rVal, jfield, cVal); + if (jcol.getFromExcelFun() != null) { + J4ECellFromExcel cellFun = jcol.getFromExcelFun(); + Object setVal = cellFun.fromExcel(cVal); + mc.setValue(rVal, jfield, setVal); + } else { + mc.setValue(rVal, jfield, cVal); + } } } return rVal; @@ -389,7 +425,7 @@ public class J4E { colType = J4EColumnType.STRING; } try { - @SuppressWarnings({"deprecation"}) // 4.2之后将可直接调用c.getCellType返回枚举 + // 3.1.5之后将可直接调用c.getCellType返回枚举 CellType cType = c.getCellTypeEnum(); switch (cType) { case NUMERIC: // 数字 @@ -538,7 +574,7 @@ public class J4E { * @param wb * @return */ - private static boolean saveExcel(OutputStream out, Workbook wb) { + public static boolean saveExcel(OutputStream out, Workbook wb) { try { wb.write(out); return true; diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcel.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcel.java new file mode 100644 index 0000000000000000000000000000000000000000..e0676ad4d177e61552abc82f04821976348b2e50 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcel.java @@ -0,0 +1,12 @@ +package org.nutz.integration.json4excel; + +/** + * 实现数据类型自由转换 + * + * @author pw + * + */ +public interface J4ECellFromExcel { + + public Object fromExcel(Object cellVal); +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcelImpl.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcelImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ae81bb0bfeeb459dce7c9d10cb5cf05100b71c2d --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellFromExcelImpl.java @@ -0,0 +1,10 @@ +package org.nutz.integration.json4excel; + +public class J4ECellFromExcelImpl implements J4ECellFromExcel { + + @Override + public Object fromExcel(Object cellVal) { + return null; + } + +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcel.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcel.java new file mode 100644 index 0000000000000000000000000000000000000000..ce4eba8175a933eb31c83f9d5cbd1422f54ae5d2 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcel.java @@ -0,0 +1,7 @@ +package org.nutz.integration.json4excel; + +public interface J4ECellToExcel { + + public Object toExecl(Object fieldVal); + +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcelImpl.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcelImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0a84fdf74eedef375f7042ca80355eb31983ec99 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4ECellToExcelImpl.java @@ -0,0 +1,10 @@ +package org.nutz.integration.json4excel; + +public class J4ECellToExcelImpl implements J4ECellToExcel { + + @Override + public Object toExecl(Object fieldVal) { + return null; + } + +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumn.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumn.java index 7e9aebf5ec2fa16538fa549bec2d1b2f6eb715e2..0f2d7464e8e085354c8c884e15f046fce2fe0efa 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumn.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumn.java @@ -3,6 +3,7 @@ package org.nutz.integration.json4excel; import java.lang.reflect.Field; import org.nutz.json.JsonField; +import org.nutz.lang.Mirror; public class J4EColumn { @@ -18,6 +19,10 @@ public class J4EColumn { // 列按照什么类型读取 private J4EColumnType columnType; + // 自定义处理方法 + private J4ECellToExcel toExcelFun; + private J4ECellFromExcel fromExcelFun; + private int precision; private boolean isIgnore; @@ -93,4 +98,22 @@ public class J4EColumn { this.isIgnore = isIgnore; } + public J4ECellToExcel getToExcelFun() { + return toExcelFun; + } + + public J4ECellFromExcel getFromExcelFun() { + return fromExcelFun; + } + + public void setToExcelFun(Class cellFun) { + Mirror mc = Mirror.me(cellFun); + toExcelFun = mc.born(); + } + + public void setFromExcelFun(Class cellFun) { + Mirror mc = Mirror.me(cellFun); + fromExcelFun = mc.born(); + } + } diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumnType.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumnType.java index 60611939fc35f468fb851d1e7a3f69802f0c66da..6413b56c70052d15f01d69162214a1a002762f19 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumnType.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EColumnType.java @@ -1,5 +1,5 @@ package org.nutz.integration.json4excel; public enum J4EColumnType { - STRING, NUMERIC, DATE + STRING, NUMERIC, DATE, FUNCTION } diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EConf.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EConf.java index 5afe0772a90b172e70f2ec859b2ae53f205f5dc5..d5ddb8fed1f89094c61d9040dc8a522c7063d9f8 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EConf.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EConf.java @@ -9,6 +9,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; +import org.nutz.integration.json4excel.annotation.J4ECell; import org.nutz.integration.json4excel.annotation.J4EDefine; import org.nutz.integration.json4excel.annotation.J4EExt; import org.nutz.integration.json4excel.annotation.J4EIgnore; @@ -39,6 +40,15 @@ public class J4EConf { // 跳过标头 private boolean passHead; + // 最大写入行数 + private long maxWrite; + + // 最大读取行数 + private long maxRead; + + // 跳过空行检查 + private J4EEmptyRow passEmptyRow; + // sheet中对应的列 private List columns; @@ -174,6 +184,31 @@ public class J4EConf { this.eachModify = eachModify; } + public J4EEmptyRow getPassEmptyRow() { + return passEmptyRow; + } + + public void setPassEmptyRow(Class cellFun) { + Mirror mc = Mirror.me(cellFun); + passEmptyRow = mc.born(); + } + + public long getMaxWrite() { + return maxWrite; + } + + public void setMaxWrite(long maxWrite) { + this.maxWrite = maxWrite; + } + + public long getMaxRead() { + return maxRead; + } + + public void setMaxRead(long maxRead) { + this.maxRead = maxRead; + } + public static J4EConf from(Class clz) { J4EConf jc = new J4EConf(); // Ext @@ -183,6 +218,12 @@ public class J4EConf { jc.passColumn = ecnf.passColumn(); jc.passHead = ecnf.passHead(); jc.passContentRow = ecnf.passContentRow(); + jc.maxRead = ecnf.maxRead(); + jc.maxWrite = ecnf.maxWrite(); + Class> perow = ecnf.passEmptyRow(); + if (!perow.isAssignableFrom(J4EEmptyRowImpl.class)) { + jc.setPassEmptyRow(perow); + } } // sheet String sheetName = null; @@ -206,11 +247,25 @@ public class J4EConf { if (define != null) { jcol.setColumnType(define.type()); jcol.setPrecision(define.precision()); + if (define.columnIndex() > -1) { + jcol.setColumnIndex(define.columnIndex()); + } } J4EIgnore ignore = cf.getAnnotation(J4EIgnore.class); if (ignore != null) { jcol.setIgnore(true); } + J4ECell cellset = cf.getAnnotation(J4ECell.class); + if (cellset != null) { + Class toExcelFun = cellset.toExcel(); + if (!toExcelFun.isAssignableFrom(J4ECellToExcelImpl.class)) { + jcol.setToExcelFun(toExcelFun); + } + Class fromExcelFun = cellset.fromExcel(); + if (!fromExcelFun.isAssignableFrom(J4ECellFromExcelImpl.class)) { + jcol.setFromExcelFun(fromExcelFun); + } + } jclist.add(jcol); } jc.setColumns(jclist); diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRow.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRow.java new file mode 100644 index 0000000000000000000000000000000000000000..e0c3c86958a527f205006016097a15131815c842 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRow.java @@ -0,0 +1,5 @@ +package org.nutz.integration.json4excel; + +public interface J4EEmptyRow { + boolean isEmpty(T rowData); +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRowImpl.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRowImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..5f3cac25f4765cdb6c20dd04033184d3f73b8991 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/J4EEmptyRowImpl.java @@ -0,0 +1,12 @@ +package org.nutz.integration.json4excel; + +import org.apache.poi.ss.formula.functions.T; + +public class J4EEmptyRowImpl implements J4EEmptyRow { + + @Override + public boolean isEmpty(T rowData) { + // 不判断 全部返回 + return false; + } +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4ECell.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4ECell.java new file mode 100644 index 0000000000000000000000000000000000000000..6bbe7d981881a6cf5e9814ff9051a9b86afba984 --- /dev/null +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4ECell.java @@ -0,0 +1,26 @@ +package org.nutz.integration.json4excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.nutz.integration.json4excel.J4ECellFromExcel; +import org.nutz.integration.json4excel.J4ECellFromExcelImpl; +import org.nutz.integration.json4excel.J4ECellToExcel; +import org.nutz.integration.json4excel.J4ECellToExcelImpl; + +/** + * 字段处理方法,toExcel跟fromExcel全部有自己来实现 + * + * @author pw + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface J4ECell { + + Class toExcel() default J4ECellToExcelImpl.class; + + Class fromExcel() default J4ECellFromExcelImpl.class; +} diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EDefine.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EDefine.java index 2a612379ed0a3601d90c4ac0933ef40a833f14f6..8f2185d2a836b78cdfc7e6a88d62654ee5f3aa97 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EDefine.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EDefine.java @@ -20,4 +20,7 @@ public @interface J4EDefine { J4EColumnType type() default J4EColumnType.STRING; int precision() default 0; + + int columnIndex() default -1; + } diff --git a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EExt.java b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EExt.java index ceff330505d8bdfdf59600a9e834ea8183dee6d0..3d7db939292ae9d66dc189e7c83b4ef061a112d1 100644 --- a/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EExt.java +++ b/nutz-integration-json4excel/src/main/java/org/nutz/integration/json4excel/annotation/J4EExt.java @@ -5,6 +5,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.nutz.integration.json4excel.J4EEmptyRow; +import org.nutz.integration.json4excel.J4EEmptyRowImpl; + /** * 额外的配置 * @@ -21,5 +24,11 @@ public @interface J4EExt { int passColumn() default 0;; + long maxRead() default 0; + + long maxWrite() default 0; + boolean passHead() default false; + + Class> passEmptyRow() default J4EEmptyRowImpl.class; } diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/AllTestNoDB.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/AllTestNoDB.java index 039ba1dc3b687548ce7cbff94a37f80002febd6e..c4121950f850dba952e36e9658e91b7f81434d70 100644 --- a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/AllTestNoDB.java +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/AllTestNoDB.java @@ -2,8 +2,13 @@ package org.nutz.integration.json4excel; import org.junit.runner.RunWith; import org.junit.runners.Suite; +import org.nutz.integration.json4excel.issue.HuromRun; import org.nutz.integration.json4excel.issue.IssueRun; @RunWith(Suite.class) -@Suite.SuiteClasses({J4EConfTest.class, J4ETest.class, J4ETest2007.class, IssueRun.class}) +@Suite.SuiteClasses({J4EConfTest.class, + J4ETest.class, + J4ETest2007.class, + IssueRun.class, + HuromRun.class}) public class AllTestNoDB {} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/J4ETest.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/J4ETest.java index cdda933d232909293bb1e745e7551e2445ed2816..40737609d7e56615561a40b0ba0cd9f66e85d2ed 100644 --- a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/J4ETest.java +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/J4ETest.java @@ -15,7 +15,7 @@ import org.nutz.lang.util.Disks; public class J4ETest extends TestUtil { - public static final String TMPDIR = System.getProperty("java.io.tmpdir"); + public static final String TMPDIR = Disks.absolute("~/tmp/"); @Test public void test_fromExcel() throws Exception { diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/TestUtil.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/TestUtil.java index 72c0d99ffee2246643e89ae32d8bcab081006dd7..39b4546dc0b521046009d988fec315355f3dfb00 100644 --- a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/TestUtil.java +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/TestUtil.java @@ -12,10 +12,11 @@ import java.util.List; import org.nutz.integration.json4excel.bean.Person; import org.nutz.lang.Streams; +import org.nutz.lang.util.Disks; public abstract class TestUtil { - public static final String TMPDIR = System.getProperty("java.io.tmpdir"); + public static final String TMPDIR = Disks.absolute("~/tmp/"); public static String FD(Date d) { return new SimpleDateFormat("yyyy-MM-dd").format(d); diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunLong2Str.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunLong2Str.java new file mode 100644 index 0000000000000000000000000000000000000000..709ff1618da0af67f1711739557f152dbec784f7 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunLong2Str.java @@ -0,0 +1,18 @@ +package org.nutz.integration.json4excel.bean; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.nutz.castor.Castors; +import org.nutz.integration.json4excel.J4ECellToExcel; + +public class CellFunLong2Str implements J4ECellToExcel { + + @Override + public Object toExecl(Object fieldVal) { + Long createAt = Castors.me().castTo(fieldVal, Long.class); + Date dateAt = new Date(createAt); + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateAt); + } + +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunStatus.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..4102351cacd4d08db0119200a6fabef7366d760a --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/CellFunStatus.java @@ -0,0 +1,20 @@ +package org.nutz.integration.json4excel.bean; + +import org.nutz.castor.Castors; +import org.nutz.integration.json4excel.J4ECellToExcel; + +public class CellFunStatus implements J4ECellToExcel { + + @Override + public Object toExecl(Object fieldVal) { + Integer status = Castors.me().castTo(fieldVal, Integer.class); + if (status == 1) { + return "审核通过"; + } + if (status == 2) { + return "未通过"; + } + return "未知状态"; + } + +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/Dashayu.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/Dashayu.java new file mode 100644 index 0000000000000000000000000000000000000000..6e2a52b6a0333573df43232ef3a37234b4ab3b50 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/Dashayu.java @@ -0,0 +1,8 @@ +package org.nutz.integration.json4excel.bean; + +public class Dashayu { + + public int id; + + public String nm; +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/DashayuChild.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/DashayuChild.java new file mode 100644 index 0000000000000000000000000000000000000000..8f8576567edff4416183c010c83898cbe3a653df --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/DashayuChild.java @@ -0,0 +1,20 @@ +package org.nutz.integration.json4excel.bean; + +import org.nutz.integration.json4excel.J4EColumnType; +import org.nutz.integration.json4excel.annotation.J4ECell; +import org.nutz.integration.json4excel.annotation.J4EDefine; +import org.nutz.integration.json4excel.annotation.J4EName; + +@J4EName("大鲨鱼测试数据") +public class DashayuChild extends Dashayu { + + @J4EName("创建时间") + @J4EDefine(type = J4EColumnType.STRING) + @J4ECell(toExcel = CellFunLong2Str.class) + public long createAt; + + @J4EName("状态") + @J4EDefine(type = J4EColumnType.STRING) + @J4ECell(toExcel = CellFunStatus.class) + public int status; +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromEmptyRow.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromEmptyRow.java new file mode 100644 index 0000000000000000000000000000000000000000..bd80dfa6cf3df775ea651ae376687029973dd9c9 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromEmptyRow.java @@ -0,0 +1,13 @@ +package org.nutz.integration.json4excel.bean; + +import org.nutz.integration.json4excel.J4EEmptyRow; +import org.nutz.lang.Strings; + +public class HuromEmptyRow implements J4EEmptyRow { + + @Override + public boolean isEmpty(HuromProduct rowData) { + return Strings.isBlank(rowData.getName()); + } + +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromProduct.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromProduct.java new file mode 100644 index 0000000000000000000000000000000000000000..961deefedccc3d4d983dc1b6544f804aca41467d --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromProduct.java @@ -0,0 +1,124 @@ +package org.nutz.integration.json4excel.bean; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.List; + +import org.nutz.integration.json4excel.J4E; +import org.nutz.integration.json4excel.J4EColumnType; +import org.nutz.integration.json4excel.annotation.J4ECell; +import org.nutz.integration.json4excel.annotation.J4EDefine; +import org.nutz.integration.json4excel.annotation.J4EExt; +import org.nutz.integration.json4excel.annotation.J4EName; +import org.nutz.json.Json; +import org.nutz.json.JsonFormat; + +@J4EName("Homepeage_Specification") +@J4EExt(passEmptyRow = HuromEmptyRow.class) +public class HuromProduct { + // 型号 Key 前体区分 产品种类 额定电压 额定频率 额定功率 转数 电线长度 电机 保险丝 产品重量 外形尺寸 前体容量 Color + // Color(Detail) 颜色 具体颜色 生产地 渠道 제품분류 产品分类 + + @J4EName("id") + private String id; + + @J4EName("型号") + private String name; + + @J4EName("Key") + private String key; + + @J4EName("前体区分") + private String forebody_type; + + @J4EName("产品种类") + private String product_type; + + @J4EName("转数") + private String speed; + + @J4EName("电线长度") + private String elen; + + @J4EName("产品重量") + @J4EDefine(precision = 1, type = J4EColumnType.NUMERIC) + @J4ECell(fromExcel = HuromWeight.class) + private String weight; + + @J4EName("外形尺寸") + private String size; + + @J4EName("前体容量") + private String forebody_size; + + @J4EName("产品分类") + private String catelog; + + public String getID() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getForebody_type() { + return forebody_type; + } + + public void setForebody_type(String forebody_type) { + this.forebody_type = forebody_type; + } + + public String getProduct_type() { + return product_type; + } + + public void setProduct_type(String product_type) { + this.product_type = product_type; + } + + public String getSpeed() { + return speed; + } + + public void setSpeed(String speed) { + this.speed = speed; + } + + public String getElen() { + return elen; + } + + public void setElen(String elen) { + this.elen = elen; + } + + public String getWeight() { + return weight; + } + + public void setWeight(String weight) { + this.weight = weight; + } + + public static void main(String[] args) throws FileNotFoundException { + // 第一步,使用j4e解析excel文件获得数据集合 + InputStream in = new FileInputStream("E:\\原汁机规格参数.xls"); + List ps = J4E.fromExcel(in, HuromProduct.class, null); + System.out.println(Json.toJson(ps, JsonFormat.full())); + } +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromWeight.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromWeight.java new file mode 100644 index 0000000000000000000000000000000000000000..8db2cae57c76e1ef5a4e3a18a1164a041b58a058 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/HuromWeight.java @@ -0,0 +1,12 @@ +package org.nutz.integration.json4excel.bean; + +import org.nutz.integration.json4excel.J4ECellFromExcel; + +public class HuromWeight implements J4ECellFromExcel { + + @Override + public Object fromExcel(Object cellVal) { + return cellVal.toString() + "kg"; + } + +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/I91Bean.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/I91Bean.java new file mode 100644 index 0000000000000000000000000000000000000000..716c62bd354d69a540f467fc4e9fe9266b313111 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/bean/I91Bean.java @@ -0,0 +1,32 @@ +package org.nutz.integration.json4excel.bean; + +import org.nutz.integration.json4excel.J4EColumnType; +import org.nutz.integration.json4excel.annotation.J4EDefine; +import org.nutz.integration.json4excel.annotation.J4EExt; +import org.nutz.integration.json4excel.annotation.J4EName; + +@J4EName("test") +@J4EExt(passHead = true) +public class I91Bean { + + @J4EName("项目") + @J4EDefine(columnIndex = 0) + public String name; + + @J4EName("REF") + @J4EDefine(precision = 2, type = J4EColumnType.NUMERIC, columnIndex = 1) + public double ref; + + @J4EName("累计") + @J4EDefine(precision = 2, type = J4EColumnType.NUMERIC, columnIndex = 2) + public double d1; + + @J4EName("计划值") + @J4EDefine(precision = 2, type = J4EColumnType.NUMERIC, columnIndex = 3) + public double d2; + + @J4EName("与计划差值") + @J4EDefine(precision = 2, type = J4EColumnType.NUMERIC, columnIndex = 4) + public double d3; + +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/HuromRun.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/HuromRun.java new file mode 100644 index 0000000000000000000000000000000000000000..d20b8196bf63594390632cf7000d84d68fde7b38 --- /dev/null +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/HuromRun.java @@ -0,0 +1,21 @@ +package org.nutz.integration.json4excel.issue; + +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; +import java.util.List; + +import org.junit.Test; +import org.nutz.integration.json4excel.J4E; +import org.nutz.integration.json4excel.TestUtil; +import org.nutz.integration.json4excel.bean.HuromProduct; + +public class HuromRun extends TestUtil { + + @Test + public void loadExcel() throws Exception { + InputStream in = this.getClass().getResourceAsStream("hdata.xlsx"); + List ps = J4E.fromExcel(in, HuromProduct.class, null); + assertEquals(2, ps.size()); + } +} diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/IssueRun.java b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/IssueRun.java index 391ee7521e8316c17b928bf1fade40e10b3d797a..e45591928c4c209cf5d5ab8e8be896ddd03d4520 100644 --- a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/IssueRun.java +++ b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/IssueRun.java @@ -2,18 +2,27 @@ package org.nutz.integration.json4excel.issue; import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; import org.junit.Test; import org.nutz.integration.json4excel.J4E; +import org.nutz.integration.json4excel.J4EColumn; +import org.nutz.integration.json4excel.J4EConf; import org.nutz.integration.json4excel.TestUtil; +import org.nutz.integration.json4excel.bean.DashayuChild; import org.nutz.integration.json4excel.bean.I68Bean; +import org.nutz.integration.json4excel.bean.I91Bean; import org.nutz.lang.Files; import org.nutz.lang.util.Disks; public class IssueRun extends TestUtil { + // https://github.com/nutzam/nutzmore/issues/16 @Test public void testIssue16() throws Exception { List vrList = J4E.fromExcel(this.getClass().getResourceAsStream("Book1.xlsx"), @@ -29,6 +38,7 @@ public class IssueRun extends TestUtil { assertEquals(1015, vr1.getSearchCount()); } + // https://github.com/nutzam/nutzmore/issues/68 @Test public void testIssue68() throws Exception { I68Bean d1 = new I68Bean(); @@ -39,6 +49,140 @@ public class IssueRun extends TestUtil { dataList.add(d1); dataList.add(d2); - J4E.toExcel(Files.createFileIfNoExists2(Disks.normalize("~/issue68.xls")), dataList, null); + J4E.toExcel(Files.createFileIfNoExists2(Disks.normalize("~/tmp/issue68.xls")), + dataList, + null); + } + + // https://github.com/nutzam/nutzmore/issues/86 + @Test + public void testIssue86() throws Exception { + // 准备数据 + DashayuChild dChild = new DashayuChild(); + dChild.id = 1000; + dChild.nm = "pw"; + dChild.createAt = System.currentTimeMillis(); + dChild.status = 1; + + DashayuChild dChild2 = new DashayuChild(); + dChild2.id = 1001; + dChild2.nm = "dsy"; + dChild2.createAt = System.currentTimeMillis(); + dChild2.status = 2; + + List dataList = new ArrayList(); + dataList.add(dChild); + dataList.add(dChild2); + + // 手动设置配置 + J4EConf j4eConf = J4EConf.from(DashayuChild.class); + List jcols = j4eConf.getColumns(); + for (J4EColumn j4eColumn : jcols) { + // id不需要 + if ("id".equals(j4eColumn.getFieldName())) { + j4eColumn.setIgnore(true); + } + // nm需要中文名称 + if ("nm".equals(j4eColumn.getFieldName())) { + j4eColumn.setColumnName("名称"); + } + } + // 导出 + J4E.toExcel(Files.createFileIfNoExists2(Disks.normalize("~/tmp/issue86.xls")), + dataList, + j4eConf); + } + + // https://github.com/nutzam/nutzmore/issues/91 + @Test + public void testIssue91() throws Exception { + // 默认配置 + J4EConf econf = J4EConf.from(I91Bean.class); + // 制作点假数据,三行就够了 + I91Bean c1 = new I91Bean(); + c1.name = "电耗(度)"; + c1.ref = 20030.23d; + c1.d1 = 40277.39d; + c1.d2 = 35.00d; + c1.d3 = 20050.00d; + + I91Bean c2 = new I91Bean(); + c2.name = "新水耗(kg)"; + c2.ref = 20039.00d; + c2.d1 = 40531.00d; + c2.d2 = 0.00d; + c2.d3 = 19833.00d; + + I91Bean c3 = new I91Bean(); + c3.name = "中水耗(kg)"; + c3.ref = 18372.34d; + c3.d1 = 49883.03d; + c3.d2 = 2.00d; + c3.d3 = 20001.00d; + + List clist = new ArrayList(); + clist.add(c1); + clist.add(c2); + clist.add(c3); + + // 加载模板 + Workbook wb = J4E.loadExcel(this.getClass().getResourceAsStream("i91.xls")); + // 第一排左边 + econf.setPassColumn(0).setPassRow(1); + J4E.toExcel(wb, null, clist, econf); + // 第一排右边 + econf.setPassColumn(5).setPassRow(1); + J4E.toExcel(wb, null, clist, econf); + + // 第二排左边 + econf.setPassColumn(0).setPassRow(9); + J4E.toExcel(wb, null, clist, econf); + // 第二排右边 + econf.setPassColumn(5).setPassRow(9); + J4E.toExcel(wb, null, clist, econf); + + File outFile = Files.createFileIfNoExists2(Disks.normalize("~/tmp/issue91.xls")); + J4E.saveExcel(new FileOutputStream(outFile), wb); + } + + @Test + public void testIssue91Read() throws Exception { + // 默认配置 + J4EConf econf = J4EConf.from(I91Bean.class); + // 加载模板 + Workbook wb = J4E.loadExcel(this.getClass().getResourceAsStream("i91Read.xls")); + // 第一个sheet + Sheet sheet1 = wb.getSheet("第一个"); + // 第一排左边 + econf.setPassColumn(0).setPassRow(1).setMaxRead(3); // 只读3行数据 + List dlist01 = J4E.fromSheet(sheet1, I91Bean.class, econf, false); + assertEquals(3, dlist01.size()); + assertEquals("我是上面1", dlist01.get(0).name); + + // 第一排右边 + econf.setPassColumn(5).setPassRow(1).setMaxRead(2); // 只读2行数据 + List dlist02 = J4E.fromSheet(sheet1, I91Bean.class, econf, false); + assertEquals(2, dlist02.size()); + assertEquals("我是右边的2", dlist02.get(1).name); + + // 第二排左边 + econf.setPassColumn(0).setPassRow(9).setMaxRead(3); // 只读3行数据 + List dlist03 = J4E.fromSheet(sheet1, I91Bean.class, econf, false); + assertEquals(3, dlist03.size()); + assertEquals("我是下面3", dlist03.get(2).name); + + // 第二排右边 + econf.setPassColumn(5).setPassRow(9).setMaxRead(2); // 只读2行数据 + List dlist04 = J4E.fromSheet(sheet1, I91Bean.class, econf, false); + assertEquals(2, dlist04.size()); + assertEquals("我是下面右边2", dlist04.get(1).name); + + // 第二个sheet + Sheet sheet2 = wb.getSheet("第二个"); + // 第一排左边 + econf.setPassColumn(0).setPassRow(1).setMaxRead(1); // 只读1行数据 + List dlist05 = J4E.fromSheet(sheet2, I91Bean.class, econf, false); + assertEquals(1, dlist05.size()); + } } diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/hdata.xlsx b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/hdata.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d23e115d2cc1a45008dec40a61bd2f91154ed910 Binary files /dev/null and b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/hdata.xlsx differ diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91.xls b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91.xls new file mode 100644 index 0000000000000000000000000000000000000000..30f111aec815255c08f62eacc6356b313046737f Binary files /dev/null and b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91.xls differ diff --git a/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91read.xls b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91read.xls new file mode 100644 index 0000000000000000000000000000000000000000..6e3c1a8075e6331d9bab8fbca420ab4958907fb4 Binary files /dev/null and b/nutz-integration-json4excel/src/test/java/org/nutz/integration/json4excel/issue/i91read.xls differ diff --git a/nutz-integration-json4excel/src/test/java/test.xls b/nutz-integration-json4excel/src/test/java/test.xls index f8b40efa7c45d534a89e811d140dd37e0c3b7552..0716876e7c2e4b612602f66c7fa0514b3a6765e9 100644 Binary files a/nutz-integration-json4excel/src/test/java/test.xls and b/nutz-integration-json4excel/src/test/java/test.xls differ diff --git a/nutz-integration-jsr303/pom.xml b/nutz-integration-jsr303/pom.xml index 0c2ae65b5731528f84d86d8a6adaa860dba12c6c..93ff3d4fba16a235e136d1770b6345e3dc699961 100644 --- a/nutz-integration-jsr303/pom.xml +++ b/nutz-integration-jsr303/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-jsr303 Nutz and JSR 303 diff --git a/nutz-integration-neo4j/pom.xml b/nutz-integration-neo4j/pom.xml index db8a0db3ceb3f17e373affee342363f4c1465c80..a2423803e02e2bb90f806d824b04daf2ebeecc11 100644 --- a/nutz-integration-neo4j/pom.xml +++ b/nutz-integration-neo4j/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-neo4j diff --git a/nutz-integration-nettice/pom.xml b/nutz-integration-nettice/pom.xml index 57430c5677375fac032abf749e33c5143e7f2c74..61847ab5c5da515aa03778bcec6a523a3507a3dd 100755 --- a/nutz-integration-nettice/pom.xml +++ b/nutz-integration-nettice/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-nettice diff --git a/nutz-integration-quartz/demo/pom.xml b/nutz-integration-quartz/demo/pom.xml index fa7d65165f1121cef10e220cfcb853d439aa120f..93fc997ff9f147f58be5bdb9d4fe6290eec1d689 100644 --- a/nutz-integration-quartz/demo/pom.xml +++ b/nutz-integration-quartz/demo/pom.xml @@ -4,12 +4,12 @@ net.wendal nutz-quartz-demo war - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutzdemo Maven Webapp http://maven.apache.org UTF-8 - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT diff --git a/nutz-integration-quartz/pom.xml b/nutz-integration-quartz/pom.xml index 59b87dc27c7149602db6983f68f7b9c45f059f15..8c40a376f66c9f658a2c259755f82e3d7b70ada2 100644 --- a/nutz-integration-quartz/pom.xml +++ b/nutz-integration-quartz/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-quartz diff --git a/nutz-integration-rabbitmq/pom.xml b/nutz-integration-rabbitmq/pom.xml index 8c5c76a92d249fd1f3d33d7a2197e4b687b0def8..d9aa65d05a491e740025998a772f446fd5c9c089 100644 --- a/nutz-integration-rabbitmq/pom.xml +++ b/nutz-integration-rabbitmq/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-rabbitmq diff --git a/nutz-integration-shiro/demo/pom.xml b/nutz-integration-shiro/demo/pom.xml index 97586686e8f757988c1ce62f3e9ff9fe4f0fee47..cdd8949749d028db5774d6031841f5e94c4c1295 100644 --- a/nutz-integration-shiro/demo/pom.xml +++ b/nutz-integration-shiro/demo/pom.xml @@ -28,7 +28,7 @@ org.nutz nutz-integration-shiro - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT net.sf.ehcache diff --git a/nutz-integration-shiro/pom.xml b/nutz-integration-shiro/pom.xml index 505bc91ebb337c34b48bd56562ac14630f728624..a5cd970efe8646be19b0174bc6c5122483850d28 100644 --- a/nutz-integration-shiro/pom.xml +++ b/nutz-integration-shiro/pom.xml @@ -5,7 +5,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-shiro nutz-integration-shiro @@ -84,7 +84,7 @@ org.nutz nutz-plugins-cache - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT provided @@ -101,7 +101,7 @@ org.nutz nutz-plugins-mock - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT test diff --git a/nutz-integration-spring/demo/pom.xml b/nutz-integration-spring/demo/pom.xml index 1509cfd85388617c38f136c67ff3ab935673e5ea..216d9c07e19e9f5367b2fb0f245c81494f150f3e 100644 --- a/nutz-integration-spring/demo/pom.xml +++ b/nutz-integration-spring/demo/pom.xml @@ -4,7 +4,7 @@ com.ywjno nutz-spring-demo war - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutzdemo Maven Webapp http://maven.apache.org diff --git a/nutz-integration-spring/pom.xml b/nutz-integration-spring/pom.xml index a3abff26d1a8f86570223ab9eb40070de3a9c2ac..15ef8287fa04b371ea38e64aab6f2d5a8ff3aed0 100644 --- a/nutz-integration-spring/pom.xml +++ b/nutz-integration-spring/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-spring https://nutzam.com diff --git a/nutz-integration-struts2/pom.xml b/nutz-integration-struts2/pom.xml index 461d6761a3209491336b06402d96eca1bf71b539..f8f0ce2fe7d3daf4d47f161cb564b823213f593b 100644 --- a/nutz-integration-struts2/pom.xml +++ b/nutz-integration-struts2/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-struts2 https://nutzam.com diff --git a/nutz-integration-swagger/pom.xml b/nutz-integration-swagger/pom.xml index 0ac589d28585dd5657f01bedb4375edbd9b6cdad..c13b8ec130f886cd1360304ccd4e7e60209861b5 100644 --- a/nutz-integration-swagger/pom.xml +++ b/nutz-integration-swagger/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-swagger diff --git a/nutz-integration-zbus/demo/pom.xml b/nutz-integration-zbus/demo/pom.xml index 20effa7fe48933c5dd7d4938846d56bc0acc7f73..2204e43216b55fc0881603811b051efb00c1bf7f 100644 --- a/nutz-integration-zbus/demo/pom.xml +++ b/nutz-integration-zbus/demo/pom.xml @@ -4,7 +4,7 @@ net.wendal nutz-zbus-demo war - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutzdemo Maven Webapp http://maven.apache.org @@ -53,7 +53,7 @@ org.nutz nutz-integration-zbus - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT com.alibaba diff --git a/nutz-integration-zbus/pom.xml b/nutz-integration-zbus/pom.xml index 14ed997848feec84669e66beb48d029cecc63cdb..8efb93a1f4ea92c1728e9580514888b0f65336d8 100644 --- a/nutz-integration-zbus/pom.xml +++ b/nutz-integration-zbus/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-zbus diff --git a/nutz-integration-zookeeper/pom.xml b/nutz-integration-zookeeper/pom.xml index 70f547c57474be99d83022aba86a7077d8b4418a..ac2df05f38b7e69e975a397fc50eb92d7eb39f83 100644 --- a/nutz-integration-zookeeper/pom.xml +++ b/nutz-integration-zookeeper/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-integration-zookeeper https://nutzam.com diff --git a/nutz-maven-quickstart/pom.xml b/nutz-maven-quickstart/pom.xml index ce74786163793e4b4b91e3dcd2ba8eae55d57532..c4c2b85593d012a0a5b65d2b1c7b8194aaa6c420 100644 --- a/nutz-maven-quickstart/pom.xml +++ b/nutz-maven-quickstart/pom.xml @@ -4,7 +4,7 @@ org.nutz jar Nutz Maven QuickStart - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-webapp-quickstart UTF-8 diff --git a/nutz-plugins-apidoc/demo/pom.xml b/nutz-plugins-apidoc/demo/pom.xml index 97f971e730477514e79474d26e333404ef707f0e..f1521fac74710a9fee939d4a0e66c3d26b4a44ae 100644 --- a/nutz-plugins-apidoc/demo/pom.xml +++ b/nutz-plugins-apidoc/demo/pom.xml @@ -23,7 +23,7 @@ org.nutz nutz-plugins-apidoc - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT log4j diff --git a/nutz-plugins-apidoc/pom.xml b/nutz-plugins-apidoc/pom.xml index 8583622a76202d9de78e7d8944a827b9f74780f4..91c4c56f46ce596d303bbcab9554ba3a733178bf 100644 --- a/nutz-plugins-apidoc/pom.xml +++ b/nutz-plugins-apidoc/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-apidoc diff --git a/nutz-plugins-cache/pom.xml b/nutz-plugins-cache/pom.xml index c274a4ba6511f748ec0b712a38f5414391bdc5b2..93fbf164ba969218d2204e460dadac0185cc1360 100644 --- a/nutz-plugins-cache/pom.xml +++ b/nutz-plugins-cache/pom.xml @@ -3,14 +3,14 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-cache org.nutz nutz-integration-jedis - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT net.sf.ehcache diff --git a/nutz-plugins-daocache/README.md b/nutz-plugins-daocache/README.md index 5fa31e9cbb103a6edfae7c940705abb8bdcfa92b..4d515611e84e06c0b5218724b95013e68f0f987b 100644 --- a/nutz-plugins-daocache/README.md +++ b/nutz-plugins-daocache/README.md @@ -155,4 +155,21 @@ var ioc = { ``` 有用户反映ehcache在shiro.ini的配置顺序会导致获取到CacheManager为null,请确保 -ehcache的声明在其他所有realm声明之前 \ No newline at end of file +ehcache的声明在其他所有realm声明之前 + +## 使用redis + +dao.js中的cacheProvider变更一下 + +```js + // 基于Ehcache的DaoCacheProvider + cacheProvider : { + type : "org.nutz.plugins.cache.dao.impl.provider.RedisDaoCacheProvider", + fields : { + jedisPool : {refer:"jedisPool"} // 引用nutz-integration-jedis的JedisPool + }, + events : { + create : "init" + } + } +``` \ No newline at end of file diff --git a/nutz-plugins-daocache/pom.xml b/nutz-plugins-daocache/pom.xml index b61c281dcc6265c363c1ac3e7c790252fc5ca0d8..6b44925a0e64bca4faf7c8a79031c3b51ec77966 100644 --- a/nutz-plugins-daocache/pom.xml +++ b/nutz-plugins-daocache/pom.xml @@ -5,7 +5,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-daocache Nutz Dao Cache diff --git a/nutz-plugins-daomapping/pom.xml b/nutz-plugins-daomapping/pom.xml index 16ce0f0599686d8c1fbe1a48925acfd1a22ae9cd..9d0ca3c25d19bcc2eb535e4306a09833b59d1367 100644 --- a/nutz-plugins-daomapping/pom.xml +++ b/nutz-plugins-daomapping/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-daomapping diff --git a/nutz-plugins-dict/README.md b/nutz-plugins-dict/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6f43aa86bdd6e8f090665ac18227440f22ef063a --- /dev/null +++ b/nutz-plugins-dict/README.md @@ -0,0 +1,280 @@ +# nutz-plugins-dict 全局字典生成插件 + +简介(可用性:测试,维护者:邓华锋(http://dhf.ink)) +================================== + +生成全局字典文件和map供前段或视图里调用 + + +开发目的 +---------------------------------------------- +后台开发中经常牵涉到一些类型字典,例如(用户表的类型字段,分普通会员、高级会员等),如果用常规的常量标识不可取,没法统一,也没法很好的标识意义,推荐用枚举。 + 而前段展示类型字段值的字面意思时,通常是生拉硬写,各种if判断来展示不同的字面意思,不好维护,改动一处,要改动多处。 + 而此插件的开发目的是解决这些问题,让通过后台枚举配置注解的方式,生成可配置格式的前段json字典串,及全局的字典map,供前段调用等。 + + +使用示例 +---------------------------------------------- +使用select来注解枚举类,把所有字典想象成下拉框结构,所以有了selec这个注解。 +```Java +/** + * 下拉框注解,用于生成全局字典 + * + * @author 邓华锋 http://dhf.ink + * @date 2016年6月29日 上午3:03:43 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Documented +public @interface Select { + + public enum Fields { + NAME, TEXT, VALUE + } + + /** + * 下拉框ID和name属性的值 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:04:16 + * + * @return + */ + String name() default ""; + + /** + * 下拉框显示的文本 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:03:50 + * + * @return + */ + Fields text() default Fields.TEXT; + + /** + * 下拉框的值 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:04:02 + * + * @return + */ + Fields value() default Fields.VALUE; + +} +``` + + +```Java +import org.nutz.plugins.dict.Select; + +@Select +public enum JQGridSelectOPT { + eq("等于","="),ne("不等于","<>"),bw("开始于","LIKE ${value}%"),bn("不开始于","NOT LIKE ${value}%"),ew("结束于","LIKE %${value}"),en("不结束于","NOT LIKE %${value}"), + cn("包含","LIKE"),nc("不包含","NOT LIKE"),nu("空值于","IS NULL"),nn("非空值","IS NOT NULL"),in("属于","IN"),ni("不属于","NOT IN"), + lt("小于","<"),le("小于等于","<="),gt("大于",">"),ge("大于等于",">="); + + private String text; + + private String value; + + private JQGridSelectOPT(String text, String value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public String value() { + return value; + } + +} +``` + +```Java +import org.nutz.plugins.dict.Select; +import org.nutz.plugins.dict.Select.Fields; + +@Select(value=Fields.NAME) +public enum JQGridOrder { + asc("升序",0),desc("降序",1) ; + private String text; + + private int value; + + private JQGridOrder(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } +} +``` +枚举让代码可维护性,可读性高 +看以下示例: +```Java +String oper="edit"; +if (StringUtils.equals(oper, JQGridOper.add.name())) { + //TODO add +}else if (StringUtils.equals(oper, JQGridOper.del.name())) { + //TODO delete +}else if(StringUtils.equals(oper, JQGridOper.edit.name())) { + //TODO update +} +``` + +或 +```Java +int oper=1; +if (oper==JQGridOper.add.value()) { + //TODO add +}else if (oper==JQGridOper.del.value()) { + //TODO delete +}else if(oper==JQGridOper.edit.value()) { + //TODO update +} +``` + +执行生成字典代码 +```Java +Selects.custom().addProcessorFirst(new JqgridSelectProcessor()).addProcessorLast(new EditableSelectProcessor()).setPackages("org.nutz.plugins.dict").setJsonFilePath("e:/dict").build(); +``` + +生成的结果: +globalSelect.js +```javascript +var globalSelect={ + "jQGridGroupOP": { + "or": "或者", + "and": "并且" + }, + "jQGridOrder": { + "asc": "升序", + "desc": "降序" + }, + "jQGridSelectOPT": { + "=": "等于", + "<>": "不等于", + "LIKE ${value}%": "开始于", + "NOT LIKE ${value}%": "不开始于", + "LIKE %${value}": "结束于", + "NOT LIKE %${value}": "不结束于", + "LIKE": "包含", + "NOT LIKE": "不包含", + "IS NULL": "空值于", + "IS NOT NULL": "非空值", + "IN": "属于", + "NOT IN": "不属于", + "<": "小于", + "<=": "小于等于", + ">": "大于", + ">=": "大于等于" + } +}; +``` +jqgridSelect.js +```javascript +var jqgridSelect={ + "jQGridGroupOP": "or:或者;and:并且", + "jQGridOrder": "asc:升序;desc:降序", + "jQGridSelectOPT": "=:等于;<>:不等于;LIKE ${value}%:开始于;NOT LIKE ${value}%:不开始于;LIKE %${value}:结束于;NOT LIKE %${value}:不结束于;LIKE:包含;NOT LIKE:不包含;IS NULL:空值于;IS NOT NULL:非空值;IN:属于;NOT IN:不属于;<:小于;<=:小于等于;>:大于;>=:大于等于" +}; +``` +editableSelect.js +```javascript +var editableSelect={ + "jQGridGroupOP": [{ + "id": "or", + "text": "或者" + }, { + "id": "and", + "text": "并且" + }], + "jQGridOrder": [{ + "id": "asc", + "text": "升序" + }, { + "id": "desc", + "text": "降序" + }], + "jQGridSelectOPT": [{ + "id": "=", + "text": "等于" + }, { + "id": "<>", + "text": "不等于" + }, { + "id": "LIKE ${value}%", + "text": "开始于" + }, { + "id": "NOT LIKE ${value}%", + "text": "不开始于" + }, { + "id": "LIKE %${value}", + "text": "结束于" + }, { + "id": "NOT LIKE %${value}", + "text": "不结束于" + }, { + "id": "LIKE", + "text": "包含" + }, { + "id": "NOT LIKE", + "text": "不包含" + }, { + "id": "IS NULL", + "text": "空值于" + }, { + "id": "IS NOT NULL", + "text": "非空值" + }, { + "id": "IN", + "text": "属于" + }, { + "id": "NOT IN", + "text": "不属于" + }, { + "id": "<", + "text": "小于" + }, { + "id": "<=", + "text": "小于等于" + }, { + "id": ">", + "text": "大于" + }, { + "id": ">=", + "text": "大于等于" + }] +}; +``` + +如果要自定义实现字典生成,只需实现SelectProcessor接口,具体方法实现参考GlobalSelectProcessor、JqgridSelectProcessor和EditableSelectProcessor。 +前段使用方法:以globalSelect.js为例,假如globalSelect.js生成的路径在web服务器的项目目录里 +* 首先在页面引用这个js文件 +```HTML + +``` + +* 然后js可以这样调用 +```javascript +var opName=globalSelect["jQGridGroupOP"]["or"]; +console.log(opName); +``` + + +计划: +* 不用实现SelectProcessor,直接用通过模板引擎来自定义字典生成格式 + + diff --git a/nutz-plugins-dict/pom.xml b/nutz-plugins-dict/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a59f05c107ab109df13a50fe09ba304e5f6e7942 --- /dev/null +++ b/nutz-plugins-dict/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + + org.nutz + nutzmore + 1.r.66-SNAPSHOT + + nutz-plugins-dict + Nutz More dict + + + 邓华锋 + 邓华锋 + denghuafeng@gmail.com + http://dhf.ink + + + + UTF-8 + + + + com.alibaba + fastjson + 1.2.32 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + -parameters + + false + + + + org.apache.maven.plugins + maven-surefire-plugin + + once + -Dfile.encoding=UTF-8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + -Xdoclint:none + + + + + + + + nutzcn-snapshots + NutzCN snapshot repository + https://jfrog.nutz.cn/artifactory/snapshots + + + + sonatype-release-staging + Sonatype Nexus release repository + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Select.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Select.java new file mode 100644 index 0000000000000000000000000000000000000000..058fddf4278a1c5f7ff727372919a568911e4f5d --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Select.java @@ -0,0 +1,55 @@ +package org.nutz.plugins.dict; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 下拉框注解,用于生成全局字典 + * + * @author 邓华锋 http://dhf.ink + * @date 2016年6月29日 上午3:03:43 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Documented +public @interface Select { + + public enum Fields { + NAME, TEXT, VALUE + } + + /** + * 下拉框ID和name属性的值 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:04:16 + * + * @return + */ + String name() default ""; + + /** + * 下拉框显示的文本 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:03:50 + * + * @return + */ + Fields text() default Fields.TEXT; + + /** + * 下拉框的值 + * + * @author 邓华锋 + * @date 2016年6月29日 上午11:04:02 + * + * @return + */ + Fields value() default Fields.VALUE; + +} \ No newline at end of file diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/SelectBuilder.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/SelectBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..6ebeb16ec4fd52da2d41846f75c780fe08452848 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/SelectBuilder.java @@ -0,0 +1,221 @@ +package org.nutz.plugins.dict; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; + +import org.nutz.json.Json; +import org.nutz.lang.Strings; +import org.nutz.log.Log; +import org.nutz.log.Logs; +import org.nutz.plugins.dict.Select.Fields; +import org.nutz.plugins.dict.chain.GlobalSelectProcessor; +import org.nutz.plugins.dict.chain.SelectProcessor; +import org.nutz.plugins.dict.chain.SelectProcessorBuilder; +import org.nutz.resource.Scans; + + +/** + * 下拉框注解,用于生成全局字典 + * + * @author 邓华锋 http://dhf.ink + * + */ +public class SelectBuilder { + private static final Log log = Logs.get(); + private boolean systemProperties; + private SelectProcessor selectProcessor; + private LinkedList selectFirst; + private LinkedList selectLast; + private String[] packages; + private String jsonFilePath; + + public final SelectBuilder setPackages(String... packages) { + this.packages = packages; + return this; + } + + public final SelectBuilder setJsonFilePath(String jsonFilePath) { + this.jsonFilePath = jsonFilePath; + return this; + } + + public static SelectBuilder create() { + return new SelectBuilder(); + } + + public final SelectBuilder useSystemProperties() { + this.systemProperties = true; + return this; + } + + public final SelectBuilder addProcessorFirst(final SelectProcessor itcp) { + if (itcp == null) { + return this; + } + if (selectFirst == null) { + selectFirst = new LinkedList(); + } + selectFirst.addFirst(itcp); + return this; + } + + public final SelectBuilder addProcessorLast(final SelectProcessor itcp) { + if (itcp == null) { + return this; + } + if (selectLast == null) { + selectLast = new LinkedList(); + } + selectLast.addLast(itcp); + return this; + } + + @SuppressWarnings("unchecked") + public void build() { + if (systemProperties) { + + } + SelectProcessor selectProcessorCopy = this.selectProcessor; + // 添加执行链 + if (selectProcessorCopy == null) { + final SelectProcessorBuilder b = SelectProcessorBuilder.create(); + if (selectFirst != null) { + for (final SelectProcessor i : selectFirst) { + b.addFirst(i); + } + } + b.addAll(new GlobalSelectProcessor()); + if (selectLast != null) { + for (final SelectProcessor i : selectLast) { + b.addLast(i); + } + } + selectProcessorCopy = b.build(); + } + // 全局 用于生成文件 + Map globalDictVal = new HashMap(); + for (String pk : this.packages) { + for (Class clazz : Scans.me().scanPackage(pk)) { + Select select = clazz.getAnnotation(Select.class); + if (select == null) { + continue; + } + String name = select.name(); + Fields value = select.value(); + Fields text = select.text(); + if (Strings.isBlank(name)) { + name = Strings.lowerFirst(clazz.getSimpleName()); + } + + Class> enumClass = (Class>) clazz; + String val = value.name().toLowerCase(); + String txt = text.name().toLowerCase(); + try { + Method valMethod = enumClass.getMethod(val); + Method txtMethod = enumClass.getMethod(txt); + Enum[] enumElems = enumClass.getEnumConstants(); + for (int i = 0; i < enumElems.length; i++) { + Enum enumElem = enumElems[i]; + // TODO 如果没有value方法,则调用name方法 + String valStr = valMethod.invoke(enumElem).toString(); + String txtStr = txtMethod.invoke(enumElem).toString(); + selectProcessorCopy.process(valStr, txtStr); + } + selectProcessorCopy.put(name); + } catch (NoSuchMethodException e) { + log.error("枚举没有找到此方法", e); + } catch (SecurityException e) { + log.error("SecurityException", e); + } catch (IllegalAccessException e) { + log.error("IllegalAccessException", e); + } catch (IllegalArgumentException e) { + log.error("IllegalArgumentException", e); + } catch (InvocationTargetException e) { + log.error("InvocationTargetException", e); + } + } + } + //put全局变量里 + selectProcessorCopy.putGlobalDict(globalDictVal); + + //进行遍历生成js文件 + Iterator> it = globalDictVal.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + Object dictVal = entry.getValue(); + String key = entry.getKey(); + String valKey = "${" + entry.getKey() + "};"; + String jsonTpl = "var " + key + "=" + valKey + ";"; + String json = jsonTpl.replace(valKey, Json.toJson(dictVal)); + System.out.println(json); + String fileName = jsonFilePath + "/" + key + ".js"; + File file = new File(fileName); + try { + if (!file.getParentFile().exists()) { + // 如果目标文件所在的目录不存在,则创建父目录 + log.info("目标文件所在目录不存在,准备创建它!"); + if (!file.getParentFile().mkdirs()) { + log.info("创建目标文件所在目录失败!"); + } + } + if (!file.exists()) { + file.createNewFile(); + } else { + file.delete(); + file.createNewFile(); + } + FileWriter writer = new FileWriter(file, true); + writer.write(json); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + /*try { + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg); + Template t = gt.getTemplate(FileUtils.readFileToString(new File(jsFilePath))); + t.binding("dictSelectMap", dictSelect); + //t.binding("jqgridSelectMap", jqgridSelect); + //t.binding("editableSelectMap", editableSelect); + t.renderTo(new FileOutputStream(new File(jsFilePath))); + } catch (BeetlException e) { + log.error("BeetlException",e); + } catch (IOException e) { + log.error("IOException",e); + }*/ + } + /*public static void outToJs(String jsFilePath){ + SelectUtils.loadSelectToMap(); + String dictSelect=Json.toJson(SelectUtils.dictSelectMap); + log.info("var dictSelect="+dictSelect); + String jqgridSelect=Json.toJson(SelectUtils.jqgridSelectMap); + log.info("var jqgridSelect="+jqgridSelect); + String editableSelect=Json.toJson(SelectUtils.editableSelectMap); + log.info("var editableSelect="+editableSelect); + try { + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg); + Template t = gt.getTemplate(JS_TPL); + t.binding("dictSelectMap", dictSelect); + t.binding("jqgridSelectMap", jqgridSelect); + t.binding("editableSelectMap", editableSelect); + t.renderTo(new FileOutputStream(new File(jsFilePath))); + } catch (BeetlException e) { + log.error("BeetlException",e); + } catch (IOException e) { + log.error("IOException",e); + } + }*/ + +} \ No newline at end of file diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Selects.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Selects.java new file mode 100644 index 0000000000000000000000000000000000000000..bdce165e65fcc3e462360fbe1465aa0777672d79 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/Selects.java @@ -0,0 +1,19 @@ +package org.nutz.plugins.dict; + +public class Selects { + private Selects() { + super(); + } + + public static SelectBuilder custom() { + return SelectBuilder.create(); + } + + public static void createDefault() { + SelectBuilder.create().build(); + } + + public static void createSystem() { + SelectBuilder.create().useSystemProperties().build(); + } +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ChainBuilder.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ChainBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..45e962f4e01d240df732147de2a9ea5d2facda60 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ChainBuilder.java @@ -0,0 +1,90 @@ +package org.nutz.plugins.dict.chain; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +final class ChainBuilder { + + private final LinkedList list; + private final Map, E> uniqueClasses; + + public ChainBuilder() { + this.list = new LinkedList(); + this.uniqueClasses = new HashMap, E>(); + } + + private void ensureUnique(final E e) { + final E previous = this.uniqueClasses.remove(e.getClass()); + if (previous != null) { + this.list.remove(previous); + } + this.uniqueClasses.put(e.getClass(), e); + } + + public ChainBuilder addFirst(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addFirst(e); + return this; + } + + public ChainBuilder addLast(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addLast(e); + return this; + } + + public ChainBuilder addAllFirst(final Collection c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + @SuppressWarnings("unchecked") + public ChainBuilder addAllFirst(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + public ChainBuilder addAllLast(final Collection c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + @SuppressWarnings("unchecked") + public ChainBuilder addAllLast(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + public LinkedList build() { + return new LinkedList(this.list); + } + +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/EditableSelectProcessor.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/EditableSelectProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..516b7ad3246525513f5113fee78a5c7d25e71d50 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/EditableSelectProcessor.java @@ -0,0 +1,35 @@ +package org.nutz.plugins.dict.chain; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * jqGrid编辑表时 + * @author 邓华锋 http://dhf.ink + * + */ +public class EditableSelectProcessor implements SelectProcessor { + public static Map>> editableSelectMap = new LinkedHashMap>>(); + List> row = new LinkedList>(); + + @Override + public void process(String value, String text) { + Map map = new LinkedHashMap(); + map.put("id", value); + map.put("text", text); + row.add(map); + } + + @Override + public void put(String key) { + editableSelectMap.put(key, row); + row= new LinkedList>(); + } + + @Override + public void putGlobalDict(Map globalDictVal) { + globalDictVal.put("editableSelect",editableSelectMap); + } +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/GlobalSelectProcessor.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/GlobalSelectProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..3e75cc325cb017171210b624ecbdcbdc12b7b3eb --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/GlobalSelectProcessor.java @@ -0,0 +1,32 @@ +package org.nutz.plugins.dict.chain; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 全局 常用的 + * @author 邓华锋 http://dhf.ink + * + */ +public class GlobalSelectProcessor implements SelectProcessor { + public static Map> dictSelectMap = new LinkedHashMap>(); + + Map dictMap = new LinkedHashMap(); + + @Override + public void process(String value, String text) { + dictMap.put(value, text); + } + + @Override + public void put(String key) { + dictSelectMap.put(key, dictMap); + dictMap = new LinkedHashMap(); + } + + @Override + public void putGlobalDict(Map globalDictVal) { + globalDictVal.put("globalSelect",dictSelectMap); + } + +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ImmutableSelectProcessor.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ImmutableSelectProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..68c12ee926ce8e29e1ff32baff120e08e8a39024 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/ImmutableSelectProcessor.java @@ -0,0 +1,54 @@ +package org.nutz.plugins.dict.chain; + +import java.util.List; +import java.util.Map; + +public class ImmutableSelectProcessor implements SelectProcessor { + private final SelectProcessor[] selectProcessors; + + /* + * public ImmutableSelectProcessor(final SelectProcessor... requestInterceptors) + * { //this(requestInterceptors); } + */ + public ImmutableSelectProcessor(final SelectProcessor... selectProcessors) { + super(); + if (selectProcessors != null) { + final int l = selectProcessors.length; + this.selectProcessors = new SelectProcessor[l]; + System.arraycopy(selectProcessors, 0, this.selectProcessors, 0, l); + } else { + this.selectProcessors = new SelectProcessor[0]; + } + } + + public ImmutableSelectProcessor(final List selectProcessors) { + super(); + if (selectProcessors != null) { + final int l = selectProcessors.size(); + this.selectProcessors = selectProcessors.toArray(new SelectProcessor[l]); + } else { + this.selectProcessors = new SelectProcessor[0]; + } + } + + @Override + public void process(String value, String text) { + for (final SelectProcessor selectProcessor : this.selectProcessors) { + selectProcessor.process(value, text); + } + } + + @Override + public void put(String key) { + for (final SelectProcessor selectProcessor : this.selectProcessors) { + selectProcessor.put(key); + } + } + + @Override + public void putGlobalDict(Map globalDictVal) { + for (final SelectProcessor selectProcessor : this.selectProcessors) { + selectProcessor.putGlobalDict(globalDictVal); + } + } +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/JqgridSelectProcessor.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/JqgridSelectProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..f91ca1a8a591173d3b01f0dc6cfd71fc4cd3eb29 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/JqgridSelectProcessor.java @@ -0,0 +1,35 @@ +package org.nutz.plugins.dict.chain; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * jqgrid 处理 + * @author 邓华锋 http://dhf.ink + * + */ +public class JqgridSelectProcessor implements SelectProcessor { + public static Map jqgridSelectMap = new LinkedHashMap(); + private StringBuffer sb = new StringBuffer(); + + @Override + public void process(String value, String text) { + sb.append(value); + sb.append(":"); + sb.append(text); + sb.append(";"); + } + + @Override + public void put(String key) { + String row=sb.toString(); + row=row.substring(0, row.lastIndexOf(";")); + jqgridSelectMap.put(key, row); + sb = new StringBuffer(); + } + + @Override + public void putGlobalDict(Map globalDictVal) { + globalDictVal.put("jqgridSelect", jqgridSelectMap); + } +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessor.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..1b530368a65800c080bfb0d7bd34917298f1e83d --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessor.java @@ -0,0 +1,14 @@ +package org.nutz.plugins.dict.chain; + +import java.util.Map; + +/** + * select处理接口 + * @author 邓华锋 http://dhf.ink + * + */ +public interface SelectProcessor { + void process(String value,String text); + void put(String key); + void putGlobalDict(Map globalDictVal); +} diff --git a/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessorBuilder.java b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessorBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..a6322336d969543c92c227ede39dbefc7f62adc6 --- /dev/null +++ b/nutz-plugins-dict/src/main/java/org/nutz/plugins/dict/chain/SelectProcessorBuilder.java @@ -0,0 +1,69 @@ +package org.nutz.plugins.dict.chain; + +/** + * select处理构建类 + * @author 邓华锋 http://dhf.ink + * + */ +public class SelectProcessorBuilder { + private ChainBuilder selectChainBuilder; + + SelectProcessorBuilder() { + super(); + } + + public static SelectProcessorBuilder create() { + return new SelectProcessorBuilder(); + } + + public SelectProcessor build() { + return new ImmutableSelectProcessor(selectChainBuilder != null ? selectChainBuilder.build() : null); + } + + private ChainBuilder getSelectChainBuilder() { + if (selectChainBuilder == null) { + selectChainBuilder = new ChainBuilder(); + } + return selectChainBuilder; + } + + public SelectProcessorBuilder addFirst(final SelectProcessor e) { + if (e == null) { + return this; + } + getSelectChainBuilder().addFirst(e); + return this; + } + + public SelectProcessorBuilder addLast(final SelectProcessor e) { + if (e == null) { + return this; + } + getSelectChainBuilder().addLast(e); + return this; + } + + public SelectProcessorBuilder add(final SelectProcessor e) { + return addLast(e); + } + + public SelectProcessorBuilder addAllFirst(final SelectProcessor... e) { + if (e == null) { + return this; + } + getSelectChainBuilder().addAllFirst(e); + return this; + } + + public SelectProcessorBuilder addAllLast(final SelectProcessor... e) { + if (e == null) { + return this; + } + getSelectChainBuilder().addAllLast(e); + return this; + } + + public SelectProcessorBuilder addAll(final SelectProcessor... e) { + return addAllLast(e); + } +} diff --git a/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridGroupOP.java b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridGroupOP.java new file mode 100644 index 0000000000000000000000000000000000000000..26a354a270e024087302001d83e0994a1d454bfb --- /dev/null +++ b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridGroupOP.java @@ -0,0 +1,29 @@ +package org.nutz.plugins.dict; +import org.nutz.plugins.dict.Select; +import org.nutz.plugins.dict.Select.Fields; + +/** + * jqgrid分组操作 + * @author 邓华锋 http://dhf.ink + * + */ +@Select(value=Fields.NAME) +public enum JQGridGroupOP { + or("或者",0),and("并且",1); + private String text; + + private int value; + + private JQGridGroupOP(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } +} \ No newline at end of file diff --git a/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOper.java b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOper.java new file mode 100644 index 0000000000000000000000000000000000000000..98f69b2438ef9ad3eb0eaa20ea38489ebd280072 --- /dev/null +++ b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOper.java @@ -0,0 +1,26 @@ +package org.nutz.plugins.dict; +/** + * jqgrid按钮 + * @author 邓华锋 http://dhf.ink + */ +public enum JQGridOper { + edit("编辑",0),del("删除",1),add("增加",2); + + private String text; + + private int value; + + private JQGridOper(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } + +} diff --git a/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOrder.java b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..73ca39facbac9cf85dfd33793558f2e13d07b584 --- /dev/null +++ b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridOrder.java @@ -0,0 +1,28 @@ +package org.nutz.plugins.dict; +import org.nutz.plugins.dict.Select; +import org.nutz.plugins.dict.Select.Fields; + +/** + * jqgrid排序 + * @author 邓华锋 http://dhf.ink + */ +@Select(value=Fields.NAME) +public enum JQGridOrder { + asc("升序",0),desc("降序",1) ; + private String text; + + private int value; + + private JQGridOrder(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } +} \ No newline at end of file diff --git a/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridSelectOPT.java b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridSelectOPT.java new file mode 100644 index 0000000000000000000000000000000000000000..81790df6fff403f41415b940eae11f0336703b88 --- /dev/null +++ b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/JQGridSelectOPT.java @@ -0,0 +1,34 @@ +package org.nutz.plugins.dict; + +import org.nutz.plugins.dict.Select; + +/** + * JQGrid查询操作符 + * + * @author 邓华锋 http://dhf.ink + * + */ +@Select +public enum JQGridSelectOPT { + eq("等于","="),ne("不等于","<>"),bw("开始于","LIKE ${value}%"),bn("不开始于","NOT LIKE ${value}%"),ew("结束于","LIKE %${value}"),en("不结束于","NOT LIKE %${value}"), + cn("包含","LIKE"),nc("不包含","NOT LIKE"),nu("空值于","IS NULL"),nn("非空值","IS NOT NULL"),in("属于","IN"),ni("不属于","NOT IN"), + lt("小于","<"),le("小于等于","<="),gt("大于",">"),ge("大于等于",">="); + + private String text; + + private String value; + + private JQGridSelectOPT(String text, String value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public String value() { + return value; + } + +} \ No newline at end of file diff --git a/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/TestSelectBuilder.java b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/TestSelectBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..81c5cfe194a5d199108e6fa79340c6270f1764ba --- /dev/null +++ b/nutz-plugins-dict/src/test/java/org/nutz/plugins/dict/TestSelectBuilder.java @@ -0,0 +1,10 @@ +package org.nutz.plugins.dict; + +import org.nutz.plugins.dict.chain.EditableSelectProcessor; +import org.nutz.plugins.dict.chain.JqgridSelectProcessor; + +public class TestSelectBuilder { + public static void main(String[] args) { + Selects.custom().addProcessorFirst(new JqgridSelectProcessor()).addProcessorLast(new EditableSelectProcessor()).setPackages("org.nutz.plugins.dict").setJsonFilePath("e:/dict").build(); + } +} diff --git a/nutz-plugins-event/pom.xml b/nutz-plugins-event/pom.xml index 98a07b1fe3405ac0a9f77751391f50071add6ff1..09ee2dd23e7ba3556a048f809ca66b0a0ff04681 100644 --- a/nutz-plugins-event/pom.xml +++ b/nutz-plugins-event/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-event Simple, lightweight and fast event bus tailored for Nutz @@ -58,7 +58,7 @@ org.nutz nutz-integration-jedis - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT provided diff --git a/nutz-plugins-fiddler/pom.xml b/nutz-plugins-fiddler/pom.xml index 8c9a38ae3093c18c9340315431347c0ba5ab280d..3dadd3b4b7fc7f589a3eeb6450ff7090e45ca7e5 100644 --- a/nutz-plugins-fiddler/pom.xml +++ b/nutz-plugins-fiddler/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-fiddler https://nutzam.com diff --git a/nutz-plugins-hotplug/pom.xml b/nutz-plugins-hotplug/pom.xml index 6db304f6eed4fec006ab6d0afcb4c1a943f288ec..9b8de75c79f73a7619b02782bd2946b3c32752fe 100644 --- a/nutz-plugins-hotplug/pom.xml +++ b/nutz-plugins-hotplug/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-hotplug diff --git a/nutz-plugins-iocloader/README.md b/nutz-plugins-iocloader/README.md index 35e2ef7bd94904cbcdb08961e1edcbc112dd64b1..ecdc06d4d1dc61715d4e127d9523b5d37f611b0c 100644 --- a/nutz-plugins-iocloader/README.md +++ b/nutz-plugins-iocloader/README.md @@ -1,7 +1,57 @@ nutz-plugins-iocloader ================================== -简介(可用性:废弃,维护者:wendal) +简介(可用性:试用,维护者:wendal、[邓华锋](http://dhf.ink)) ================================== -演示自定义IocLoader的用法 \ No newline at end of file +演示自定义IocLoader的用法 + +新增功能点: +* 定时任务、线程环境下使用Ioc +* 通过配置comboIocLoader.properties文件来配置相关加载配置 +* 从数据库指定表中加载ioc配置 + +comboIocLoader.properties 配置 +```Shell +#也可配置项目的MainModule +ioc.main.module= +#ioc常规配置 +ioc.by=*js, ioc/dao.js, *anno, ink.dhf, org.nutz.integration.quartz,org.nutz.plugins.ioc.loader +#需要在ioc初始化后,单独调用的类以","分割 +ioc.loader.classes=org.nutz.integration.quartz.NutQuartzCronJobFactory,org.nutz.plugins.ioc.loader.TestIocBean1 +#ioc加载后初始化动作 前后顺序 用户可以自定义实现org.nutz.plugins.ioc.loader.chain.IocSetup 接口 类似于mvc环境下的org.nutz.mvc.Setup接口 只不过参数改成ioc +ioc.setup.first= +ioc.setup.last= +#ioc初始化后,后加入的IocLoader 以“,”分割 +ioc.combo.loader=org.nutz.plugins.ioc.loader.dao.DaoIocLoader +``` + + +定时任务、线程环境下使用Ioc方式 +```Java +System.out.println(ThreadIocLoader.getIoc().get(PropertiesProxy.class, "config").get("db.url")); +``` + +DaoIocLoader 默认是从当前ioc的dao实例的数据源中 t_iocbean 表 取出数据 bean的名称对应的字段名(默认是nm), + 配置对应在的字段名(默认是val). 现在可通过配置文件daoIocLoader.properties来配置。 + +```Shell +ioc.dao.name=dao +ioc.table=t_iocbean +ioc.name.field=nm +ioc.value.field=val +``` + + + 可在test里的db配置文件,指定数据库,创建默认的表字段,添加上测试数据,运行以上代码来进行测试,最终获取的是db配置文件里的db.url的值 + + + 以上的测试数据nm和val字段是: + + + config | { + type : "org.nutz.ioc.impl.PropertiesProxy", + fields : { + paths : [ "custom/" ] + } + } \ No newline at end of file diff --git a/nutz-plugins-iocloader/pom.xml b/nutz-plugins-iocloader/pom.xml index bcf466cd5db24567440560302f84f2bbd4ea6583..a27003631cf923484de6efb8c5b5433a2507abc8 100644 --- a/nutz-plugins-iocloader/pom.xml +++ b/nutz-plugins-iocloader/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-iocloader https://nutzam.com @@ -37,6 +37,12 @@ Bird.Wyatt@gmail.com https://github.com/juqkai + + denghuafeng + denghuafeng + denghuafeng@gmail.com + https://dhf.ink + scm:git:git://github.com/nutzam/nutzmore.git @@ -85,5 +91,30 @@ 2.5 provided + + com.alibaba + druid + 1.0.29 + test + + + mysql + mysql-connector-java + 5.1.41 + test + + + + nutzcn-snapshots + NutzCN snapshot repository + https://jfrog.nutz.cn/artifactory/snapshots + + + + sonatype-release-staging + Sonatype Nexus release repository + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + \ No newline at end of file diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/ThreadIocLoader.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/ThreadIocLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..4400dec1fdaa91bbfa066d69f35d943b565917f6 --- /dev/null +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/ThreadIocLoader.java @@ -0,0 +1,185 @@ +package org.nutz.plugins.ioc.loader; + +import java.util.List; + +import org.nutz.ioc.Ioc; +import org.nutz.ioc.IocLoader; +import org.nutz.ioc.impl.NutIoc; +import org.nutz.ioc.impl.PropertiesProxy; +import org.nutz.ioc.loader.combo.ComboIocLoader; +import org.nutz.lang.Strings; +import org.nutz.log.Log; +import org.nutz.log.Logs; +import org.nutz.mvc.Mvcs; +import org.nutz.mvc.annotation.IocBy; +import org.nutz.plugins.ioc.loader.chain.IocSetup; +import org.nutz.plugins.ioc.loader.chain.IocSetupBuilder; + +/** + * 定时任务、线程环境下ioc加载 + * + * @author 邓华锋 http://dhf.ink + * + */ +public final class ThreadIocLoader { + /** + * 持有Ioc容器,避免被GC, 及完成测试后需要关闭ioc容器 + */ + private static Ioc ioc; + private static final Log log = Logs.get(); + private static final String MAIN_MODULE = "ioc.main.module"; + private static final String IOC_BY = "ioc.by"; + private static final String LOADER_CLASSES = "ioc.loader.classes"; + private static final String SETUP_FIRST = "ioc.setup.first"; + private static final String SETUP_LAST = "ioc.setup.last"; + private static final String IOC_COMBO_LOADER = "ioc.combo.loader"; + private static final String PROPERTIES_NAME = "comboIocLoader.properties"; + private static final String SEPARATOR_CHAR = ","; + private static PropertiesProxy config; + private static IocSetup iocSetupCopy; + public static ComboIocLoader comboIocLoader; + + public static Ioc getMvcFilterIoc() { + if (ioc == null) { + // NutFilter作用域内,通常是请求线程内 + ioc = Mvcs.getIoc(); + log.info("<<<--- get Mvc Ioc --->>>"); + getNotMvcIoc(); + } + return ioc; + } + + public static Ioc getIoc() { + if (ioc == null) { + // 独立线程, 例如计划任务,定时任务的线程. + ioc = Mvcs.ctx().getDefaultIoc(); + log.info("<<<--- get Mvc Ioc --->>>"); + getNotMvcIoc(); + } + return ioc; + } + + private static Ioc getNotMvcIoc() { + synchronized (log) { + if (ioc == null) { + config = new PropertiesProxy(PROPERTIES_NAME); + try { + init(); + // 是为了不在同一包下,做的动作,进行重新加载 + List loaderClasses = config.getList(LOADER_CLASSES, SEPARATOR_CHAR); + for (String loaderClass : loaderClasses) { + ioc.get(Class.forName(loaderClass)); + } + log.info("<<<--- get Not Mvc Ioc --->>>"); + } catch (Exception e) { + log.error("ioc实例失败", e); + } + + } + } + return ioc; + } + + /** + * 初始化Ioc容器 + * + * @throws Exception + * 初始化过程出错的话抛错 + */ + public static void init() throws Exception { + ioc = new NutIoc(getIocLoader()); // 生成Ioc容器 + _init(); // 执行用户自定义初始化过程 + } + + /** + * 用户自定义初始化过程, 在ioc容器初始化完成后及本对象的属性注入完成后执行 + */ + public static void _init() throws Exception { + // 添加各种组合IocLoader + String iocComboLoader = config.get(IOC_COMBO_LOADER); + if (Strings.isNotBlank(iocComboLoader)) { + String[] iocComboLoaders = Strings.splitIgnoreBlank(iocComboLoader, SEPARATOR_CHAR); + for (String icl : iocComboLoaders) { + IocLoader loader = (IocLoader) Class.forName(icl).newInstance(); + comboIocLoader.addLoader(loader); + } + } + + // 添加执行链 + if (iocSetupCopy == null) { + final IocSetupBuilder b = IocSetupBuilder.create(); + String iocSetupFirstStr = config.get(SETUP_FIRST);// 从comboIocLoader配置文件中加载复合配置 + if (Strings.isNotBlank(iocSetupFirstStr)) { + String[] iocSetupFirsts = Strings.splitIgnoreBlank(iocSetupFirstStr, SEPARATOR_CHAR); + for (String isf : iocSetupFirsts) { + IocSetup is = (IocSetup) ioc.get(Class.forName(isf)); + b.addFirst(is); + } + } + + String iocSetupLastStr = config.get(SETUP_LAST);// 从comboIocLoader配置文件中加载复合配置 + if (Strings.isNotBlank(iocSetupLastStr)) { + String[] iocSetupLasts = Strings.splitIgnoreBlank(iocSetupLastStr, SEPARATOR_CHAR); + for (String isl : iocSetupLasts) { + IocSetup is = (IocSetup) ioc.get(Class.forName(isl)); + b.addLast(is); + } + } + iocSetupCopy = b.build(); + } + iocSetupCopy.init(ioc); + } + + /** + * 用户自定义销毁过程, 在ioc容器销毁前执行 + */ + public static void _depose() throws Exception { + iocSetupCopy.destroy(ioc); + } + + /** + * 获取IocLoader,默认是ComboIocLoader实例, 子类可以自定义 + */ + public static IocLoader getIocLoader() throws Exception { + comboIocLoader = new ComboIocLoader(getIocConfigure()); + return comboIocLoader; + } + + /** + * 子类可覆盖本方法,以配置项目的MainModule,可选项 + */ + public static Class getMainModule() throws Exception { + String mainModule = config.get(MAIN_MODULE); + if (Strings.isNotBlank(mainModule)) { + return Class.forName(config.get(MAIN_MODULE)); + } + return null; + } + + /** + * 子类可覆盖本方法,以配置项目的ioc配置,可选项 + */ + public static String[] getIocConfigure() throws Exception { + Class klass = getMainModule(); + String iocByStr = config.get(IOC_BY);// 从comboIocLoader配置文件中加载复合配置 + String[] iocBys = null; + if (Strings.isNotBlank(iocByStr)) { + iocBys = Strings.splitIgnoreBlank(iocByStr, SEPARATOR_CHAR); + } + if (klass == null) + return iocBys; + IocBy iocBy = klass.getAnnotation(IocBy.class); + if (iocBy == null) + return iocBys; + return iocBy.args(); + } + + public static void depose() throws Exception { + try { + _depose(); + } finally { + if (ioc != null) + ioc.depose(); + } + } +} diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ChainBuilder.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ChainBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..5cd24069b5e546354374deb0f6bc2f1698f4cc28 --- /dev/null +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ChainBuilder.java @@ -0,0 +1,96 @@ +package org.nutz.plugins.ioc.loader.chain; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +/** + * + * @author 邓华锋 http://dhf.ink + * + * @param + */ +final class ChainBuilder { + + private final LinkedList list; + private final Map, E> uniqueClasses; + + public ChainBuilder() { + this.list = new LinkedList(); + this.uniqueClasses = new HashMap, E>(); + } + + private void ensureUnique(final E e) { + final E previous = this.uniqueClasses.remove(e.getClass()); + if (previous != null) { + this.list.remove(previous); + } + this.uniqueClasses.put(e.getClass(), e); + } + + public ChainBuilder addFirst(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addFirst(e); + return this; + } + + public ChainBuilder addLast(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addLast(e); + return this; + } + + public ChainBuilder addAllFirst(final Collection c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + @SuppressWarnings("unchecked") + public ChainBuilder addAllFirst(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + public ChainBuilder addAllLast(final Collection c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + @SuppressWarnings("unchecked") + public ChainBuilder addAllLast(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + public LinkedList build() { + return new LinkedList(this.list); + } + +} diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ImmutableIocSetup.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ImmutableIocSetup.java new file mode 100644 index 0000000000000000000000000000000000000000..16f11e4877f231b48a8403674a476722928fd41a --- /dev/null +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/ImmutableIocSetup.java @@ -0,0 +1,44 @@ +package org.nutz.plugins.ioc.loader.chain; + +import java.util.List; + +import org.nutz.ioc.Ioc; + +public class ImmutableIocSetup implements IocSetup { + private final IocSetup[] IocSetups; + + public ImmutableIocSetup(final IocSetup... setups) { + super(); + if (setups != null) { + final int l = setups.length; + this.IocSetups = new IocSetup[l]; + System.arraycopy(setups, 0, this.IocSetups, 0, l); + } else { + this.IocSetups = new IocSetup[0]; + } + } + + public ImmutableIocSetup(final List setups) { + super(); + if (setups != null) { + final int l = setups.size(); + this.IocSetups = setups.toArray(new IocSetup[l]); + } else { + this.IocSetups = new IocSetup[0]; + } + } + + @Override + public void init(Ioc ioc) { + for (final IocSetup setup : this.IocSetups) { + setup.init(ioc); + } + } + + @Override + public void destroy(Ioc ioc) { + for (final IocSetup setup : this.IocSetups) { + setup.destroy(ioc); + } + } +} diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetup.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetup.java new file mode 100644 index 0000000000000000000000000000000000000000..a497af7afab4c27fa148b603687b5bd17ec61e81 --- /dev/null +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetup.java @@ -0,0 +1,23 @@ +package org.nutz.plugins.ioc.loader.chain; + +import org.nutz.ioc.Ioc; +/** + * Ioc启动接口 + * @author 邓华锋 http://dhf.ink + * + */ +public interface IocSetup { + /** + * 启动时,额外逻辑 + * + * @param nc 配置对象,包含Ioc等你需要的一切资源 + */ + void init(Ioc ioc); + + /** + * 关闭时,额外逻辑 + * + * @param nc 配置对象,包含Ioc等你需要的一切资源 + */ + void destroy(Ioc ioc); +} diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetupBuilder.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetupBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..c8fea3502b6fcb5eb154c794385a62050f81d16f --- /dev/null +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/chain/IocSetupBuilder.java @@ -0,0 +1,69 @@ +package org.nutz.plugins.ioc.loader.chain; + +/** + * + * @author 邓华锋 http://dhf.ink + * + */ +public class IocSetupBuilder { + private ChainBuilder setupChainBuilder; + + IocSetupBuilder() { + super(); + } + + public static IocSetupBuilder create() { + return new IocSetupBuilder(); + } + + public IocSetup build() { + return new ImmutableIocSetup(setupChainBuilder != null ? setupChainBuilder.build() : null); + } + + private ChainBuilder getIocSetupChainBuilder() { + if (setupChainBuilder == null) { + setupChainBuilder = new ChainBuilder(); + } + return setupChainBuilder; + } + + public IocSetupBuilder addFirst(final IocSetup e) { + if (e == null) { + return this; + } + getIocSetupChainBuilder().addFirst(e); + return this; + } + + public IocSetupBuilder addLast(final IocSetup e) { + if (e == null) { + return this; + } + getIocSetupChainBuilder().addLast(e); + return this; + } + + public IocSetupBuilder add(final IocSetup e) { + return addLast(e); + } + + public IocSetupBuilder addAllFirst(final IocSetup... e) { + if (e == null) { + return this; + } + getIocSetupChainBuilder().addAllFirst(e); + return this; + } + + public IocSetupBuilder addAllLast(final IocSetup... e) { + if (e == null) { + return this; + } + getIocSetupChainBuilder().addAllLast(e); + return this; + } + + public IocSetupBuilder addAll(final IocSetup... e) { + return addAllLast(e); + } +} diff --git a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/dao/DaoIocLoader.java b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/dao/DaoIocLoader.java index 5f1f198065b529cdbbfeaf00908c3b84f6477256..b0f13185bd9fcac37281b0725d971016b27830fe 100644 --- a/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/dao/DaoIocLoader.java +++ b/nutz-plugins-iocloader/src/main/java/org/nutz/plugins/ioc/loader/dao/DaoIocLoader.java @@ -8,11 +8,12 @@ import org.nutz.dao.Dao; import org.nutz.dao.entity.Record; import org.nutz.ioc.IocLoading; import org.nutz.ioc.ObjectLoadException; +import org.nutz.ioc.impl.PropertiesProxy; import org.nutz.ioc.loader.json.JsonLoader; import org.nutz.ioc.meta.IocObject; import org.nutz.json.Json; import org.nutz.lang.Lang; -import org.nutz.mvc.Mvcs; +import org.nutz.plugins.ioc.loader.ThreadIocLoader; /** *

从数据库加载ioc配置, 需要4个参数, @@ -24,16 +25,31 @@ import org.nutz.mvc.Mvcs; * select val from t_iocbean where nm="mqtt" * * @author wendal(wendal1985@gmail.com) - * + * @rewriter 邓华锋 http://dhf.ink */ public class DaoIocLoader extends JsonLoader { - + private static final String IOC_DAO_NAME="ioc.dao.name"; + private static final String IOC_TABLE="ioc.table"; + private static final String IOC_NAME_FIELD="ioc.name.field"; + private static final String IOC_VALUE_FIELD="ioc.value.field"; + private static final String PROPERTIES_NAME = "daoIocLoader.properties"; protected String name = "dao"; protected String table = "t_iocbean"; protected String nameField = "nm"; protected String valueField = "val"; + protected Dao dao; - public DaoIocLoader(String ... args) { + + public DaoIocLoader() { + super(); + PropertiesProxy config = new PropertiesProxy(PROPERTIES_NAME); + name=config.get(IOC_DAO_NAME, name); + table=config.get(IOC_TABLE, table); + nameField=config.get(IOC_NAME_FIELD, nameField); + valueField=config.get(IOC_VALUE_FIELD, valueField); + } + + public DaoIocLoader(String ... args) { if (args.length > 0) { name = args[0]; if (args.length > 1) { @@ -56,10 +72,10 @@ public class DaoIocLoader extends JsonLoader { throw new ObjectLoadException("Object '" + name + "' without define!"); Map map = Json.fromJsonAsMap(Object.class, re.getString(valueField)); try { - map.put(name, map); + getMap().put(name, map); return super.load(loading, name); } catch (Throwable e) { - map.remove(name); + getMap().remove(name); throw Lang.wrapThrow(e); } } @@ -80,8 +96,8 @@ public class DaoIocLoader extends JsonLoader { } protected Dao dao() { - if (dao == null) - dao = Mvcs.getIoc().get(Dao.class, name); + if (dao == null)//dao = Mvcs.getIoc().get(Dao.class, name); + dao = ThreadIocLoader.getIoc().get(Dao.class, name); return dao; } } diff --git a/nutz-plugins-iocloader/src/test/java/ink/dhf/TestIocBean.java b/nutz-plugins-iocloader/src/test/java/ink/dhf/TestIocBean.java new file mode 100644 index 0000000000000000000000000000000000000000..9d572cbb4add6bc80b1de8c2c2ce9435fdee67f3 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/java/ink/dhf/TestIocBean.java @@ -0,0 +1,8 @@ +package ink.dhf; + +import org.nutz.ioc.loader.annotation.IocBean; + +@IocBean +public class TestIocBean { + +} diff --git a/nutz-plugins-iocloader/src/test/java/org/nutz/integration/quartz/NutQuartzCronJobFactory.java b/nutz-plugins-iocloader/src/test/java/org/nutz/integration/quartz/NutQuartzCronJobFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..bbf918e0743fd9b791d221b60ceef61c93abfee4 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/java/org/nutz/integration/quartz/NutQuartzCronJobFactory.java @@ -0,0 +1,8 @@ +package org.nutz.integration.quartz; + +import org.nutz.ioc.loader.annotation.IocBean; + +@IocBean +public class NutQuartzCronJobFactory { + +} diff --git a/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestIocBean1.java b/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestIocBean1.java new file mode 100644 index 0000000000000000000000000000000000000000..ddd644afdfe49379caa4f203a6db49c8af84da06 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestIocBean1.java @@ -0,0 +1,8 @@ +package org.nutz.plugins.ioc.loader; + +import org.nutz.ioc.loader.annotation.IocBean; + +@IocBean +public class TestIocBean1 { + +} diff --git a/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestThreadIocLoader.java b/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestThreadIocLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..7bbadd560f4819357d9962ae6dfd9afe021b6024 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/java/org/nutz/plugins/ioc/loader/TestThreadIocLoader.java @@ -0,0 +1,12 @@ +package org.nutz.plugins.ioc.loader; + +import org.nutz.ioc.impl.PropertiesProxy; + +public class TestThreadIocLoader { + public static void main(String[] args) { + //ThreadIocLoader.getIoc(); + //IocLoader daoIocLoader=new DaoIocLoader("dao","t_iocbean","nm","val"); + //ThreadIocLoader.comboIocLoader.addLoader(daoIocLoader); + System.out.println(ThreadIocLoader.getIoc().get(PropertiesProxy.class, "config").get("db.url")); + } +} diff --git a/nutz-plugins-iocloader/src/test/resources/comboIocLoader.properties b/nutz-plugins-iocloader/src/test/resources/comboIocLoader.properties new file mode 100644 index 0000000000000000000000000000000000000000..5ac787a0062e60b0cf3955a0fc582909d767e873 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/resources/comboIocLoader.properties @@ -0,0 +1,8 @@ +ioc.main.module= +ioc.by=*js, ioc/dao.js, *anno, ink.dhf, org.nutz.integration.quartz,org.nutz.plugins.ioc.loader +# +ioc.loader.classes=org.nutz.integration.quartz.NutQuartzCronJobFactory,org.nutz.plugins.ioc.loader.TestIocBean1 +# +ioc.setup.first= +ioc.setup.last= +ioc.combo.loader=org.nutz.plugins.ioc.loader.dao.DaoIocLoader \ No newline at end of file diff --git a/nutz-plugins-iocloader/src/test/resources/custom/db.properties b/nutz-plugins-iocloader/src/test/resources/custom/db.properties new file mode 100644 index 0000000000000000000000000000000000000000..f69bcbcc068ff2d00402a1781666895d862d1007 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/resources/custom/db.properties @@ -0,0 +1,24 @@ +db.driverClassName=com.mysql.jdbc.Driver +db.validationQuery=SELECT 1 +db.defaultAutoCommit=false +db.maxWait=180000 +db.testWhileIdle=true +db.maxActive=1000 +db.filters=mergeStat +db.connectionProperties=druid.stat.slowSqlMillis=180000 +db.timeBetweenEvictionRunsMillis=3000 +db.minEvictableIdleTimeMillis=300000 +db.poolPreparedStatements=true +db.maxPoolPreparedStatementPerConnectionSize=20 +db.initialSize=1 +db.minIdle=1 +db.testWhileIdle=true; +db.testOnBorrow=false +db.testOnReturn=false +db.removeAbandoned=true +db.removeAbandonedTimeout=180 +db.logAbandoned=true +db.url=jdbc:mysql://localhost:3306/jqgrid?autoReconnect=true&autoReconnectForPools=true&maxReconnects=3&serverTimezone=CST&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&noAccessToProcedureBodies=true +db.username=root +db.password=root + diff --git a/nutz-plugins-iocloader/src/test/resources/daoIocLoader.properties b/nutz-plugins-iocloader/src/test/resources/daoIocLoader.properties new file mode 100644 index 0000000000000000000000000000000000000000..8e53054e1485d20b54ab27c03f7613fbf6fb83f3 --- /dev/null +++ b/nutz-plugins-iocloader/src/test/resources/daoIocLoader.properties @@ -0,0 +1,4 @@ +ioc.dao.name=dao +ioc.table=t_iocbean +ioc.name.field=nm +ioc.value.field=val \ No newline at end of file diff --git a/nutz-plugins-iocloader/src/test/resources/ioc/dao.js b/nutz-plugins-iocloader/src/test/resources/ioc/dao.js new file mode 100644 index 0000000000000000000000000000000000000000..78a401334b53c4ccfe82c141da5780dff3c4829c --- /dev/null +++ b/nutz-plugins-iocloader/src/test/resources/ioc/dao.js @@ -0,0 +1,91 @@ +var ioc = { + conf : { + type : "org.nutz.ioc.impl.PropertiesProxy", + fields : { + paths : [ "custom/" ] + } + }, + dataSource : { + type : "com.alibaba.druid.pool.DruidDataSource", + events : { + depose : 'close' + }, + fields : { + driverClassName : { + java : "$conf.get('db.driverClassName')" + }, + url : { + java : "$conf.get('db.url')" + }, + maxWait : { + java : "$conf.get('db.maxWait')" + }, + defaultAutoCommit : { + java : "$conf.get('db.defaultAutoCommit')" + }, + validationQuery : { + java : "$conf.get('db.validationQuery')" + }, + testWhileIdle : { + java : "$conf.get('db.testWhileIdle')" + }, + maxActive : { + java : "$conf.get('db.maxActive')" + }, + filters : { + java : "$conf.get('db.filters')" + }, + connectionProperties : { + java : "$conf.get('db.connectionProperties')" + }, + username : { + java : "$conf.get('db.username')" + }, + password : { + java : "$conf.get('db.password')" + }, + timeBetweenEvictionRunsMillis : { + java : "$conf.get('db.timeBetweenEvictionRunsMillis')" + }, + minEvictableIdleTimeMillis : { + java : "$conf.get('db.minEvictableIdleTimeMillis')" + }, + poolPreparedStatements : { + java : "$conf.get('db.poolPreparedStatements')" + }, + maxPoolPreparedStatementPerConnectionSize : { + java : "$conf.get('db.maxPoolPreparedStatementPerConnectionSize')" + }, + initialSize : { + java : "$conf.get('db.initialSize')" + }, + minIdle : { + java : "$conf.get('db.minIdle')" + }, + testWhileIdle : { + java : "$conf.get('db.testWhileIdle')" + }, + testOnBorrow : { + java : "$conf.get('db.testOnBorrow')" + }, + testOnReturn : { + java : "$conf.get('db.testOnReturn')" + }, + removeAbandoned : { + java : "$conf.get('db.removeAbandoned')" + }, + removeAbandonedTimeout : { + java : "$conf.get('db.removeAbandonedTimeout')" + }, + logAbandoned : { + java : "$conf.get('db.logAbandoned')" + }, + } + }, + dao : { + type : "org.nutz.dao.impl.NutDao", + args : [ { + refer : "dataSource" + } ] + } +}; \ No newline at end of file diff --git a/nutz-plugins-ip2region/pom.xml b/nutz-plugins-ip2region/pom.xml index 1b91dada70b0716e9b403a1801f0b842652a83fe..e1a3b4a44edab564d529950ff0187e8145172a12 100644 --- a/nutz-plugins-ip2region/pom.xml +++ b/nutz-plugins-ip2region/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-ip2region 稍微改造一下原版的java代码,https://github.com/lionsoul2014/ip2region diff --git a/nutz-plugins-jqgrid/README.md b/nutz-plugins-jqgrid/README.md new file mode 100644 index 0000000000000000000000000000000000000000..00e1bd508d9697dc31f6c91fc56aa7fe7712fae9 --- /dev/null +++ b/nutz-plugins-jqgrid/README.md @@ -0,0 +1,84 @@ +# nutz-plugins-jqgrid JQGrid dao层使用插件 + +简介(可用性:生产,维护者:邓华锋(http://dhf.ink)) +================================== + +前段jqGrid提交到后端通用处理方法:简单、易用 +示例IocBy配置 +---------------------------------------------- +```Java +@IocBy(type=ComboIocProvider.class, args={"*js", "ioc/","*anno", "ink.dhf","org.nutz.plugins.jqgrid"}) +``` + +前段jqGrid配置: +```javascript +jQuery(grid_selector).jqGrid({ + url:"${base}/user/bean/list",//${base}/user/tname/list + datatype: "json", + ......省略 + editurl: "${basePath}/user/oper",//nothing is saved +}); +``` + +```javascript +$('#btnSeach').on('click', function(e){ + //此处可以添加对查询数据的合法验证 + var userId = $("#btnUser").val(); + $(grid_selector).jqGrid('setGridParam',{ + datatype:'json', + postData:{'userId':userId}, + page:1 + }).trigger("reloadGrid"); +}); +``` +module使用示例: +```Java +@At("/user") +@IocBean +public class UserModule { + @Inject + JQGridService jQGridService; + + @At("/bean/list") + @Fail(">>:/index") + @Ok("json") + public JQGridResult beanList(Integer userId, @Param("..") JQGridPage jqGridPage) { + Cnd cnd = Cnd.where("1", "=", 1); + if(userId!=null&&userId>0) { + cnd.and("userId", "=", userId); + } + Dao dao = Mvcs.getIoc().get(Dao.class); + return jQGridService.query(jqGridPage, dao, cnd, "id", TestUser.class); + } + + + @At("/tname/list") + @Fail(">>:/index") + @Ok("json") + public JQGridResult tableNamelist(Integer userId, @Param("..") JQGridPage jqGridPage) { + Cnd cnd = Cnd.where("1", "=", 1); + if(userId!=null&&userId>0) { + cnd.and("userId", "=", userId); + } + Dao dao = Mvcs.getIoc().get(Dao.class); + return jQGridService.query(jqGridPage, "test_user", dao, cnd, "id"); + } + + + @At + @Ok("json") + public Object oper(@Param("..") final Map data, @Param("oper") String oper) { + if (StringUtils.equals(oper, JQGridOper.add.name())) { + //TODO add + return true; + }else if (StringUtils.equals(oper, JQGridOper.del.name())) { + //TODO delete + return true; + }else if(StringUtils.equals(oper, JQGridOper.edit.name())) { + //TODO update + return true; + } + return false; + } +} +``` diff --git a/nutz-plugins-jqgrid/pom.xml b/nutz-plugins-jqgrid/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d4d184fc1d796e2c64eab33053bb8fc7482e1f8b --- /dev/null +++ b/nutz-plugins-jqgrid/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + + org.nutz + nutzmore + 1.r.66-SNAPSHOT + + nutz-plugins-jqgrid + Nutz More jqgrid + + + 邓华锋 + 邓华锋 + denghuafeng@gmail.com + http://dhf.ink + + + + UTF-8 + + + + org.apache.commons + commons-lang3 + 3.5 + + + junit + junit + 4.12 + test + + + com.alibaba + druid + 1.0.29 + test + + + mysql + mysql-connector-java + 5.1.41 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + -parameters + + false + + + + org.apache.maven.plugins + maven-surefire-plugin + + once + -Dfile.encoding=UTF-8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + -Xdoclint:none + + + + + + + + nutzcn-snapshots + NutzCN snapshot repository + https://jfrog.nutz.cn/artifactory/snapshots + + + + sonatype-release-staging + Sonatype Nexus release repository + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridGroupOP.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridGroupOP.java new file mode 100644 index 0000000000000000000000000000000000000000..5d099ca2b94f3edb225f8da579c756ed35fba4fd --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridGroupOP.java @@ -0,0 +1,27 @@ +package org.nutz.plugins.jqgrid.dict; + +/** + * jqgrid分组操作 + * @author 邓华锋 http://dhf.ink + * + */ +//@Select(value=Fields.NAME) +public enum JQGridGroupOP { + or("或者",0),and("并且",1); + private String text; + + private int value; + + private JQGridGroupOP(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOper.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOper.java new file mode 100644 index 0000000000000000000000000000000000000000..153039c7bf6f01d877fe3fe8adb2e6a2b88faf65 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOper.java @@ -0,0 +1,26 @@ +package org.nutz.plugins.jqgrid.dict; +/** + * jqgrid按钮 + * @author 邓华锋 http://dhf.ink + */ +public enum JQGridOper { + edit("编辑",0),del("删除",1),add("增加",2); + + private String text; + + private int value; + + private JQGridOper(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } + +} diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOrder.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..f0ac4617f5712ba6fec47c3a93403bb5e9eefb90 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridOrder.java @@ -0,0 +1,26 @@ +package org.nutz.plugins.jqgrid.dict; + +/** + * jqgrid排序 + * @author 邓华锋 http://dhf.ink + */ +//@Select(value=Fields.NAME) +public enum JQGridOrder { + asc("升序",0),desc("降序",1) ; + private String text; + + private int value; + + private JQGridOrder(String text, int value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public int value() { + return value; + } +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridSelectOPT.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridSelectOPT.java new file mode 100644 index 0000000000000000000000000000000000000000..c7daa60476a2aa04031c1c861d2d70620b3989d1 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/dict/JQGridSelectOPT.java @@ -0,0 +1,32 @@ +package org.nutz.plugins.jqgrid.dict; + +/** + * JQGrid查询操作符 + * + * @author 邓华锋 http://dhf.ink + * + */ +//@Select +public enum JQGridSelectOPT { + eq("等于","="),ne("不等于","<>"),bw("开始于","LIKE ${value}%"),bn("不开始于","NOT LIKE ${value}%"),ew("结束于","LIKE %${value}"),en("不结束于","NOT LIKE %${value}"), + cn("包含","LIKE"),nc("不包含","NOT LIKE"),nu("空值于","IS NULL"),nn("非空值","IS NOT NULL"),in("属于","IN"),ni("不属于","NOT IN"), + lt("小于","<"),le("小于等于","<="),gt("大于",">"),ge("大于等于",">="); + + private String text; + + private String value; + + private JQGridSelectOPT(String text, String value) { + this.text = text; + this.value = value; + } + + public String text() { + return text; + } + + public String value() { + return value; + } + +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridFilter.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..3c5733d4e360c6dbfe0cd08675a23e18ee037167 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridFilter.java @@ -0,0 +1,35 @@ +package org.nutz.plugins.jqgrid.entity; +import java.io.Serializable; +import java.util.List; + +/** + * jqGrid过滤器 + * + * @author 邓华锋 + * @date 2016年6月27日 下午4:22:41 + * + */ +public class JQGridFilter implements Serializable{ + + private static final long serialVersionUID = 3777917034270668946L; + + private String groupOp; + + private List rules; + + public String getGroupOp() { + return groupOp; + } + + public void setGroupOp(String groupOp) { + this.groupOp = groupOp; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridPage.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridPage.java new file mode 100644 index 0000000000000000000000000000000000000000..517976e6abf7b264ad954db8546fff6b7981ff87 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridPage.java @@ -0,0 +1,126 @@ +package org.nutz.plugins.jqgrid.entity; +import java.io.Serializable; + + +/** + * JQGrid分页 + * + * @author 邓华锋 + * @date 2016年6月27日 下午3:43:11 + * + */ +public class JQGridPage implements Serializable{ + private static final long serialVersionUID = -6779387545446523955L; + + private boolean _search; + + private JQGridFilter filters; + + private String nd; + + /** + * 当前页码 + */ + private int page=1; + + /** + * 分页行数 + */ + private int rows=10; + + private String searchField; + + private String searchOper; + + private String searchString; + + /** + * 排序字段 + */ + private String sidx; + + /** + * 排序方式:1.asc 2.desc + */ + private String sord; + + public boolean is_search() { + return _search; + } + + public void set_search(boolean _search) { + this._search = _search; + } + + public JQGridFilter getFilters() { + return filters; + } + + public void setFilters(JQGridFilter filters) { + this.filters = filters; + } + + public String getNd() { + return nd; + } + + public void setNd(String nd) { + this.nd = nd; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getRows() { + return rows; + } + + public void setRows(int rows) { + this.rows = rows; + } + + public String getSearchField() { + return searchField; + } + + public void setSearchField(String searchField) { + this.searchField = searchField; + } + + public String getSearchOper() { + return searchOper; + } + + public void setSearchOper(String searchOper) { + this.searchOper = searchOper; + } + + public String getSearchString() { + return searchString; + } + + public void setSearchString(String searchString) { + this.searchString = searchString; + } + + public String getSidx() { + return sidx; + } + + public void setSidx(String sidx) { + this.sidx = sidx; + } + + public String getSord() { + return sord; + } + + public void setSord(String sord) { + this.sord = sord; + } +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridResult.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridResult.java new file mode 100644 index 0000000000000000000000000000000000000000..8c4e0d19a199f72dc20cbdcd0c24f9ffa54207ac --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridResult.java @@ -0,0 +1,74 @@ +package org.nutz.plugins.jqgrid.entity; +import java.io.Serializable; +import java.util.List; + +import org.nutz.dao.pager.Pager; +/** + * jqGrid返回的结果 + * + * @author 邓华锋 + * @date 2016年6月27日 下午4:22:19 + * + */ +public class JQGridResult implements Serializable{ + private static final long serialVersionUID = 5939846263450399192L; + + /** + * 页码 + */ + private int page; + + /** + * 总页数 + */ + private int total; + + /** + * 总行数 + */ + private int records; + + /** + * 当前页的数据 + */ + private List rows; + + public JQGridResult(Pager page,List rows) { + this.page=page.getPageNumber(); + this.total=page.getPageCount(); + this.records=page.getRecordCount(); + this.rows = rows; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getRecords() { + return records; + } + + public void setRecords(int records) { + this.records = records; + } + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } +} \ No newline at end of file diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridRule.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridRule.java new file mode 100644 index 0000000000000000000000000000000000000000..a52a6cc9ab3f6dd420e635213250a1973f2d4ead --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/entity/JQGridRule.java @@ -0,0 +1,44 @@ +package org.nutz.plugins.jqgrid.entity; +import java.io.Serializable; + + +/** + * jqGrid规则 + * + * @author 邓华锋 + * @date 2016年6月27日 下午4:21:21 + * + */ +public class JQGridRule implements Serializable{ + private static final long serialVersionUID = -2672331350537972005L; + + private String field; + + private String op; + + private String data; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getOp() { + return op; + } + + public void setOp(String op) { + this.op = op; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/JQGridService.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/JQGridService.java new file mode 100644 index 0000000000000000000000000000000000000000..c5b901f04b35459b29189b5a3a41597d77079c59 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/JQGridService.java @@ -0,0 +1,35 @@ +package org.nutz.plugins.jqgrid.service; + +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.plugins.jqgrid.entity.JQGridPage; +import org.nutz.plugins.jqgrid.entity.JQGridResult; + +/** + * JQGrid通用查询 + * @author 邓华锋 http://dhf.ink + * + */ +public interface JQGridService { + /** + * JQGrid通用查询 传class 返回class集合 + * @param jqGridPage + * @param dao + * @param cnd + * @param defaultOrderField + * @param clazz + * @return + */ + public JQGridResult query(JQGridPage jqGridPage, Dao dao, Cnd cnd, String defaultOrderField, Class clazz); + + /** + * JQGrid通用查询 传表名 返回Record集合 + * @param jqGridPage + * @param tableName + * @param dao + * @param cnd + * @param defaultOrderField + * @return + */ + public JQGridResult query(JQGridPage jqGridPage, String tableName,Dao dao, Cnd cnd, String defaultOrderField); +} diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/impl/JQGridServiceImpl.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/impl/JQGridServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..76d41c780312446dc368ae54fbfb09ccdb4dd0b7 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/service/impl/JQGridServiceImpl.java @@ -0,0 +1,150 @@ +package org.nutz.plugins.jqgrid.service.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.pager.Pager; +import org.nutz.dao.sql.Criteria; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.plugins.jqgrid.dict.JQGridGroupOP; +import org.nutz.plugins.jqgrid.dict.JQGridOrder; +import org.nutz.plugins.jqgrid.dict.JQGridSelectOPT; +import org.nutz.plugins.jqgrid.entity.JQGridPage; +import org.nutz.plugins.jqgrid.entity.JQGridResult; +import org.nutz.plugins.jqgrid.entity.JQGridRule; +import org.nutz.plugins.jqgrid.service.JQGridService; +import org.nutz.plugins.jqgrid.util.Args; + +/** + * 操作jqgrid service类 + * @author 邓华锋 http://dhf.ink + * + */ +@IocBean(name = "jQGridService") +public class JQGridServiceImpl implements JQGridService { + private static Map selectOPT = new HashMap(); + + static { + // 遍历JQGrid查询操作符枚举及对应的操作符,放入到静态变量中 + for (JQGridSelectOPT sopt : JQGridSelectOPT.values()) { + selectOPT.put(sopt.name(), sopt.value()); + } + } + + @Override + public JQGridResult query(JQGridPage jqGridPage, String tableName, Dao dao, Cnd cnd, String defaultOrderField) { + Args.notBlank(tableName, "tableName"); + return query(jqGridPage, tableName, dao, cnd, defaultOrderField, null); + } + + /** + * JQGrid通用查询 + * + * @param jqGridPage + * @param dao + * @param cnd + * @param defaultOrderField + * @param clazz + * @return + */ + public JQGridResult query(JQGridPage jqGridPage, Dao dao, Cnd cnd, String defaultOrderField, Class clazz) { + Args.notNull(clazz, "clazz"); + return query(jqGridPage, null,dao, cnd, defaultOrderField, clazz); + } + + private JQGridResult query(JQGridPage jqGridPage, String tableName, Dao dao, Cnd cnd, String defaultOrderField, + Class clazz) { + Args.notNull(jqGridPage, "jqGridPage"); + Args.notNull(dao, "dao"); + Args.notNull(cnd, "cnd"); + if (jqGridPage.getRows() < 1) + jqGridPage.setRows(10); + + Pager pager = dao.createPager(jqGridPage.getPage(), jqGridPage.getRows()); + // 创建一个 Criteria 接口实例 + Criteria cri = null; + if (cnd != null) { + cri = cnd.getCri(); + } else { + cri = Cnd.cri(); + } + + if (jqGridPage.is_search() && jqGridPage.getFilters() != null) { + String groupOp = jqGridPage.getFilters().getGroupOp().toLowerCase(); + List rules = jqGridPage.getFilters().getRules(); + if (rules != null && rules.size() > 0) { + if (Strings.equals(groupOp, JQGridGroupOP.and.name())) { + for (JQGridRule rule : rules) { + String opt = selectOPT.get(rule.getOp()); + String data = rule.getData(); + String field = rule.getField(); + opt = opt.toLowerCase(); + if (opt.startsWith("like")) { + String vd = opt.replace("like ", ""); + String vdata = vd.replace("${value}", data); + // data="%"+data+"%"; + // "%A%" + cri.where().andLike(field, vdata); + } else if (opt.equals("in")) { + cri.where().andIn(field, data); + } else if (opt.equals("not in")) { + cri.where().andNotIn(field, data); + } else { + cri.where().and(field, opt, data); + } + } + } else if (Strings.equals(groupOp, JQGridGroupOP.or.name())) { + for (JQGridRule rule : rules) { + String opt = selectOPT.get(rule.getOp()); + String data = rule.getData(); + String field = rule.getField(); + opt = opt.toLowerCase(); + if (opt.startsWith("like")) { + String vd = opt.replace("like ", ""); + String vdata = vd.replace("${value}", data); + // data="%"+data+"%"; + // "%A%" + cri.where().orLike(field, vdata); + } else if (opt.equals("in")) { + cri.where().orIn(field, data); + } else if (opt.equals("not in")) { + cri.where().orNotIn(field, data); + } else { + cri.where().or(field, opt, data); + } + } + } + } + } + + if (!Strings.isEmpty(jqGridPage.getSidx()) && !Strings.isEmpty(jqGridPage.getSord())) { + if (Strings.equals(jqGridPage.getSord(), JQGridOrder.asc.name())) { + cri.getOrderBy().asc(jqGridPage.getSidx()); + } else if (Strings.equals(jqGridPage.getSord(), JQGridOrder.desc.name())) { + cri.getOrderBy().desc(jqGridPage.getSidx()); + } + } else { + cri.getOrderBy().desc(defaultOrderField); + } + List list = null; + if (Strings.isBlank(tableName)) { + list = dao.query(clazz, cri, pager); + } else { + list = dao.query(tableName, cri, pager); + } + + if (pager != null) { + if (Strings.isBlank(tableName)) { + pager.setRecordCount(dao.count(clazz, cnd)); + } else { + pager.setRecordCount(dao.count(tableName, cnd)); + } + + } + return new JQGridResult(pager, list); + } +} diff --git a/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/util/Args.java b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/util/Args.java new file mode 100644 index 0000000000000000000000000000000000000000..2af4dfc0cd60d1b659edb29609fd67f15b2f4530 --- /dev/null +++ b/nutz-plugins-jqgrid/src/main/java/org/nutz/plugins/jqgrid/util/Args.java @@ -0,0 +1,109 @@ +package org.nutz.plugins.jqgrid.util; +import java.util.Collection; + +import org.apache.commons.lang3.StringUtils; +import org.nutz.lang.Strings; + +public class Args { + + public static void check(final boolean expression, final String message) { + if (!expression) { + throw new IllegalArgumentException(message); + } + } + + public static void check(final boolean expression, final String message, final Object... args) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, args)); + } + } + + public static void check(final boolean expression, final String message, final Object arg) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, arg)); + } + } + + public static T notNull(final T argument, final String name) { + if (argument == null) { + throw new IllegalArgumentException(name + " may not be null"); + } + return argument; + } + + public static T notEmpty(final T argument, final String name) { + if (argument == null) { + throw new IllegalArgumentException(name + " may not be null"); + } + if (Strings.isEmpty(argument)) { + throw new IllegalArgumentException(name + " may not be empty"); + } + return argument; + } + + public static T notBlank(final T argument, final String name) { + if (argument == null) { + throw new IllegalArgumentException(name + " may not be null"); + } + if (Strings.isBlank(argument)) { + throw new IllegalArgumentException(name + " may not be blank"); + } + return argument; + } + + public static T containsNoBlanks(final T argument, final String name) { + if (argument == null) { + throw new IllegalArgumentException(name + " may not be null"); + } + //StringUtils.isAnyBlank(arg0) + //TextUtils.containsBlanks(argument) + if (StringUtils.isAnyBlank(argument)) { + throw new IllegalArgumentException(name + " may not contain blanks"); + } + return argument; + } + + public static > T notEmpty(final T argument, final String name) { + if (argument == null) { + throw new IllegalArgumentException(name + " may not be null"); + } + if (argument.isEmpty()) { + throw new IllegalArgumentException(name + " may not be empty"); + } + return argument; + } + + public static int positive(final int n, final String name) { + if (n <= 0) { + throw new IllegalArgumentException(name + " may not be negative or zero"); + } + return n; + } + + public static long positive(final long n, final String name) { + if (n <= 0) { + throw new IllegalArgumentException(name + " may not be negative or zero"); + } + return n; + } + + public static int notNegative(final int n, final String name) { + if (n < 0) { + throw new IllegalArgumentException(name + " may not be negative"); + } + return n; + } + + public static long notNegative(final long n, final String name) { + if (n < 0) { + throw new IllegalArgumentException(name + " may not be negative"); + } + return n; + } + + /*Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + Args.notEmpty(cookies, "List of cookies"); + Args.notNull(cookie, "Cookie");*/ + +} \ No newline at end of file diff --git a/nutz-plugins-jsonrpc/pom.xml b/nutz-plugins-jsonrpc/pom.xml index 85f2815002b5251d3bdcc54608adeea2bb16819c..785f5b3c9d10f4277c66f167bc6b0811adf19949 100644 --- a/nutz-plugins-jsonrpc/pom.xml +++ b/nutz-plugins-jsonrpc/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-jsonrpc diff --git a/nutz-plugins-mock/pom.xml b/nutz-plugins-mock/pom.xml index 59cf8f3feabc95970af529dbbba26b53e0bc32e4..4f7257687df0fe70be315c84db907a493158b88b 100644 --- a/nutz-plugins-mock/pom.xml +++ b/nutz-plugins-mock/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-mock diff --git a/nutz-plugins-mock/src/main/java/org/nutz/mock/AbstractMvcTest.java b/nutz-plugins-mock/src/main/java/org/nutz/mock/AbstractMvcTest.java index ac934a13773edc88ba51f1725cc59179e7a066fd..ddf36838443ad4ccbaa54725656313816cfb96b1 100644 --- a/nutz-plugins-mock/src/main/java/org/nutz/mock/AbstractMvcTest.java +++ b/nutz-plugins-mock/src/main/java/org/nutz/mock/AbstractMvcTest.java @@ -40,10 +40,10 @@ public abstract class AbstractMvcTest extends NutIocTestBase { servlet = new NutServlet(); servlet.init(servletConfig); session = Mock.servlet.session(servletContext); - newreq(); nc = Mvcs.getNutConfig(); ioc = nc.getIoc(); injectSelfFields(); + newreq(); _before(); } diff --git a/nutz-plugins-mongodb/pom.xml b/nutz-plugins-mongodb/pom.xml index 628022f68d294e7c41ccbded922792425e9a54fa..da82336242d774b60775983230173566e5b6b5ea 100644 --- a/nutz-plugins-mongodb/pom.xml +++ b/nutz-plugins-mongodb/pom.xml @@ -125,6 +125,6 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT diff --git a/nutz-plugins-multiview/README.md b/nutz-plugins-multiview/README.md index d98976f0d6b334547eb77ce745ef76381a882a91..677e1f9ba02807b461bad9f1da0b03ec521f41f4 100644 --- a/nutz-plugins-multiview/README.md +++ b/nutz-plugins-multiview/README.md @@ -1,37 +1,35 @@ # nutz-plugins-multiview 多视图插件 -简介(可用性:生产,维护者:邓华锋(http://dhf.ink)) +简介(可用性:生产,维护者:[邓华锋](http://dhf.ink)) ================================== 集合N种模板引擎,可配置性强 ###### 适应nutz 1.r.55以上,以下版本暂时未测试 -#1.65版本更新日志: -###### 1.增加默认视图设置 -###### 2.增加配置视图扩展属性 -###### 3.增加全局属性文件的可配置功能 -#1.65之前版本更新日志: -###### 1.把所有属性配置文件里的变量及值加载到全局里,例如,在配置文件中配置了CDN地址,想在页面中能调用,默认全局变量是cfg变量,通过cfg调用相应的键值。 -###### 2.支持直接调用视图 AbstractTemplateViewResolver atvr=new org.nutz.plugins.view.JspView("abc.bcd"); -###### 3.代码重构,去除了AbstractUrlBasedView.java和ViewResolver -针对 -https://github.com/nutzam/nutz/issues/603#issuecomment-35709620 -上提出的问题,开发了此插件、 +针对 [nutz 没有可以配置视图前缀功能,即配置模板路径](https://github.com/nutzam/nutz/issues/603#issuecomment-35709620) 此问题,开发了此插件。
目的是用于开发博客社交类等程序,这些可能会经常要更换模板,路径写死在代码不合适。 -使用步骤: - - 1.引用nutz-plugins-multiview.jar插件及相关视图的引用包,在pom.xml里有注释引用。 - - 2.配置MainModule的视图为ResourceBundleViewResolver +开发此插件有啥优点了,所有配置都可以在配置文件中实现,而不用硬编码: +------------------------- +* 配置视图的路径 +* 配置视图扩展名 +* 配置默认视图 +* 配置默认内容类型 +* 配置字符编码 +* 其他扩展属性配置 +* 配置全局的属性文件 +* 可单独配置视图的属性文件 +* 支持session和application级别切换模板路径、后缀及引擎功能 +使用步骤: +------------------------- +* 引用nutz-plugins-multiview.jar插件及相关视图的引用包,在pom.xml里有注释引用。 +* 配置MainModule的视图为ResourceBundleViewResolver ```Java @Views({ResourceBundleViewResolver.class}) ``` - -3.配置json文件,创建view.js文件,内容如下: - +* 配置json文件,创建view.js文件,内容如下: ```javascript var ioc = { conf : {//默认约定的视图配置文件conf @@ -105,7 +103,69 @@ https://github.com/nutzam/nutz/issues/603#issuecomment-35709620 ``` 当然要创建对应配置的目录,上面beetl的configPath是指这个视图的配置文件目录,相对于项目根目录来说的,可配置或不配置,分情况而定。 -4.在module的方法里返回相应的视图,当然要创建相应的视图文件,如下: +* 在module中使用情况如下 + +默认视图使用示例 +------------------------- +```Java +@At("/user") +@IocBean +public class UserModule { + @At + @Ok("user.index") + public void index() { + + } + + @At + @Ok("user.info") + public void info() { + + } +} +``` +默认视图,将会走默认的视图,此例子中走beetl视图,因为上面view.js里配置了defaultView的值为 btl 即此视图的前缀标识。 +默认视图的好处是@Ok里不用再加“视图前缀:”来标识,直接通过配置文件就能改变视图模板引擎。 + +session和application切换视图示例 +------------------------- +```Java +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; + +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.Mvcs; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.plugins.view.MultiView; + +@IocBean +public class IndexModule { + @At("/session/change") + @Ok("index") + public void sessioinChange() { + HttpSession session = Mvcs.getHttpSession(); + session.setAttribute(MultiView.DEFAULT_VIEW, "ftl"); + session.setAttribute(MultiView.VIEW_PREFIX, "/templates/freemarker"); + session.setAttribute(MultiView.DEFAULT_SUFFIX, ".html"); + } + + /** + * + */ + @At("/application/change") + @Ok("index") + public void applicationChange() { + ServletContext application = Mvcs.getServletContext(); + application.setAttribute(MultiView.DEFAULT_VIEW, "jsp"); + application.setAttribute(MultiView.VIEW_PREFIX, "/templates/jsp"); + application.setAttribute(MultiView.DEFAULT_SUFFIX, ".jsp"); + } +} +``` + +其他视图使用 +------------------------- ```Java @At("/beetl") @@ -163,29 +223,20 @@ public class JspModule { 访问相应的链接,就会找到相应的视图, -默认的视图如果已经设置了的话,将会是配置@Ok情况: - -```Java -@At("/user") -@IocBean -public class UserModule { - @At - @Ok("user.index") - public void index() { +插件的核心类 +------------------------- +* ResourceBundleViewResolver 实现的MultiView接口 MultiView继承ViewMaker2,用于从 IOC 容器配置文件中查找视图。 +* AbstractTemplateViewResolver 抽象出通用的视图请求操作,填充全局变量,资源路径计算 +* MultiViewResover 主要用于注入多视图,设置默认视图,配置文件 +* MultiView MultiView继承ViewMaker2接口,主要在此接口里定义常量 - } - - @At - @Ok("user.info") - public void info() { +MultiViewResover灵活性 +------------------------- +view.js配置文件中,multiViewResover不再是约定的名称,只要定义 org.nutz.plugins.view.MultiViewResover类型,插件都能加载,可灵活定义多个MultiViewResover。 - } -} -``` -默认视图,将会走默认的视图,此例子中走beetl视图,因为上面view.js里配置了defaultView的值为 btl 即此视图的前缀标识。 -默认视图的好处是@Ok里不用再加“视图前缀:”来标识,直接通过配置文件就能改变视图模板引擎。 -注意的地方: +注意 +------------------------- 1.如果beetl.properties里设置了RESOURCE.root=WEB-INF ,则view.js配置的beetl视图的路径则在WEB-INF下面。例如 @@ -225,33 +276,9 @@ $loader.reloadable =false 既这时候的root路径不起作用。 - -开发此插件有啥优点了,所有配置都可以在配置文件中实现,而不用硬编码: - -1.配置视图的路径 - -2.配置视图扩展名 - -3.配置默认视图 - -4.配置默认内容类型 - -5.配置字符编码 - -6.其他扩展属性配置 - -7.配置全局的属性文件 - -8.可单独配置视图的属性文件 - - 插件中包含了对beetl、freemarker、JetTemplate和jsp的视图实现,其实把这些代码抽离出来,按需使用可让插件体积更小。 -插件的核心类,包括ResourceBundleViewResolver(接口 ViewMaker2的实现,用于从 IOC 容器配置文件中查找视图。)、 - -AbstractTemplateViewResolver、MultiViewResover和ViewResolver -view.js配置文件中,multiViewResover是约定的名称。 如果想添加别的视图,只需继承于AbstractTemplateViewResolver,实现init和render方法即可。
例如以下是在此插件下beetl模板视图的实现: @@ -313,27 +340,20 @@ public class BeetlView extends AbstractTemplateViewResolver { ```
注意上面的getConfigPath()方法的代码,是为了实现beetl放在公共的lib目录获取不到beetl配置文件的问题而补救的一个解决方案,configPath是父类AbstractTemplateViewResolver 的属性,可在ioc配置文件中配置。
init方法只执行一次,一般用于加载视图的配置相关的代码,且某些对象只需实例化一次,后面就不用实例化。 -
render方法的sharedVars是全局的变量,有这些: -
-path 项目根路径, - -完整的项目连接路径basePath, - -请求连接的后缀servletExtension, - -模板所在目录tplDir, - -资源根路径resPath, - -模板对应的资源路径tplResPath, - -当前系统java边聊props, - -国际语言mvcs, - -所有配置文件信息cfg, - -还有个viewName变量,用于显示使用的模板视图的名称。 +
render方法的sharedVars是全局的变量。 + +内置变量 +------------------------- +* path 项目根路径 +* 完整的项目连接路径basePath +* 请求连接的后缀servletExtension +* 模板所在目录tplDir +* 资源根路径resPath +* 模板对应的资源路径tplResPath +* 当前系统环境props +* 国际语言msgs +* 所有配置文件信息cfg +* 还有个viewName变量,用于显示使用的模板视图的名称。 这几个变量对于做博客论坛等经常更换模板的程序很有用。 @@ -372,6 +392,8 @@ vr.render(req, resp, evalPath, sv); } ``` +注意:以上方式已经废弃,不起作用,请使用以下新方式 + 新: ```javascript multiViewResover : { @@ -418,9 +440,22 @@ resource.dir 资源根路径 对应页面变量resPath,此路径可以设置为 # 功能改进计划: - ###### 1.支持全局变量的添加,例如,把一些字典的类加载到全局里,供页面调用。 - ###### 2.支持Ajax视图,此需要特殊处理。例如,前段Ajax请求,需要处理获取的数据、本次请求状态、提示信息等。 - ###### 3.增加对pdf、velocity、thymeleaf、captcha视图支持,增强Freemarker视图可配置性。 + +# 更新日志: +# 1.66版本: +###### 1.增加session和application级别切换模板路径、后缀及引擎功能 +###### 2.增加MultiViewResover获取方式的灵活性 +###### 3.去除约定的获取MultiViewResover和conf的方式 + +# 1.65版本: +###### 1.增加默认视图设置 +###### 2.增加配置视图扩展属性 +###### 3.增加全局属性文件的可配置功能 + +# 1.65之前版本: +###### 1.把所有属性配置文件里的变量及值加载到全局里,例如,在配置文件中配置了CDN地址,想在页面中能调用,默认全局变量是cfg变量,通过cfg调用相应的键值。 +###### 2.支持直接调用视图 AbstractTemplateViewResolver atvr=new org.nutz.plugins.view.JspView("abc.bcd"); +###### 3.代码重构,去除了AbstractUrlBasedView.java和ViewResolver diff --git a/nutz-plugins-multiview/pom.xml b/nutz-plugins-multiview/pom.xml index 38f0180cf1b13704e6b20cbe2ba2db339e0461c9..fa7aafbca6eadd547dbd52803ca03e407916b0bd 100644 --- a/nutz-plugins-multiview/pom.xml +++ b/nutz-plugins-multiview/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-multiview Nutz More multiView diff --git a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/AbstractTemplateViewResolver.java b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/AbstractTemplateViewResolver.java index eca720dac631fbf64313b0e66292a46b11561e0f..5bbc3acf0f07213435ba0ed42adaa98c5625eddf 100644 --- a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/AbstractTemplateViewResolver.java +++ b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/AbstractTemplateViewResolver.java @@ -6,6 +6,7 @@ import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.nutz.ioc.impl.PropertiesProxy; import org.nutz.lang.Files; @@ -24,30 +25,6 @@ import org.nutz.mvc.view.AbstractPathView; */ public abstract class AbstractTemplateViewResolver extends AbstractPathView { protected static final Log log = Logs.get(); - private static final String DEFAULT_ENCODING = "UTF-8"; - private static final String DEFAULT_CONTENT_TYPE = "text/html"; - private static final String DEFAULT_PREFIX = "/WEB-INF/template/"; - private static final String DEFAULT_SUFFIX = ".html"; - private static final String OBJ = "obj"; - private static final String REQUEST = "request"; - private static final String RESPONSE = "response"; - private static final String SESSION = "session"; - private static final String APPLICATION = "application"; - private static final String VIEW_NAME = "viewName"; - private static final String PATH = "path"; - private static final String BASE_PATH = "basePath"; - private static final String SERVLET_EXTENSION = "servletExtension"; - private static final String SERVLET_EXTENSION_KEY = "servlet.extension"; - private static final String TPL_DIR = "tplDir"; - private static final String RESOURCE_DIR = "resource.dir"; - private static final String RES_PATH = "resPath"; - private static final String TPL_RES_PATH = "tplResPath"; - private static final String WEB_INF = "WEB-INF/"; - private static final String PROPS = "props"; - private static final String MVCS = "mvcs"; - private static final String CFG = "cfg"; - private static final String EVAL_PATH = "evalPath"; - private static final String DEST = "dest"; private PropertiesProxy config; private String prefix; private String suffix; @@ -74,39 +51,61 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { try { if (obj != null && obj instanceof Map) { sourceMap = org.nutz.castor.Castors.me().castTo(obj, Map.class); - if (!sourceMap.containsKey(EVAL_PATH) || !sourceMap.containsKey(DEST)) {// 验证必要的key值 + if (!sourceMap.containsKey(MultiView.EVAL_PATH) || !sourceMap.containsKey(MultiView.DEST)) {// 验证必要的key值 sourceMap = null; } } - } catch (Exception e1) { - // e1.printStackTrace(); + } catch (Exception e) { + throw e; } + Map sv = new HashMap(); Object objOld = sourceMap == null ? obj : sourceMap.get("obj"); - sv.put(OBJ, objOld); - sv.put(REQUEST, req); - sv.put(RESPONSE, resp); - sv.put(SESSION, Mvcs.getHttpSession()); - sv.put(APPLICATION, Mvcs.getServletContext()); - sv.put(VIEW_NAME, this.getClass().getSimpleName()); - sv.put(PROPS, System.getProperties());// .get("java.version") - Map msgs = Mvcs.getMessages(req); - sv.put(MVCS, msgs); - sv.put(CFG, config); + sv.put(MultiView.OBJ, objOld); + sv.put(MultiView.REQUEST, req); + sv.put(MultiView.RESPONSE, resp); + HttpSession session = Mvcs.getHttpSession(); + sv.put(MultiView.SESSION, session); + ServletContext application = Mvcs.getServletContext(); + sv.put(MultiView.APPLICATION, application); + sv.put(MultiView.VIEW_NAME, this.getClass().getSimpleName()); + sv.put(MultiView.PROPS, System.getProperties());// .get("java.version") + sv.put(MultiView.MSGS, Mvcs.getMessages(req));// Map + sv.put(MultiView.CFG, config); + if (resp != null && Strings.isBlank(resp.getContentType()) && !Strings.isBlank(this.getContentType())) {// resp的contentType优先级高 resp.setContentType(this.getContentType() + "; charset=" + this.getCharacterEncoding());// 配置文件设置的contentType resp.setCharacterEncoding(this.getCharacterEncoding()); } - String evalPath = null; - if (sourceMap != null && sourceMap.get(DEST) != null && Strings.isBlank(evalPath)) { - sv.put(DEST, sourceMap.get(EVAL_PATH).toString()); - evalPath = sourceMap.get(EVAL_PATH).toString(); + if (sourceMap != null && sourceMap.get(MultiView.DEST) != null && Strings.isBlank(evalPath)) { + sv.put(MultiView.DEST, sourceMap.get(MultiView.EVAL_PATH).toString()); + evalPath = sourceMap.get(MultiView.EVAL_PATH).toString(); } else { evalPath = evalPath(req, obj); } String tplDir = this.getPrefix();// 模板路径 + // application级别 动态切换模板路径 + Object viewPrefix = application.getAttribute(MultiView.VIEW_PREFIX); + if (viewPrefix != null) { + tplDir = viewPrefix.toString(); + } + // session级别 动态切换模板路径 + viewPrefix = session.getAttribute(MultiView.VIEW_PREFIX); + if (viewPrefix != null) { + tplDir = viewPrefix.toString(); + } String ext = this.getSuffix();// 模板文件扩展名 + // application级别 动态切换模板路径 + Object viewSuffix = application.getAttribute(MultiView.VIEW_SUFFIX); + if (viewSuffix != null) { + ext = viewSuffix.toString(); + } + // session级别 动态切换模板后缀 + viewSuffix = session.getAttribute(MultiView.VIEW_SUFFIX); + if (viewSuffix != null) { + ext = viewSuffix.toString(); + } if (Strings.isBlank(tplDir)) { tplDir = ""; @@ -128,7 +127,7 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { String resDir = ""; if (config != null) { - resDir = config.get(RESOURCE_DIR); + resDir = config.get(MultiView.RESOURCE_DIR); } String path = req.getContextPath(); @@ -136,31 +135,31 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { int serverPort = req.getServerPort(); String basePath = req.getScheme() + "://" + req.getServerName() + (serverPort != 80 ? ":" + serverPort : "") + path + "/"; - sv.put(BASE_PATH, basePath); + sv.put(MultiView.BASE_PATH, basePath); } catch (Exception e) {// 为了测试,而try的,Mock没有ServerPort Scheme ServerName if (Strings.equals("Not implement yet!", e.getMessage())) { } } - sv.put(PATH, path); + sv.put(MultiView.PATH, path); String servletExtension = ""; if (config != null) { - servletExtension = config.get(SERVLET_EXTENSION_KEY); + servletExtension = config.get(MultiView.SERVLET_EXTENSION_KEY); } - sv.put(SERVLET_EXTENSION, servletExtension); - sv.put(TPL_DIR, tplDir); + sv.put(MultiView.SERVLET_EXTENSION, servletExtension); + sv.put(MultiView.TPL_DIR, tplDir); if (!resDir.startsWith("http")) {// 如果是http开头,说明是CDN静态地址 resDir = path + "/" + resDir; } - sv.put(RES_PATH, resDir);// 资源路径 - sv.put(TPL_RES_PATH, resDir + tplDir.replace(WEB_INF, "") + "/");// 模板对应的资源路径 + sv.put(MultiView.RES_PATH, resDir);// 资源路径 + sv.put(MultiView.TPL_RES_PATH, resDir + tplDir.replace(MultiView.WEB_INF, "") + "/");// 模板对应的资源路径 this.render(req, resp, evalPath, sv); } public String getPrefix() { if (Strings.isBlank(prefix)) { - return DEFAULT_PREFIX; + return MultiView.DEFAULT_PREFIX; } return prefix; } @@ -171,7 +170,7 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { public String getSuffix() { if (Strings.isBlank(suffix)) { - return DEFAULT_SUFFIX; + return MultiView.DEFAULT_SUFFIX; } return suffix; } @@ -182,7 +181,7 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { public String getContentType() { if (Strings.isBlank(contentType)) { - return DEFAULT_CONTENT_TYPE; + return MultiView.DEFAULT_CONTENT_TYPE; } return contentType; } @@ -225,7 +224,7 @@ public abstract class AbstractTemplateViewResolver extends AbstractPathView { public String getCharacterEncoding() { if (Strings.isBlank(this.characterEncoding)) { - return DEFAULT_ENCODING; + return MultiView.DEFAULT_ENCODING; } return this.characterEncoding; } diff --git a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/JetTemplateView.java b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/JetTemplateView.java index eed428383d66b3e1eb262531ec374900a76687cf..3832600283b0bc9695a4751449960362a3962794 100644 --- a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/JetTemplateView.java +++ b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/JetTemplateView.java @@ -18,24 +18,23 @@ import org.nutz.lang.Lang; /** * JetTemplate视图。 - * * @author 邓华锋(http://dhf.ink) * */ public class JetTemplateView extends AbstractTemplateViewResolver { private JetEngine engine; - + public JetTemplateView(String dest) { super(dest); } - public void init(String appRoot, ServletContext sc) { + public void init(String appRoot,ServletContext sc) { engine = JetWebEngine.create(sc); } @Override - public void render(HttpServletRequest req, HttpServletResponse resp, String evalPath, - Map sharedVars) throws Throwable { + public void render(HttpServletRequest req, HttpServletResponse resp, + String evalPath, Map sharedVars) throws Throwable { String charsetEncoding = engine.getConfig().getOutputEncoding().name(); resp.setCharacterEncoding(charsetEncoding); if (resp.getContentType() == null) { diff --git a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiView.java b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiView.java new file mode 100644 index 0000000000000000000000000000000000000000..5519c012210ff2b0c67e0019b9c6e09974b52370 --- /dev/null +++ b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiView.java @@ -0,0 +1,40 @@ +package org.nutz.plugins.view; + +import org.nutz.mvc.ViewMaker2; + +/** + * 多视图接口 继承ViewMaker2 常量定义在此 + * + * @author 邓华锋 http://dhf.ink + * + */ +public interface MultiView extends ViewMaker2 { + String VIEW_PREFIX = "viewPrefix"; + String VIEW_SUFFIX = "viewSuffix"; + String DEFAULT_ENCODING = "UTF-8"; + String DEFAULT_CONTENT_TYPE = "text/html"; + String DEFAULT_PREFIX = "/WEB-INF/template/"; + String DEFAULT_SUFFIX = ".html"; + String OBJ = "obj"; + String REQUEST = "request"; + String RESPONSE = "response"; + String SESSION = "session"; + String APPLICATION = "application"; + String VIEW_NAME = "viewName"; + String PATH = "path"; + String BASE_PATH = "basePath"; + String SERVLET_EXTENSION = "servletExtension"; + String SERVLET_EXTENSION_KEY = "servlet.extension"; + String TPL_DIR = "tplDir"; + String RESOURCE_DIR = "resource.dir"; + String RES_PATH = "resPath"; + String TPL_RES_PATH = "tplResPath"; + String WEB_INF = "WEB-INF/"; + String PROPS = "props"; + String MSGS = "msgs"; + String CFG = "cfg"; + String EVAL_PATH = "evalPath"; + String DEST = "dest"; + String INNER_VIEW_TYPE = "json|raw|re|void|http|redirect|forward|>>|->"; + String DEFAULT_VIEW = "defaultView"; +} diff --git a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiViewResover.java b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiViewResover.java index e00d75164701628742ab8aca4239e31cbff9e151..0ebd799885ccbd9fc0f6e302d0c54c96ab28bbef 100644 --- a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiViewResover.java +++ b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/MultiViewResover.java @@ -6,6 +6,7 @@ import org.nutz.ioc.impl.PropertiesProxy; /** * 用于注入的多视图 + * * @author 邓华锋(http://dhf.ink) * */ @@ -33,5 +34,5 @@ public class MultiViewResover { public PropertiesProxy getConfig() { return config; } - + } diff --git a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/ResourceBundleViewResolver.java b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/ResourceBundleViewResolver.java index 55eba3c762bc46be5c3bfd3837ea07fe07bf3d6f..41a6b78349648a263e161c9f21121ffac011de1f 100644 --- a/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/ResourceBundleViewResolver.java +++ b/nutz-plugins-multiview/src/main/java/org/nutz/plugins/view/ResourceBundleViewResolver.java @@ -4,18 +4,18 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.nutz.ioc.Ioc; -import org.nutz.ioc.IocException; import org.nutz.ioc.impl.PropertiesProxy; import org.nutz.lang.Strings; import org.nutz.mvc.ActionInfo; import org.nutz.mvc.Mvcs; import org.nutz.mvc.NutConfig; import org.nutz.mvc.View; -import org.nutz.mvc.ViewMaker2; import org.nutz.mvc.view.AbstractPathView; /** @@ -24,13 +24,11 @@ import org.nutz.mvc.view.AbstractPathView; * @author 邓华锋(http://dhf.ink) * */ -public class ResourceBundleViewResolver implements ViewMaker2 { - private static final String INNER_VIEW_TYPE = "json|raw|re|void|http|redirect|forward|>>|->"; - private static final String CONFIG = "conf"; - private static final String MULTI_VIEW_RESOVER = "multiViewResover"; +public class ResourceBundleViewResolver implements MultiView { private LinkedHashMap resolvers = new LinkedHashMap(); - private MultiViewResover multiViewResover; - private PropertiesProxy config; + private MultiViewResover[] multiViewResovers; + private PropertiesProxy config = new PropertiesProxy(); + private String defaultView; private String appRoot; private boolean inited; @@ -40,24 +38,33 @@ public class ResourceBundleViewResolver implements ViewMaker2 { synchronized (resolvers) { if (!inited) { if (ioc != null) { - try { - config = ioc.get(PropertiesProxy.class, CONFIG); - } catch (IocException e) { - throw e; + // 查找MultiViewResover类型的定义名称,进行映射配置 + String[] names = ioc.getNamesByType(MultiViewResover.class); + multiViewResovers = new MultiViewResover[names.length]; + for (int i = 0; i < names.length; i++) { + String name = names[i]; + MultiViewResover multiViewResover = ioc.get(MultiViewResover.class, name); + multiViewResovers[i] = multiViewResover; + if (multiViewResover != null) { + LinkedHashMap rs = multiViewResover + .getResolvers(); + if (rs == null || rs.size() == 0) { + continue; + } + resolvers.putAll(rs);// 叠加配置视图 + } + config.putAll(multiViewResover.getConfig());// 叠加配置文件 + // 设置默认视图 + if (Strings.isNotBlank(multiViewResover.getDefaultView())) { + defaultView = multiViewResover.getDefaultView(); + } } - multiViewResover = ioc.get(MultiViewResover.class, MULTI_VIEW_RESOVER); - } - - if (multiViewResover != null) { - resolvers = multiViewResover.getResolvers(); - } - if (resolvers == null || resolvers.size() == 0) { - return null; } inited = true; } } } + String reqPath = value; boolean containsInnerType = INNER_VIEW_TYPE.indexOf(type) > -1;// 有没有内置的视图参数 boolean containsResolversKey = resolvers.containsKey(type);// 在配置的目标视图里的前缀有没有 @@ -66,8 +73,8 @@ public class ResourceBundleViewResolver implements ViewMaker2 { if (isNoContains) { reqPath = type; // 设置默认视图 - if (Strings.isNotBlank(multiViewResover.getDefaultView())) { - viewType = multiViewResover.getDefaultView(); + if (Strings.isNotBlank(defaultView)) { + viewType = defaultView; } } final AbstractTemplateViewResolver vr = resolvers.get(viewType); @@ -76,13 +83,7 @@ public class ResourceBundleViewResolver implements ViewMaker2 { } // 设置全局配置文件 if (vr.getConfig() == null) { - // 优先自定义配置 - if (multiViewResover.getConfig() != null) { - vr.setConfig(multiViewResover.getConfig()); - } else {// 约定的配置conf - vr.setConfig(config); - } - + vr.setConfig(config); } if (Strings.isBlank(vr.getPrefix()) || Strings.isBlank(vr.getSuffix())) { @@ -102,26 +103,17 @@ public class ResourceBundleViewResolver implements ViewMaker2 { return new AbstractPathView(reqPath) { @Override public void render(HttpServletRequest req, HttpServletResponse resp, Object obj) throws Throwable { - Map sourceMap = new HashMap(); - sourceMap.put("obj", obj); - sourceMap.put("evalPath", this.evalPath(req, obj)); - sourceMap.put("dest", type); - vr.render(req, resp, sourceMap); + renderView(type, vr, req, resp, obj, this.evalPath(req, obj)); } }; } else { return new AbstractPathView(reqPath) { @Override public void render(HttpServletRequest req, HttpServletResponse resp, Object obj) throws Throwable { - Map sourceMap = new HashMap(); - sourceMap.put("obj", obj); - sourceMap.put("evalPath", this.evalPath(req, obj)); - sourceMap.put("dest", value); - vr.render(req, resp, sourceMap); + renderView(value, vr, req, resp, obj, this.evalPath(req, obj)); } }; } - } @Override @@ -129,4 +121,28 @@ public class ResourceBundleViewResolver implements ViewMaker2 { appRoot = conf.getAppRoot(); return make(conf.getIoc(), type, value); } + + private void setDefaultView(String defaultView) { + this.defaultView = defaultView; + } + + private void renderView(final String dest, final AbstractTemplateViewResolver vr, HttpServletRequest req, + HttpServletResponse resp, Object obj, String evalPath) throws Throwable { + ServletContext application = Mvcs.getServletContext(); + // application级别 动态切换模板引擎 + if (application.getAttribute(DEFAULT_VIEW) != null) { + setDefaultView(application.getAttribute(DEFAULT_VIEW).toString()); + } + HttpSession session = Mvcs.getHttpSession(); + // session级别 动态切换模板引擎 + if (session.getAttribute(DEFAULT_VIEW) != null) { + setDefaultView(session.getAttribute(DEFAULT_VIEW).toString()); + } + Map sourceMap = new HashMap(); + sourceMap.put(OBJ, obj); + sourceMap.put(EVAL_PATH, evalPath); + sourceMap.put(DEST, dest); + vr.render(req, resp, sourceMap); + } + } diff --git a/nutz-plugins-ngrok/pom.xml b/nutz-plugins-ngrok/pom.xml index 88a688731d8644dfadbeded11ade834435643f64..0c26210b0ff4a73293f9bd629adffb97c2c236c3 100644 --- a/nutz-plugins-ngrok/pom.xml +++ b/nutz-plugins-ngrok/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-ngrok @@ -45,7 +45,7 @@ org.nutz nutz-integration-jedis - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT io.netty @@ -55,7 +55,7 @@ org.nutz nutz-web - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT provided diff --git a/nutz-plugins-nop/demo/nop-demo/pom.xml b/nutz-plugins-nop/demo/nop-demo/pom.xml index d6274ec40208737905facf9288827ef185887ed4..618353322fb838413b3060d8354b01ea9a53d58a 100644 --- a/nutz-plugins-nop/demo/nop-demo/pom.xml +++ b/nutz-plugins-nop/demo/nop-demo/pom.xml @@ -22,7 +22,7 @@ org.nutz nutz-plugins-nop - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT log4j @@ -39,7 +39,7 @@ org.nutz nutz-plugins-apidoc - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT diff --git a/nutz-plugins-nop/pom.xml b/nutz-plugins-nop/pom.xml index 2a3ea6fe9ed62ec84ae380404dc8ebd2140892d3..924f600b75364fb411bd1123cae08020caed3add 100644 --- a/nutz-plugins-nop/pom.xml +++ b/nutz-plugins-nop/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-nop diff --git a/nutz-plugins-oauth2-server/pom.xml b/nutz-plugins-oauth2-server/pom.xml index 709c8184c4593e7f08e8cdb5b56095507d358cc6..bc4d111fd9501832afddb6d450c9a29d5548eaab 100644 --- a/nutz-plugins-oauth2-server/pom.xml +++ b/nutz-plugins-oauth2-server/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.nutz oauth2-server - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT war nutz-plugins-oauth2-server http://maven.apache.org diff --git a/nutz-plugins-profiler/pom.xml b/nutz-plugins-profiler/pom.xml index d0b13abf5456ae917684feeedf23c2c39950e335..c55e7133d78ea6d696d4c7f7a889d5c47136e668 100644 --- a/nutz-plugins-profiler/pom.xml +++ b/nutz-plugins-profiler/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-profiler diff --git a/nutz-plugins-protobuf/pom.xml b/nutz-plugins-protobuf/pom.xml index e74854af8f451c38c2e93b1de3f323c5f6197ba3..47956867a589adbb95c838b0dc7f7566e7222e95 100644 --- a/nutz-plugins-protobuf/pom.xml +++ b/nutz-plugins-protobuf/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-protobuf nutz-plugins-protobuf diff --git a/nutz-plugins-qrcode/pom.xml b/nutz-plugins-qrcode/pom.xml index 643d34f07798fb7d908dcf8cfafe24d2174c0d8e..90af98b16bac27806a23371d994ce735de950cd3 100644 --- a/nutz-plugins-qrcode/pom.xml +++ b/nutz-plugins-qrcode/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-qrcode https://nutzam.com diff --git a/nutz-plugins-secken/pom.xml b/nutz-plugins-secken/pom.xml index e60ef870323c3377b9d597a91d3100b41bdf9ebc..2e1cb0ffbf93ee7740cb1a3969440fe384a49855 100644 --- a/nutz-plugins-secken/pom.xml +++ b/nutz-plugins-secken/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-secken diff --git a/nutz-plugins-sfntly/pom.xml b/nutz-plugins-sfntly/pom.xml index 048e7368d9ca90cd20ebe745bf21aa675395f3df..e085b2f529888a3a6b673da22a26c37189a8aa22 100644 --- a/nutz-plugins-sfntly/pom.xml +++ b/nutz-plugins-sfntly/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-sfntly diff --git a/nutz-plugins-sigar/pom.xml b/nutz-plugins-sigar/pom.xml index 83d13d5e7e80c0ffbb5539355a800f9cb1d27178..3e2cc833be2fb6db0bae403f64eb3a248ac18d51 100644 --- a/nutz-plugins-sigar/pom.xml +++ b/nutz-plugins-sigar/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-sigar Nutz Sigar diff --git a/nutz-plugins-slog/pom.xml b/nutz-plugins-slog/pom.xml index 9dbc21b19548cd3818442245f1714aab97a8093d..5d9bd5cc7bb99cfdb21dfc78daa8adc6363ad5d2 100644 --- a/nutz-plugins-slog/pom.xml +++ b/nutz-plugins-slog/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-slog diff --git a/nutz-plugins-spring-boot-starter/demo/pom.xml b/nutz-plugins-spring-boot-starter/demo/pom.xml index ca6dab13c45d50269abad7ee0356b178a3116a34..1bfa2f6e1db5c7f6671d2f8d7bff7b799fcb1e68 100644 --- a/nutz-plugins-spring-boot-starter/demo/pom.xml +++ b/nutz-plugins-spring-boot-starter/demo/pom.xml @@ -75,7 +75,7 @@ org.nutz nutz-plugins-spring-boot-starter - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT club.zhcs diff --git a/nutz-plugins-spring-boot-starter/pom.xml b/nutz-plugins-spring-boot-starter/pom.xml index 29b1541a563d539d34ec6185c46e7cc6178f3501..25c1c86de0c0b39ff78e71104ec58ffebcf81640 100644 --- a/nutz-plugins-spring-boot-starter/pom.xml +++ b/nutz-plugins-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-spring-boot-starter diff --git a/nutz-plugins-sqlmanager/pom.xml b/nutz-plugins-sqlmanager/pom.xml index 322d7ea4af90184c899a4c8a517fcdf19af081f6..57178fb353ac80294bc9c91ffcfd9c9150576719 100644 --- a/nutz-plugins-sqlmanager/pom.xml +++ b/nutz-plugins-sqlmanager/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-sqlmanager https://nutzam.com diff --git a/nutz-plugins-sqltpl/pom.xml b/nutz-plugins-sqltpl/pom.xml index 7fd27cb4c610e4b37193808fd4d5fec88b33eefe..09be2724c041198f5a9db04db8a42df12e51638b 100644 --- a/nutz-plugins-sqltpl/pom.xml +++ b/nutz-plugins-sqltpl/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-sqltpl diff --git a/nutz-plugins-thrift-netty/demo/thrift-netty-demo/pom.xml b/nutz-plugins-thrift-netty/demo/thrift-netty-demo/pom.xml index 9710316ccd82c79a6bf2e9ff516fd70e50db81f5..e487cbd1a49f5eb78302706f25bdad5dcd8796a2 100644 --- a/nutz-plugins-thrift-netty/demo/thrift-netty-demo/pom.xml +++ b/nutz-plugins-thrift-netty/demo/thrift-netty-demo/pom.xml @@ -97,7 +97,7 @@ org.nutz nutz-plugins-thrift-netty - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT log4j diff --git a/nutz-plugins-thrift-netty/pom.xml b/nutz-plugins-thrift-netty/pom.xml index 7753ba1b07118e868edbd8d431e528453cb1ea23..7a115965a116d8bba50ec06ed43f94b68d96d0d6 100644 --- a/nutz-plugins-thrift-netty/pom.xml +++ b/nutz-plugins-thrift-netty/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-thrift-netty Nutz Thrift diff --git a/nutz-plugins-undertow/pom.xml b/nutz-plugins-undertow/pom.xml index ec9de3ad99f794f519a1ef35680e854bee981b79..62b9850f3c3965fc2f0e2b328a23ed3a826c049b 100644 --- a/nutz-plugins-undertow/pom.xml +++ b/nutz-plugins-undertow/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-undertow Simple, lightweight embed web server for Nutz diff --git a/nutz-plugins-validation/pom.xml b/nutz-plugins-validation/pom.xml index b363823c0c8f590060fca7f3654e9e2b97ecbcea..a4e4cc9b8e36664250fdd8d7a62b87279fd1de00 100644 --- a/nutz-plugins-validation/pom.xml +++ b/nutz-plugins-validation/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-validation https://nutzam.com diff --git a/nutz-plugins-views/pom.xml b/nutz-plugins-views/pom.xml index c41b77fde89b730330276be4e7a4262df28cec9e..d676eefae19c5b07175668907df5f176d00b05d5 100644 --- a/nutz-plugins-views/pom.xml +++ b/nutz-plugins-views/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-views Nutz More Views diff --git a/nutz-plugins-webqq/pom.xml b/nutz-plugins-webqq/pom.xml index 7522400866c896ef3bba6fa738e7684fe000b5d6..777a568df996a1161a632d9a3daca190f1e2928a 100644 --- a/nutz-plugins-webqq/pom.xml +++ b/nutz-plugins-webqq/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-webqq diff --git a/nutz-plugins-websocket/README.md b/nutz-plugins-websocket/README.md index e09cf4da88bfdd13f62092e7337f562ef9bd6171..45f3b26a0645e6655bad35d76900772e913a4aad 100644 --- a/nutz-plugins-websocket/README.md +++ b/nutz-plugins-websocket/README.md @@ -64,6 +64,8 @@ public class MyWebsocket extends AbstractWsEndpoint { } ``` +**特别提醒: 已知限制, Endpoint类不能使用@Aop或者aop相关的注解(如@Async/@SLog)** + ### 页面端js示例 假设是jsp页面, 其中的base是项目的Context Path, home是房间的名称 diff --git a/nutz-plugins-websocket/pom.xml b/nutz-plugins-websocket/pom.xml index 29e117488df974e344ebe82f9cd1c48fcdadff90..ad56edec655ae0d780e851d48db1be05250d1f24 100644 --- a/nutz-plugins-websocket/pom.xml +++ b/nutz-plugins-websocket/pom.xml @@ -3,7 +3,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-websocket https://nutzam.com @@ -113,7 +113,7 @@ org.nutz nutz-integration-jedis - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT provided diff --git a/nutz-plugins-wkcache/pom.xml b/nutz-plugins-wkcache/pom.xml index ed22ea68ef66c7ef24809990d58d7432da1d5e73..0f45036cce283f2c3447afd496e41a39d9c6a65c 100644 --- a/nutz-plugins-wkcache/pom.xml +++ b/nutz-plugins-wkcache/pom.xml @@ -5,7 +5,7 @@ nutzmore org.nutz - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT 4.0.0 @@ -15,7 +15,7 @@ org.nutz nutz-integration-jedis - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT redis.clients diff --git a/nutz-plugins-xmlentitymaker/pom.xml b/nutz-plugins-xmlentitymaker/pom.xml index 4da67002e6845ebd5c18550c7faac5c1490685c2..34657579acb93a0501ada5dd90de3510d162cc7e 100644 --- a/nutz-plugins-xmlentitymaker/pom.xml +++ b/nutz-plugins-xmlentitymaker/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-xmlentitymaker https://nutzam.com diff --git a/nutz-plugins-zcron/pom.xml b/nutz-plugins-zcron/pom.xml index 3da00d1a5d2f75afd4f698b45d1eb6a2155637e6..23b9ffe935cf294c2ff65af23f0adecdce8177ac 100644 --- a/nutz-plugins-zcron/pom.xml +++ b/nutz-plugins-zcron/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-zcron diff --git a/nutz-plugins-zdoc/pom.xml b/nutz-plugins-zdoc/pom.xml index d66c873eb6d9543fb9f841a462404ee0540f205e..eb5ae2f2dc74435da64cad89686edd80b8777d94 100644 --- a/nutz-plugins-zdoc/pom.xml +++ b/nutz-plugins-zdoc/pom.xml @@ -4,7 +4,7 @@ org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutz-plugins-zdoc diff --git a/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MarkdownDocParser.java b/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MarkdownDocParser.java index a320dfff8ff2b98ac379943765aa60da7f8c7ecc..1f9767201359e7b65c9d926fd57e0f7bb9851af6 100644 --- a/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MarkdownDocParser.java +++ b/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MarkdownDocParser.java @@ -32,10 +32,20 @@ public class MarkdownDocParser implements NutDocParser { // 定义内容输出函数 private void __B_to_html(Tag tag, MdBlock B) { boolean isFirstLine = true; + + // 处理任务列表 + if (B.isTask) { + Tag jInput = tag.add("input").attr("disabled", "true").attr("type", "checkbox"); + if (B.isChecked) { + jInput.attr("checked", "true"); + } + } + + // 收集一下块内标签 NutMap tagNames = new NutMap(); for (String line : B.content) { // 忽略空行 - if(Strings.isBlank(line)) + if (Strings.isBlank(line)) continue; // 首行 if (isFirstLine) { @@ -52,6 +62,10 @@ public class MarkdownDocParser implements NutDocParser { if (tagNames.size() == 1 && tagNames.getBoolean("img")) { tag.attr("md-img-only", "yes"); } + // 标识一下任务列表 + if (B.isTask) { + tag.attrs(".md-task-list-item"); + } } private void __line_to_html(Tag tag, String str, NutMap tagNames) { @@ -61,7 +75,9 @@ public class MarkdownDocParser implements NutDocParser { + "|(~~([^~]+)~~)" + "|(`([^`]+)`)" + "|(!\\[([^\\]]*)\\]\\(([^\\)]+)\\))" - + "|(\\[([^\\]]*)\\]\\(([^\\)]*)\\))" + + "|(\\[(" + + "(!\\[([^\\]]*)\\]\\(([^\\)]+)\\))|([^\\]]*)" + + ")\\]\\(([^\\)]*)\\))" + "|(https?:\\/\\/[^ ]+)"; Pattern REG = Pattern.compile(reg); Matcher m = REG.matcher(str); @@ -130,7 +146,10 @@ public class MarkdownDocParser implements NutDocParser { } // IMG: ![](xxxx) else if (null != m.group(11)) { - tag.add("img").attr("title", m.group(12)).attr("src", m.group(13)); + Tag img = tag.add("img").attr("src", m.group(13)); + if (!Strings.isBlank(m.group(12))) { + img.attr("alt", m.group(12)); + } // 记录标签 if (null != tagNames) tagNames.put("img", true); @@ -138,28 +157,42 @@ public class MarkdownDocParser implements NutDocParser { // A: [](xxxx) else if (null != m.group(14)) { // 得到超链 - String href = m.group(16); + String href = m.group(20); if (null != href && href.endsWith(".md")) { href = Files.renameSuffix(href, ".html"); } - // 得到文字 - String text = Strings.sBlank(m.group(15), Files.getMajorName(href)); - // 锚点 - if (Strings.isBlank(href) && text.matches("^#.+$")) { - tag.add("a").attr("name", text.substring(1)); + // 如果内部是一个图片 + if (!Strings.isBlank(m.group(16))) { + String src = m.group(18); + Tag img = tag.add("a").attr("href", href).add("img").attr("src", src); + if (!Strings.isBlank(m.group(17))) { + img.attr("alt", m.group(17)); + } + // 记录标签 + if (null != tagNames) { + tagNames.put("img", true); + } } - // 链接 + // 得到文字 else { - Tag a = tag.add("a").attr("href", href); - this.__line_to_html(a, text, tagNames); + String text = Strings.sBlank(m.group(19), Files.getMajorName(href)); + // 锚点 + if (Strings.isBlank(href) && text.matches("^#.+$")) { + tag.add("a").attr("name", text.substring(1)); + } + // 链接 + else { + Tag a = tag.add("a").attr("href", href); + this.__line_to_html(a, text, tagNames); + } } // 记录标签 if (null != tagNames) tagNames.put("a", true); } // A: http://xxxx - else if (null != m.group(17)) { - tag.add("a").attr("href", m.group(17)).setText(Strings.sBlank(m.group(17))); + else if (null != m.group(21)) { + tag.add("a").attr("href", m.group(21)).setText(Strings.sBlank(m.group(21))); // 记录标签 if (null != tagNames) tagNames.put("a", true); @@ -188,8 +221,28 @@ public class MarkdownDocParser implements NutDocParser { this.index--; } + private static final Pattern _P2 = Pattern.compile("^[ \t]*(\\[[xX ]\\])[ ](.+)$"); + + // 处理一下第一行,判断支持一下 task list + private MdBlock __B_test_task(MdBlock B) { + if (null != B.content && B.content.size() > 0) { + String line0 = B.content.get(0); + Matcher m2 = _P2.matcher(line0); + if (m2.find()) { + B.isTask = true; + B.isChecked = "[ ]".equals(m2.group(1)); + B.content.set(0, m2.group(2)); + } + } + return B; + }; + private void __B_to_list(Tag tag, MdBlock B) { + __B_test_task(B); Tag tList = tag.add(B.type.toLowerCase()); + if (B.isTask) { + tList.attrs(".md-task-list"); + } Tag tLi = tList.add("li"); this.__B_to_html(tLi, B); // 循环查找后续的列表项,或者是嵌套 @@ -198,6 +251,7 @@ public class MarkdownDocParser implements NutDocParser { // 继续增加 if (B.type == B2.type && B2.level == B.level) { tLi = tList.add("li"); + __B_test_task(B2); this.__B_to_html(tLi, B2); } // 嵌套 diff --git a/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MdBlock.java b/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MdBlock.java index ab93ddfaffa85835f677fac16ad8efbf8914a6e3..1023748531b2cec75224e72708e1d827dab534f4 100644 --- a/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MdBlock.java +++ b/nutz-plugins-zdoc/src/main/java/org/nutz/plugins/zdoc/markdown/MdBlock.java @@ -16,6 +16,10 @@ class MdBlock { List content; String[] cellAligns; + + boolean isTask; + + boolean isChecked; MdBlock() { this.level = 0; diff --git a/nutz-plugins-zdoc/src/test/java/org/nutz/plugins/zdoc/markdown/MarkdownTest.java b/nutz-plugins-zdoc/src/test/java/org/nutz/plugins/zdoc/markdown/MarkdownTest.java index 74541ca679887b140f0aeceddaaf89921b51af2e..2940aefcda25a93d7e15c8136fbaec3c84399710 100644 --- a/nutz-plugins-zdoc/src/test/java/org/nutz/plugins/zdoc/markdown/MarkdownTest.java +++ b/nutz-plugins-zdoc/src/test/java/org/nutz/plugins/zdoc/markdown/MarkdownTest.java @@ -6,12 +6,55 @@ import org.junit.Test; import org.nutz.lang.Strings; public class MarkdownTest { - + + /** + * https://github.com/nutzam/nutzmore/issues/88 + */ + @Test + public void test_task_list() { + assertEquals("

    " + + "
  • " + + "AA" + + "
", + _HTML("- [ ] AA")); + + assertEquals("
    " + + "
  • " + + "AAAA" + + "
  • " + + "
  • " + + "BBBB" + + "
      " + + "
    • " + + "BB-b0
    • " + + "
    • " + + "BB-b1
    • " + + "
    " + + "
  • " + + "
", + _HTML("- [ ] AAAA\n" + + "- [ ] BBBB\n" + + " - [ ] BB-b0\n" + + " - [ ] BB-b1\n")); + + } + + /** + * https://github.com/nutzam/nutzmore/issues/87 + */ + @Test + public void test_img_in_link() { + assertEquals("

\"xyz\"

", + _HTML("[![xyz](image/abc.png)](http://nutz.cn)")); + assertEquals("

", + _HTML("[![](image/abc.png)](http://nutz.cn)")); + } + @Test public void test_mix_html() { assertEquals("

A

BXC

", _HTML("A\n\nBXC")); } - + @Test public void test_indent_2space() { assertEquals("
  • A
    • B
", _HTML(" - A\n - B")); diff --git a/pom.xml b/pom.xml index 758fc54f47ae864509653593f7a43d61e856ba36..abfe581406b408209dfc5d405e72f62a2e7a003d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.nutz nutzmore - 1.r.65-SNAPSHOT + 1.r.66-SNAPSHOT nutzmore Nutz, which is a collections of lightweight frameworks, each of them can be used independently @@ -122,9 +122,12 @@ nutz-plugins-cache nutz-plugins-daocache nutz-plugins-daomapping + nutz-plugins-dict nutz-plugins-event nutz-plugins-hotplug + nutz-plugins-iocloader nutz-plugins-ip2region + nutz-plugins-jqgrid nutz-plugins-jsonrpc nutz-plugins-mock nutz-plugins-multiview