diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..3907d9c --- /dev/null +++ b/build.gradle @@ -0,0 +1,125 @@ + +apply plugin: 'java' + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +ext { + /** + * 项目中依赖的jar的路径 + * 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 + * 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 + */ + libPath = "$projectDir/../webroot/WEB-INF/lib" + + /** + * 是否对插件的class进行加密保护,防止反编译 + */ + guard = true + + def pluginInfo = getPluginInfo() + pluginPre = "fine-plugin" + pluginName = pluginInfo.id + pluginVersion = pluginInfo.version + + outputPath = "$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-" + pluginVersion + "/classes" +} + +group = 'com.fr.plugin' +version = '10.0' +sourceCompatibility = '8' + +sourceSets { + main { + java.outputDir = file(outputPath) + output.resourcesDir = file(outputPath) + } +} + +ant.importBuild("encrypt.xml") +//定义ant变量 +ant.projectDir = projectDir +ant.references["compile.classpath"] = ant.path { + fileset(dir: libPath, includes: '**/*.jar') + fileset(dir: ".",includes:"**/*.jar" ) +} + +classes.dependsOn('clean') + +task copyFiles(type: Copy,dependsOn: 'classes'){ + from outputPath + into "$projectDir/classes" +} + +task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){ + from "$projectDir/classes" + into "$projectDir/transform-classes" + include "**/*.*" +} +jar.dependsOn("preJar") + +task makeJar(type: Jar,dependsOn: preJar){ + from fileTree(dir: "$projectDir/transform-classes") + baseName pluginPre + appendix "data-factory" + version pluginVersion + destinationDir = file("$buildDir/libs") + + doLast(){ + delete file("$projectDir/classes") + delete file("$projectDir/transform-classes") + } +} + +task copyFile(type: Copy,dependsOn: ["makeJar"]){ + from "$buildDir/libs" + from("$projectDir/lib") { + include "*.jar" + } + from "$projectDir/plugin.xml" + into file("$buildDir/temp/plugin") +} + +task zip(type:Zip,dependsOn:["copyFile"]){ + from "$buildDir/temp/plugin" + destinationDir file("$buildDir/install") + baseName pluginPre + appendix pluginName + version pluginVersion +} + +//控制build时包含哪些文件,排除哪些文件 +processResources { +// exclude everything +// 用*.css没效果 +// exclude '**/*.css' +// except this file +// include 'xx.xml' +} + +/*读取plugin.xml中的version*/ +def getPluginInfo(){ + def xmlFile = file("plugin.xml") + if (!xmlFile.exists()) { + return ["id":"none", "version":"1.0.0"] + } + def plugin = new XmlParser().parse(xmlFile) + def version = plugin.version[0].text() + def id = plugin.id[0].text() + return ["id":id,"version":version] +} + +repositories { + mavenLocal() + maven { + url = uri('http://mvn.finedevelop.com/repository/maven-public/') + } +} + +dependencies { + //使用本地jar + implementation fileTree(dir: 'lib', include: ['**/*.jar']) + implementation fileTree(dir: libPath, include: ['**/*.jar']) +} + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..6dd430c --- /dev/null +++ b/build.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/encrypt.xml b/encrypt.xml new file mode 100644 index 0000000..1401cd1 --- /dev/null +++ b/encrypt.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/fine-tool-echarts-export-1.0.jar b/lib/fine-tool-echarts-export-1.0.jar new file mode 100644 index 0000000..ee88c3f Binary files /dev/null and b/lib/fine-tool-echarts-export-1.0.jar differ diff --git a/lib/report/fine-plugin-com.tptj.plugin.hg.client.center.v10-1.0.10.jar b/lib/report/fine-plugin-com.tptj.plugin.hg.client.center.v10-1.0.10.jar new file mode 100644 index 0000000..b5c4d71 Binary files /dev/null and b/lib/report/fine-plugin-com.tptj.plugin.hg.client.center.v10-1.0.10.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..04a214b --- /dev/null +++ b/plugin.xml @@ -0,0 +1,26 @@ + + com.fr.plugin.jee.open.port.demo + + yes + 2.3.2 + 10.0~ + tptj + 2019-12-30 + + + com.fr.plugin.jee.port + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/jee/port/AbstractDataApi.java b/src/main/java/com/fr/plugin/jee/port/AbstractDataApi.java new file mode 100644 index 0000000..f050e12 --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/AbstractDataApi.java @@ -0,0 +1,245 @@ +package com.fr.plugin.jee.port; + +import com.fr.base.*; +import com.fr.data.TableDataSource; +import com.fr.data.api.TableDataAssist; +import com.fr.decision.webservice.Response; +import com.fr.form.main.FormIO; +import com.fr.general.data.DataModel; +import com.fr.intelli.record.MetricRegistry; +import com.fr.io.TemplateWorkBookIO; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.main.TemplateWorkBook; +import com.fr.main.workbook.ResultWorkBook; +import com.fr.report.report.Report; +import com.fr.script.Calculator; +import com.fr.stable.Primitive; +import com.fr.stable.StringUtils; +import com.fr.stable.WriteActor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.condition.QueryCondition; +import com.fr.stable.query.data.DataList; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.web.utils.WebUtils; +import com.fr.write.main.WriteRWorkBook; +import com.tptj.plugin.hg.client.open.exception.CodeException; + + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-09-07 + **/ +public abstract class AbstractDataApi { + + + + protected List> format(DataModel data )throws CodeException { + List> content = new ArrayList>(); + try{ + int colCount = data.getColumnCount(); + String [] colNames = new String[colCount]; + for( int i=0; i row = new HashMap(); + for( int j=0;j parameters = getSpParameters(req); + ParameterMapNameSpace space = ParameterMapNameSpace.create(parameters); + calculator.pushNameSpace( space ); + calculator.setAttribute( TableDataSource.KEY, source ); + return calculator; + } + + protected TableDataSource getTableDataSource( String report )throws CodeException{ + try{ + if( report.endsWith(".frm") ){ + return FormIO.readForm(report); + } + return TemplateWorkBookIO.readTemplateWorkBook(report); + }catch(Exception e){ + throw CodeException.create("10010",e.getMessage()); + } + } + + protected String parseSql(HttpServletRequest req,String sql)throws CodeException{ + Parameter[] parameters = ParameterHelper.analyze4Parameters(sql, false); + Map params = new HashMap(); + for( Parameter p : parameters ){ + params.put(p.getName(),getSpParameters(req).get(p.getName())); + } + try{ + return TemplateUtils.render( sql, params,Calculator.createCalculator() ); + }catch(Exception e){ + throw CodeException.create("10011",e.getMessage()); + } + } + + protected String[] getDataConfig( String id, String dsName )throws CodeException{ + Calculator cal = Calculator.createCalculator(); + Map parameters = new HashMap(); + parameters.put("id",id); + ParameterMapNameSpace space = ParameterMapNameSpace.create(parameters); + cal.pushNameSpace(space); + DataModel rs = SynchronizedLiveDataModelUtils.getSELiveDataModel4Share(cal, dsName); + if (rs == null) { + TableData td = TableDataAssist.getTableData(cal, dsName); + rs = td == null ? null : td.createDataModel(cal); + } + try{ + if( 0 == rs.getRowCount() ){ + throw new Exception("["+id+"] 对应的服务不存在!请联系管理员处理!"); + } + if( 1 < rs.getRowCount() ){ + throw new Exception("["+id+"] 服务异常!一个ID只能对应一个数据服务!请联系管理员处理!"); + } + int idxSql = rs.getColumnIndex("data"); + int connIdx = rs.getColumnIndex("source"); + return new String[]{ + (String)rs.getValueAt(0,connIdx),(String)rs.getValueAt(0,idxSql) + }; + }catch(Exception e){ + throw CodeException.create("10012",e.getMessage()); + } + } + + protected ResultWorkBook getResultWorkBook( TemplateWorkBook workbook, HttpServletRequest req )throws CodeException { + Map parameters = getSpParameters(req); + return workbook.execute(parameters,new WriteActor()); + } + + protected Report getSheet(Map config, WriteRWorkBook resultBook ){ + //sheet名 + String name = (String) config.get("tag"); + if( StringUtils.isEmpty(name) ){ + name = resultBook.getReportName(0); + } + int idx = getSheetIndex( name, resultBook,0 ); + return resultBook.getReport(idx); + } + + protected int getSheetIndex( String name, WriteRWorkBook resultBook, int dft){ + int count = resultBook.getReportCount(); + for( int i=0; i getSpParameters(HttpServletRequest req){ + Map parameters = WebUtils.parameters4SessionIDInfor(req); + if( null == parameters ){ + parameters = new HashMap(); + } + ServletInputStream in = null; + try{ + int len = req.getContentLength(); + String charset = req.getCharacterEncoding(); + if( StringUtils.isEmpty(charset) ){ + charset = "UTF-8"; + } + byte[] buffer = new byte[len]; + in = req.getInputStream(); + in.read(buffer, 0, len); + String body = new String(buffer,charset); + parameters.put("body",body); + Map obj = new JSONObject(body).toMap(); + parameters.putAll(obj); + }catch(Exception e){ + FineLoggerFactory.getLogger().info("####HUGH####:error={}",e.getMessage()); + }finally { + if( null != in ){ + try{ + in.close(); + }catch(Exception e){ } + } + } + return parameters; + } + + /** + * 额外增加相应参数 + * @param req + * @param defaultParameters + * @param config + * @return + * @throws CodeException + */ + public abstract Response mixCall(HttpServletRequest req, Map defaultParameters, Map config) throws CodeException ; + + /** + * 获取要回显的其他内容 + * @param config + * @return + */ + public abstract Map getOptions(Map config); + + public Response call(HttpServletRequest req, Map defaultParameters, Map config) throws CodeException { + Response res = mixCall(req, defaultParameters, config); + Object data = res.getData(); + if( null == data || null == config ){ + return res; + } + config = getOptions(config); + if( config.isEmpty() ){ + return res; + } + if( config.containsKey("url") ){ + String url = (String) config.get("url"); + if( !url.startsWith("http://") && !url.startsWith("https://") ){ + config.put("url",getBaseUrl(req)+config.get("url")); + } + } + return Response.ok(data ); + } + + private String getBaseUrl( HttpServletRequest req ){ + String url = req.getScheme()+"://"+req.getServerName(); + int port = req.getServerPort(); + if( 443 != port && 80 != port ){ + url += ":"+ port; + } + url += req.getContextPath()+req.getServletPath(); + return url; + } + +} diff --git a/src/main/java/com/fr/plugin/jee/port/DemoAuth.java b/src/main/java/com/fr/plugin/jee/port/DemoAuth.java new file mode 100644 index 0000000..726099d --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/DemoAuth.java @@ -0,0 +1,21 @@ +package com.fr.plugin.jee.port; + +import com.tptj.plugin.hg.client.open.exception.CodeException; +import com.tptj.plugin.hg.client.open.impl.AbstractAuthProvider; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class DemoAuth extends AbstractAuthProvider { + + + @Override + public String AuthName() { + return "DEMO认证"; + } + + @Override + public boolean auth(HttpServletRequest httpServletRequest, Map map, Map map1) throws CodeException { + return true; + } +} diff --git a/src/main/java/com/fr/plugin/jee/port/DemoCaller.java b/src/main/java/com/fr/plugin/jee/port/DemoCaller.java new file mode 100644 index 0000000..5d708aa --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/DemoCaller.java @@ -0,0 +1,27 @@ +package com.fr.plugin.jee.port; + +import com.fr.decision.webservice.Response; +import com.sun.management.ThreadMXBean; +import com.tptj.plugin.hg.client.open.exception.CodeException; +import com.tptj.plugin.hg.client.open.impl.AbstractAPICaller; + +import javax.servlet.http.HttpServletRequest; +import java.lang.management.ManagementFactory; +import java.util.Map; + +public class DemoCaller extends AbstractAPICaller { + @Override + public Response call(HttpServletRequest httpServletRequest, Map map, Map map1) throws CodeException { + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + System.out.println(threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId())); + String[] st = new String[100000000]; + + System.out.println(threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId())); + return Response.success(); + } + + @Override + public String Description() { + return "测试"; + } +} diff --git a/src/main/java/com/fr/plugin/jee/port/DemoCallerProvider.java b/src/main/java/com/fr/plugin/jee/port/DemoCallerProvider.java new file mode 100644 index 0000000..a3e2631 --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/DemoCallerProvider.java @@ -0,0 +1,31 @@ +package com.fr.plugin.jee.port; + +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.tptj.plugin.hg.client.open.fun.APILoader; +import com.tptj.plugin.hg.client.open.impl.AbstractAPICallerProvider; + + +@FunctionRecorder +public class DemoCallerProvider extends AbstractAPICallerProvider { + + @ExecuteFunctionRecord + @Override + public APILoader[] registerCallers() { + return new APILoader[]{ + new DemoLoader() + }; + } + + + + @Override + public String groupName() { + return "测试"; + } + + @Override + public String groupDescription() { + return "这是测试"; + } +} diff --git a/src/main/java/com/fr/plugin/jee/port/DemoLoader.java b/src/main/java/com/fr/plugin/jee/port/DemoLoader.java new file mode 100644 index 0000000..25a9eac --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/DemoLoader.java @@ -0,0 +1,33 @@ +package com.fr.plugin.jee.port; + +import com.fr.decision.webservice.Response; +import com.tptj.plugin.hg.client.open.exception.CodeException; +import com.tptj.plugin.hg.client.open.fun.APICaller; +import com.tptj.plugin.hg.client.open.impl.AbstractAPILoader; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +public class DemoLoader extends AbstractAPILoader { + + @Override + public String APIName(){ + return "这是DEMO"; + } + + @Override + public String RequestType() { + return "GET"; + } + + @Override + public String path() { + return "demo"; + } + + @Override + public APICaller APICaller() { + return new DemoCaller(); + } +} diff --git a/src/main/java/com/fr/plugin/jee/port/GetBySql.java b/src/main/java/com/fr/plugin/jee/port/GetBySql.java new file mode 100644 index 0000000..c9dbd8f --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/GetBySql.java @@ -0,0 +1,71 @@ +package com.fr.plugin.jee.port; + +import com.fr.data.impl.DBTableData; +import com.fr.data.impl.NameDatabaseConnection; +import com.fr.decision.webservice.Response; +import com.fr.general.data.DataModel; +import com.fr.json.JSONObject; +import com.tptj.plugin.hg.client.open.exception.CodeException; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-09-07 + **/ +public class GetBySql extends AbstractDataApi { + { + + + } + @Override + public Response mixCall(HttpServletRequest req, Map defaultParameters, Map config) throws CodeException { + String connection = (String)config.get("connection"); + String sql = (String)config.get("sql"); + sql = parseSql(req,sql); + DataModel data = DBTableData.createCacheableDBResultSet(new NameDatabaseConnection(connection), sql, -1); + List content = format( data ); + return Response.ok(content); + } + + @Override + public Map getOptions(Map config) { + config.remove("connection"); + config.remove("sql"); + return config; + } + + + + + public String APIName() { + return "[demo]Sql数据服务-插件化"; + } + + public Map defaultParameters() { + return new HashMap(); + } + + public Map config() { + return new HashMap(){{ + put("connection","FRDemo"); + put("sql","SELECT * FROM `销量` where 地区 = '${地区}'"); + }}; + } + + public boolean isPublic() { + return true; + } + + public String RequestType() { + return "GET"; + } + + public String Description() { + return "通过配置SQL和数据源连接向外提供数据服务"; + } +} diff --git a/src/main/java/com/fr/plugin/jee/port/TestPort.java b/src/main/java/com/fr/plugin/jee/port/TestPort.java new file mode 100644 index 0000000..2071707 --- /dev/null +++ b/src/main/java/com/fr/plugin/jee/port/TestPort.java @@ -0,0 +1,4 @@ +package com.fr.plugin.jee.port; + +public class TestPort { +}