周浩 8 лет назад
Родитель
Сommit
44f1a76f98

+ 11 - 0
hsweb-web-bean/src/main/java/org/hsweb/web/bean/common/QueryParam.java

@@ -5,13 +5,16 @@ import org.hsweb.ezorm.param.Term;
 import org.hsweb.ezorm.param.TermType;
 
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Created by 浩 on 2016-01-16 0016.
  */
 public class QueryParam extends org.hsweb.ezorm.param.QueryParam<QueryParam> implements Serializable {
     private static final long serialVersionUID = 7941767360194797891L;
+    private Map<String, Object> param = new HashMap<>();
 
     public QueryParam noPaging() {
         setPaging(false);
@@ -41,4 +44,12 @@ public class QueryParam extends org.hsweb.ezorm.param.QueryParam<QueryParam> imp
     public static QueryParam build() {
         return new QueryParam();
     }
+
+    public Map<String, Object> getParam() {
+        return param;
+    }
+
+    public void setParam(Map<String, Object> param) {
+        this.param = param;
+    }
 }

+ 3 - 0
hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/module/ModuleMeta.java

@@ -1,5 +1,6 @@
 package org.hsweb.web.bean.po.module;
 
+import org.hibernate.validator.constraints.NotBlank;
 import org.hsweb.web.bean.po.GenericPo;
 
 /**
@@ -8,10 +9,12 @@ import org.hsweb.web.bean.po.GenericPo;
  */
 public class ModuleMeta extends GenericPo<String> {
 
+    @NotBlank(message = "key不能为空")
     private String key;
 
     private String remark;
 
+    @NotBlank(message = "模块不能为空")
     private String moduleId;
 
     private String roleId;

+ 9 - 19
hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/script/DynamicScript.java

@@ -14,13 +14,13 @@ public class DynamicScript extends GenericPo<String> {
     private static final long serialVersionUID = 8910856253780046561L;
 
     //名称
-    @Length(min = 4, message = "名称长度不能少于4")
     @NotNull
-    @Pattern(regexp = "^[a-zA-Z0-9_-]+$", message = "名称只能为大小写字母和下划线组成")
+    @Length(min = 4, message = "名称长度不能少于4")
+    @Pattern(regexp = "^[a-zA-Z0-9_-]+$", message = "名称只能为大小写字母,数字,下划线和-组成")
     private String name;
 
     //类型
-    @Pattern(regexp = "(js)|(groovy)|(spel)|(ognl)|(java)", message = "类型仅支持js,groovy,spel,ognl,java")
+    @Pattern(regexp = "(js)|(groovy)|(java)", message = "类型仅支持js,groovy,java")
     private String type;
 
     //内容
@@ -29,8 +29,8 @@ public class DynamicScript extends GenericPo<String> {
     //备注
     private String remark;
 
-    //路径
-    private String path;
+    //分类
+    private String classifiedId;
 
     //状态
     private int status;
@@ -105,22 +105,12 @@ public class DynamicScript extends GenericPo<String> {
         this.remark = remark;
     }
 
-    /**
-     * 获取 路径
-     *
-     * @return String 路径
-     */
-    public String getPath() {
-        if (this.path == null)
-            return "root";
-        return this.path;
+    public void setClassifiedId(String classifiedId) {
+        this.classifiedId = classifiedId;
     }
 
-    /**
-     * 设置 路径
-     */
-    public void setPath(String path) {
-        this.path = path;
+    public String getClassifiedId() {
+        return classifiedId;
     }
 
     /**

+ 2 - 2
hsweb-web-bean/src/main/resources/system/install/sql/h2/install.sql

@@ -268,7 +268,7 @@ COMMENT ON COLUMN "S_ROLE_MODULES"."ACTIONS" IS '可操作权限';
 CREATE TABLE "S_SCRIPT" (
   "U_ID"    VARCHAR2(256)  NOT NULL,
   "NAME"    VARCHAR2(256)  NOT NULL,
-  "PATH"    VARCHAR2(1024) NOT NULL,
+  "CLASSIFIED_ID"    VARCHAR2(1024) NOT NULL,
   "TYPE"    VARCHAR2(256)  NOT NULL,
   "CONTENT" CLOB           NOT NULL,
   "REMARK"  VARCHAR2(512)  NULL,
@@ -277,7 +277,7 @@ CREATE TABLE "S_SCRIPT" (
 COMMENT ON TABLE "S_SCRIPT" IS '脚本';
 COMMENT ON COLUMN "S_SCRIPT"."U_ID" IS 'UID';
 COMMENT ON COLUMN "S_SCRIPT"."NAME" IS '脚本名称';
-COMMENT ON COLUMN "S_SCRIPT"."PATH" IS '路径';
+COMMENT ON COLUMN "S_SCRIPT"."CLASSIFIED_ID" IS '路径';
 COMMENT ON COLUMN "S_SCRIPT"."TYPE" IS '类型';
 COMMENT ON COLUMN "S_SCRIPT"."CONTENT" IS '内容';
 COMMENT ON COLUMN "S_SCRIPT"."REMARK" IS '备注';

+ 1 - 1
hsweb-web-bean/src/main/resources/system/install/sql/mysql/install.sql

@@ -198,7 +198,7 @@ CREATE TABLE `s_script` (
   COMMENT 'uid',
   `name`    VARCHAR(256)  NOT NULL
   COMMENT '脚本名称',
-  `path`    VARCHAR(1024) NOT NULL
+  `classified_id`    VARCHAR(1024) NOT NULL
   COMMENT '路径',
   `type`    VARCHAR(256)  NOT NULL
   COMMENT '类型',

+ 2 - 2
hsweb-web-bean/src/main/resources/system/install/sql/oracle/install.sql

@@ -268,7 +268,7 @@ COMMENT ON COLUMN ${jdbc.username}."S_ROLE_MODULES"."ACTIONS" IS '可操作权
 CREATE TABLE ${jdbc.username}."S_SCRIPT" (
 "U_ID" VARCHAR2(256)  NOT NULL,
 "NAME" VARCHAR2(256)  NOT NULL,
-"PATH" VARCHAR2(1024) NOT NULL,
+"CLASSIFIED_ID" VARCHAR2(1024) NOT NULL,
 "TYPE" VARCHAR2(256)  NOT NULL,
 "CONTENT" CLOB NOT NULL,
 "REMARK" VARCHAR2(512)  NULL,
@@ -277,7 +277,7 @@ CREATE TABLE ${jdbc.username}."S_SCRIPT" (
 COMMENT ON TABLE ${jdbc.username}."S_SCRIPT" IS '脚本';
 COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."U_ID" IS 'UID';
 COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."NAME" IS '脚本名称';
-COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."PATH" IS '路径';
+COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."CLASSIFIED_ID" IS '路径';
 COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."TYPE" IS '类型';
 COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."CONTENT" IS '内容';
 COMMENT ON COLUMN ${jdbc.username}."S_SCRIPT"."REMARK" IS '备注';

+ 1 - 1
hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/script/DynamicScriptMapper.xml

@@ -10,7 +10,7 @@
         <result property="type" column="type" javaType="String" jdbcType="VARCHAR" />
         <result property="content" column="content" javaType="String" jdbcType="VARCHAR" />
         <result property="remark" column="remark" javaType="String" jdbcType="VARCHAR" />
-        <result property="path" column="path" javaType="String" jdbcType="VARCHAR" />
+        <result property="classifiedId" column="classified_id" javaType="String" jdbcType="VARCHAR" />
         <result property="status" column="status" javaType="int" jdbcType="INTEGER" />
     </resultMap>
 

+ 1 - 1
hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/script/DynamicScriptMapper.xml

@@ -10,7 +10,7 @@
         <result property="type" column="type" javaType="String" jdbcType="VARCHAR" />
         <result property="content" column="content" javaType="String" jdbcType="VARCHAR" />
         <result property="remark" column="remark" javaType="String" jdbcType="VARCHAR" />
-        <result property="path" column="path" javaType="String" jdbcType="VARCHAR" />
+        <result property="classifiedId" column="classified_id" javaType="String" jdbcType="VARCHAR" />
         <result property="status" column="status" javaType="int" jdbcType="INTEGER" />
     </resultMap>
 

+ 3 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DataBaseAutoConfiguration.java

@@ -4,6 +4,7 @@ import org.hsweb.ezorm.executor.SqlExecutor;
 import org.hsweb.ezorm.meta.DatabaseMetaData;
 import org.hsweb.ezorm.meta.expand.ObjectWrapperFactory;
 import org.hsweb.ezorm.meta.expand.ValidatorFactory;
+import org.hsweb.ezorm.meta.parser.H2TableMetaParser;
 import org.hsweb.ezorm.meta.parser.MysqlTableMetaParser;
 import org.hsweb.ezorm.meta.parser.OracleTableMetaParser;
 import org.hsweb.ezorm.meta.parser.TableMetaParser;
@@ -58,6 +59,8 @@ public class DataBaseAutoConfiguration {
             return new MysqlTableMetaParser(sqlExecutor);
         } else if (driverClassName.contains("oracle")) {
             return new OracleTableMetaParser(sqlExecutor);
+        }else if (driverClassName.contains("h2")) {
+            return new H2TableMetaParser(sqlExecutor);
         }
         return null;
     }

+ 85 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/script/DynamicScriptExecuteServiceImpl.java

@@ -0,0 +1,85 @@
+package org.hsweb.web.service.impl.script;
+
+import org.hsweb.commons.MD5;
+import org.hsweb.expands.script.engine.DynamicScriptEngine;
+import org.hsweb.expands.script.engine.DynamicScriptEngineFactory;
+import org.hsweb.expands.script.engine.ExecuteResult;
+import org.hsweb.expands.script.engine.ScriptContext;
+import org.hsweb.web.bean.po.script.DynamicScript;
+import org.hsweb.web.core.authorize.ExpressionScopeBean;
+import org.hsweb.web.core.exception.NotFoundException;
+import org.hsweb.web.service.script.DynamicScriptExecuteService;
+import org.hsweb.web.service.script.DynamicScriptService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * Created by zhouhao on 16-6-29.
+ */
+@Service("dynamicScriptExecuteService")
+public class DynamicScriptExecuteServiceImpl implements DynamicScriptExecuteService {
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired(required = false)
+    protected Map<String, ExpressionScopeBean> expressionScopeBeanMap;
+
+    @Resource
+    protected DynamicScriptService dynamicScriptService;
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public Object exec(String name, String type, Map<String, Object> var) throws Throwable {
+        DynamicScript script = dynamicScriptService.selectByNameAndType(name, type);
+        assertNotNull(script, "脚本不存在");
+        return exec(script, var);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public Object exec(String id, Map<String, Object> var) throws Throwable {
+        if (id.contains(".")) {
+            String nameAndType[] = id.split("[.]");
+            return exec(nameAndType[0], nameAndType[1], var);
+        }
+        DynamicScript script = dynamicScriptService.selectByPk(id);
+        assertNotNull(script, "脚本不存在");
+        return exec(script, var);
+    }
+    @Transactional(rollbackFor = Throwable.class)
+    protected Object exec(DynamicScript script, Map<String, Object> var) throws Throwable {
+        if (script.getStatus() != 1) {
+            assertNotNull(null, "脚本已禁用");
+        }
+        DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(script.getType());
+        assertNotNull(engine, "不支持的引擎");
+        if (!engine.compiled(script.getId())) {
+            dynamicScriptService.compile(script.getId());
+        }
+        if (expressionScopeBeanMap != null) {
+            var.putAll(expressionScopeBeanMap);
+        }
+        ScriptContext context = engine.getContext(script.getId());
+        //如果发生了变化,自动重新进行编译
+        if (!context.getMd5().equals(MD5.defaultEncode(script.getContent()))) {
+            dynamicScriptService.compile(script.getId());
+        }
+        ExecuteResult result = engine.execute(script.getId(), var);
+        if (!result.isSuccess()) {
+            if (result.getException() != null)
+                throw result.getException();
+        }
+        return result.getResult();
+    }
+
+    protected void assertNotNull(Object po, String message) {
+        if (po == null) throw new NotFoundException(message);
+    }
+
+}

+ 45 - 14
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/script/DynamicScriptServiceImpl.java

@@ -1,18 +1,26 @@
 package org.hsweb.web.service.impl.script;
 
+import org.hsweb.commons.MD5;
+import org.hsweb.expands.script.engine.*;
+import org.hsweb.web.bean.common.QueryParam;
+import org.hsweb.web.bean.common.UpdateParam;
 import org.hsweb.web.bean.po.script.DynamicScript;
+import org.hsweb.web.core.authorize.ExpressionScopeBean;
 import org.hsweb.web.dao.script.DynamicScriptMapper;
 import org.hsweb.web.core.exception.BusinessException;
 import org.hsweb.web.service.impl.AbstractServiceImpl;
 import org.hsweb.web.service.script.DynamicScriptService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
+import org.springframework.cache.annotation.Caching;
 import org.springframework.stereotype.Service;
-import org.hsweb.expands.script.engine.DynamicScriptEngine;
-import org.hsweb.expands.script.engine.DynamicScriptEngineFactory;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 动态脚本服务类
@@ -32,6 +40,14 @@ public class DynamicScriptServiceImpl extends AbstractServiceImpl<DynamicScript,
         return this.dynamicScriptMapper;
     }
 
+    @Override
+    public String insert(DynamicScript data) throws Exception {
+        DynamicScript old = selectSingle(QueryParam.build().where("name", data.getName()).and("type", data.getType()));
+        if (old != null) throw new BusinessException("已存在相同名称和类型的脚本!", 400);
+        data.setStatus(1);
+        return super.insert(data);
+    }
+
     @Override
     @Cacheable(value = CACHE_KEY, key = "'script.'+#pk")
     public DynamicScript selectByPk(String pk) throws Exception {
@@ -39,9 +55,28 @@ public class DynamicScriptServiceImpl extends AbstractServiceImpl<DynamicScript,
     }
 
     @Override
-    @CacheEvict(value = CACHE_KEY, key = "'script.'+#data.id")
+    @Cacheable(value = CACHE_KEY, key = "'script.md5.'+#pk")
+    public String getScriptMd5(String scriptId) throws Exception {
+        DynamicScript script = selectByPk(scriptId);
+        assertNotNull(script, "脚本不存在");
+        return MD5.defaultEncode(script.getContent());
+    }
+
+    @Override
+    @Cacheable(value = CACHE_KEY, key = "'script.'+#name+'.'+#type")
+    public DynamicScript selectByNameAndType(String name, String type) throws Exception {
+        return selectSingle(QueryParam.build().where("name", name).and("type", type));
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_KEY, allEntries = true)
     public int update(DynamicScript data) throws Exception {
-        int i = super.update(data);
+        DynamicScript old = selectSingle(QueryParam.build()
+                .where("name", data.getName())
+                .and("type", data.getType())
+                .and("id$not", data.getId()));
+        if (old != null) throw new BusinessException("已存在相同名称和类型的脚本!", 400);
+        int i = getMapper().update(UpdateParam.build(data).excludes("status").where("id", data.getId()));
         return i;
     }
 
@@ -53,28 +88,24 @@ public class DynamicScriptServiceImpl extends AbstractServiceImpl<DynamicScript,
     }
 
     @Override
-    @CacheEvict(value = CACHE_KEY, key = "'script.'+#pk")
+    @CacheEvict(value = CACHE_KEY, allEntries = true)
     public int delete(String pk) throws Exception {
         return super.delete(pk);
     }
 
     public void compile(String id) throws Exception {
         DynamicScript script = this.selectByPk(id);
-        if (script == null) throw new BusinessException(String.format("脚本[%s]不存在", id));
+        assertNotNull(script, "脚本不存在");
         DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(script.getType());
-        try {
-            if(engine==null)throw new BusinessException("不支持的脚本语言:"+script.getType());
-            engine.compile(script.getId(), script.getContent());
-        } catch (Exception e) {
-            logger.error("compile error!", e);
-        }
+        assertNotNull(engine, "不支持的引擎");
+        engine.compile(script.getId(), script.getContent());
     }
 
     public void compileAll() throws Exception {
-        List<DynamicScript> list = this.select();
+        List<DynamicScript> list = this.select(QueryParam.build().where("status", 1).noPaging());
         for (DynamicScript script : list) {
             DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(script.getType());
-            if(engine==null)throw new BusinessException("不支持的脚本语言:"+script.getType());
+            assertNotNull(engine, "不支持的引擎");
             engine.compile(script.getId(), script.getContent());
         }
     }

+ 13 - 0
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/script/DynamicScriptExecuteService.java

@@ -0,0 +1,13 @@
+package org.hsweb.web.service.script;
+
+import java.util.Map;
+
+/**
+ * Created by zhouhao on 16-6-29.
+ */
+public interface DynamicScriptExecuteService {
+    Object exec(String scriptId, Map<String, Object> var) throws Throwable;
+
+    Object exec(String name, String type, Map<String, Object> var) throws Throwable;
+
+}

+ 5 - 0
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/script/DynamicScriptService.java

@@ -3,6 +3,8 @@ package org.hsweb.web.service.script;
 import org.hsweb.web.bean.po.script.DynamicScript;
 import org.hsweb.web.service.GenericService;
 
+import java.util.Map;
+
 /**
  * 动态脚本服务类
  * Created by generator
@@ -23,4 +25,7 @@ public interface DynamicScriptService extends GenericService<DynamicScript, Stri
      */
     void compileAll() throws Exception;
 
+    String getScriptMd5(String scriptId) throws Exception;
+
+    DynamicScript selectByNameAndType(String name, String type) throws Exception;
 }