diff --git a/docs/claim.md b/docs/claim.md index 166fc99..3934d83 100644 --- a/docs/claim.md +++ b/docs/claim.md @@ -1,5 +1,7 @@ # 非FineKit中的Open类 +## 公共类别 + com.fr.script.AbstractFunction com.fr.script.Calculator @@ -40,8 +42,31 @@ com.fr.web.struct.category.ScriptPath com.fr.web.struct.category.StylePath +com.fr.js.NameJavaScriptGroup + +## 设计器类别 + +com.fr.design.beans.BasicBeanPane + +com.fr.design.beans.FurtherBasicBeanPane + +com.fr.design.dialog.BasicDialog + +com.fr.design.dialog.BasicPane + +com.fr.design.dialog.DialogActionAdapter + +## 图表类别 + com.fr.chart.ChartWebPara com.fr.chartx.data.field.ColumnField -com.fr.js.NameJavaScriptGroup \ No newline at end of file +## 报表类别 + +com.fr.report.cell.cellattr.highlight.AbstractHighlight + +com.fr.report.cell.cellattr.highlight.AbstractStyleHighlightAction + +## BI类别 + diff --git a/docs/name.md b/docs/name.md new file mode 100644 index 0000000..24de771 --- /dev/null +++ b/docs/name.md @@ -0,0 +1,13 @@ +# 命名和设计规范 + +* 在产品内部,接口会有一个抽象类实现,命名方式为Abstract+接口名,而在SDK中推荐使用Base+接口名来命名开放给插件使用的抽象类。 + +* 在产品内部,工具类工厂是以+Utils或者+Helper结尾的,而在SDK中推荐使用+Kit的方式作为工具类类名的结尾。 + +* 所有的包名字,都必须由一个个独立的小写的单词组成,务必不能混扎多单词组合、驼峰命名等。 + +* com.fanruan.api.design下均是提供给插件设计器部分使用的API。 + +* com.fanruan.api.report下均是提供给报表插件服务器部分使用的API。 + +* com.fanruan.api.decision下均是提供给插件调用的平台相关的API,包括但不限于:用户管理、登入登出、权限管理、模板管理等。 diff --git a/readme.md b/readme.md index 51a76d4..121545e 100644 --- a/readme.md +++ b/readme.md @@ -32,6 +32,10 @@ SessionKit#getSession(@NotNull String sessionID); 开放类列表见:[非FineKit开放类](docs/claim.md) +## 约定俗成的规范 + +[命名和设计规范](docs/name.md) + ## 使用方法 先使用maven打包,执行下面的命令(跳过单元测试) @@ -42,20 +46,17 @@ SessionKit#getSession(@NotNull String sessionID); 会在target目录下获得一个形如finekit-10.0-20190815.jar名字jar包,直接作为插件依赖jar包即可。 -## 已完全依赖FineKit的插件 +## 如何判断插件中调用的API需要增加到FineKit中 -|插件名|源码| -|-----|----| -|redis数据集插件|https://git.fanruan.com/fanruan/demo-tabledata-redis| -|增强公式编辑器插件|https://git.fanruan.com/fanruan/demo-formula-script| -|条件属性之文本对齐插件|https://git.fanruan.com/fanruan/demo-highlight-align| -|评分形态插件|https://git.fanruan.com/fanruan/demo-show-present| -|急速下拉树插件|https://git.fanruan.com/fanruan/demo-widget-ztree| -|网页框插件|https://git.fanruan.com/fanruan/demo-widget-iframe| +最简单的原则: -## 如何判断插件中调用的API需要增加到FineKit中 +1、插件只使用了JDK自带的类、插件接口(包括抽象类)、枚举、以及使用了@Open注解标记的类; -最简单的原则:除了JDK自带的类、插件接口(包括抽象类)、枚举、以及使用了@Open注解标记的类之外,是否还使用了com.fanruan.api(com.fr.third除外)之外的类,如果有则需要修改。 +2、插件只使用了包名前缀为com.fr.third的类; + +3、插件只使用了包名前缀为com.fanruan.api之外的类; + +如果违背了上述三个原则,则需要考虑将使用类加入FineKit中。 ## 如何提交新的API @@ -65,4 +66,20 @@ SessionKit#getSession(@NotNull String sessionID); 3、克隆FineKit代码到本地,新增相关的API代码,并提交到自己的仓库; -4、提交Pull Request到FineKit主仓库,等待审核通过被合并即可。 \ No newline at end of file +4、提交Pull Request到FineKit主仓库,等待审核通过被合并即可。 + +## 已完全依赖FineKit的插件 + +|插件名|源码| +|-----|----| +|redis数据集插件|https://git.fanruan.com/fanruan/demo-tabledata-redis| +|增强公式编辑器插件|https://git.fanruan.com/fanruan/demo-formula-script| +|条件属性之文本对齐插件|https://git.fanruan.com/fanruan/demo-highlight-align| +|评分形态插件|https://git.fanruan.com/fanruan/demo-show-present| +|急速下拉树插件|https://git.fanruan.com/fanruan/demo-widget-ztree| +|网页框插件|https://git.fanruan.com/fanruan/demo-widget-iframe| +|时钟控件|https://git.fanruan.com/fanruan/demo-show-clock| +|ldaps认证插件|https://git.fanruan.com/fanruan/demo-ldaps-passport| +|个人国际化设置插件|https://git.fanruan.com/fanruan/decision-user-language| +|插件配置持久化|https://git.fanruan.com/fanruan/demo-db-access| +|http认证简化插件|https://git.fanruan.com/fanruan/demo-auth-http| diff --git a/src/main/java/com/fanruan/api/conf/ConfigurationKit.java b/src/main/java/com/fanruan/api/conf/ConfigurationKit.java index 86cebc0..6f7ccb1 100644 --- a/src/main/java/com/fanruan/api/conf/ConfigurationKit.java +++ b/src/main/java/com/fanruan/api/conf/ConfigurationKit.java @@ -6,6 +6,7 @@ import com.fr.config.Configuration; import com.fr.config.holder.ConfigChangeListener; import com.fr.transaction.Configurations; import com.fr.transaction.ValidateProxy; +import com.fr.transaction.WorkerCallBack; import com.fr.transaction.WorkerFacade; /** @@ -58,4 +59,26 @@ public class ConfigurationKit { } }); } + + /** + * 在一个事务中修改配置 + * + * @param configType 配置类 + * @param runner 执行器 + * @param callBack 事务回调 + */ + public static void modify(Class configType, Runner runner, WorkerCallBack callBack) { + WorkerFacade facade = new WorkerFacade(configType) { + @Override + public void run() { + if (runner != null) { + runner.run(); + } + } + }; + if (callBack != null) { + facade.addCallBack(callBack); + } + Configurations.modify(facade); + } } diff --git a/src/main/java/com/fanruan/api/conf/HolderKit.java b/src/main/java/com/fanruan/api/conf/HolderKit.java index 323ceb3..3e1f5b3 100644 --- a/src/main/java/com/fanruan/api/conf/HolderKit.java +++ b/src/main/java/com/fanruan/api/conf/HolderKit.java @@ -7,6 +7,7 @@ import com.fanruan.api.conf.impl.ObjectMapConf; import com.fanruan.api.conf.impl.SimConf; import com.fr.config.holder.Conf; + import java.util.Collection; import java.util.Map; diff --git a/src/main/java/com/fanruan/api/data/ConnectionKit.java b/src/main/java/com/fanruan/api/data/ConnectionKit.java index 3931a38..1715ae8 100644 --- a/src/main/java/com/fanruan/api/data/ConnectionKit.java +++ b/src/main/java/com/fanruan/api/data/ConnectionKit.java @@ -7,6 +7,8 @@ import com.fr.file.ConnectionConfig; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + /** * 数据连接相关工具类 */ @@ -46,4 +48,13 @@ public class ConnectionKit { public static Connection createNameConnection(String name) { return new NameDatabaseConnection(name); } + + /** + * 获取所有的数据连接 + * + * @return 所有的数据连接组成的集合 + */ + public static Map getConnections() { + return ConnectionConfig.getInstance().getConnections(); + } } diff --git a/src/main/java/com/fanruan/api/decision/AuthorityKit.java b/src/main/java/com/fanruan/api/decision/AuthorityKit.java new file mode 100644 index 0000000..54ba641 --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/AuthorityKit.java @@ -0,0 +1,11 @@ +package com.fanruan.api.decision; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 权限相关的工具类 + */ +public class AuthorityKit { + +} diff --git a/src/main/java/com/fanruan/api/decision/CommonKit.java b/src/main/java/com/fanruan/api/decision/CommonKit.java new file mode 100644 index 0000000..a0c49a7 --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/CommonKit.java @@ -0,0 +1,54 @@ +package com.fanruan.api.decision; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.base.Base64; +import com.fr.base.ServerConfig; +import com.fr.decision.webservice.utils.DecisionServiceConstants; +import com.fr.stable.StringUtils; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 常规工具类 + */ +public class CommonKit { + + /** + * 这个方法用于判断从前端返回服务器端的密码是否有被修改过 + * + * @param password 从前端返回的密码文本 + * @return 如果密码没有被修改过就返回true,否则就返回false + */ + public static boolean isDefaultPasswordHolderString(String password) { + return DecisionServiceConstants.DEFAULT_PASSWORD.equals(password); + } + + /** + * 获取默认密码占位符 + * + * @return 默认密码占位符 + */ + public static String fetchDefaultPasswordHolderString() { + return DecisionServiceConstants.DEFAULT_PASSWORD; + } + + /** + * 将base64编码的字符串转为常规的字符串 + * + * @param encodeStr base64编码的字符串 + * @return 常规字符串 + */ + public static String getBase64DecodeStr(String encodeStr) { + try { + if (StringUtils.isNotEmpty(encodeStr)) { + return new String(Base64.decode(encodeStr), ServerConfig.getInstance().getServerCharset()); + } + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + + return StringKit.EMPTY; + } +} diff --git a/src/main/java/com/fanruan/api/decision/auth/BasePassport.java b/src/main/java/com/fanruan/api/decision/auth/BasePassport.java new file mode 100644 index 0000000..e0e8aea --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/auth/BasePassport.java @@ -0,0 +1,25 @@ +package com.fanruan.api.decision.auth; + +import com.fr.decision.authorize.impl.AbstractPassport; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 认证方式 + */ +public abstract class BasePassport extends AbstractPassport { + + /** + * 检查登录信息是否有效 + * + * @param username 用户名 + * @param inputPassword 输入的密码 + * @param savedPassword 配置文件中保存的密码 + * @param hashPassword 哈希后的密码 + * @return 登录凭证是有效的则返回true,否则返回false + */ + public boolean checkTicket(String username, String inputPassword, String savedPassword, String hashPassword) { + return false; + } +} diff --git a/src/main/java/com/fanruan/api/decision/auth/bean/BasePassportBean.java b/src/main/java/com/fanruan/api/decision/auth/bean/BasePassportBean.java new file mode 100644 index 0000000..e8b8b91 --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/auth/bean/BasePassportBean.java @@ -0,0 +1,40 @@ +package com.fanruan.api.decision.auth.bean; + +import com.fr.decision.authorize.Passport; +import com.fr.decision.webservice.bean.authentication.PassportBean; +import com.fr.third.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 用于表示不同认证方式的接口 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") +public abstract class BasePassportBean extends PassportBean { + + /** + * 用于标记认证类型的字符串 + * + * @return 字符串 + */ + @Override + public abstract String markType(); + + /** + * 根据配置对象生成认证配置数据层对象 + * + * @param t 配置对象 + * @return 配属数据层 + */ + @Override + public abstract BasePassportBean createPassportBean(T t); + + /** + * 生成配置对象 + * + * @return 配置 + */ + @Override + public abstract Passport createPassport(); +} diff --git a/src/main/java/com/fanruan/api/login/LoginKit.java b/src/main/java/com/fanruan/api/decision/login/LoginKit.java similarity index 75% rename from src/main/java/com/fanruan/api/login/LoginKit.java rename to src/main/java/com/fanruan/api/decision/login/LoginKit.java index be128c1..620c2a2 100644 --- a/src/main/java/com/fanruan/api/login/LoginKit.java +++ b/src/main/java/com/fanruan/api/decision/login/LoginKit.java @@ -1,4 +1,4 @@ -package com.fanruan.api.login; +package com.fanruan.api.decision.login; import com.fr.decision.authorize.Passport; import com.fr.decision.authorize.impl.HttpPassport; @@ -14,14 +14,27 @@ public class LoginKit { /** * 获取决策平台设置的认证类型 + * * @return 认证对象 */ public static Passport getCurrentPassport() { return FSConfig.getInstance().getPassport(); } + /** + * 获取指定类型的通行证,如果不存在,就返回null + * + * @param type 通行证类型 + * @param 类型 + * @return 通行证 + */ + public static T getPassport(Class type) { + return FSConfig.getInstance().getPassport(type); + } + /** * 获取http认证的地址 + * * @return http认证地址 */ public static @Nullable String getHttpPassportUrl() { @@ -34,6 +47,7 @@ public class LoginKit { /** * 获取http认证的秘钥 + * * @return http认证地址 */ public static @Nullable String getHttpPassportKey() { diff --git a/src/main/java/com/fanruan/api/decision/user/OpenUser.java b/src/main/java/com/fanruan/api/decision/user/OpenUser.java new file mode 100644 index 0000000..52ff51e --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/user/OpenUser.java @@ -0,0 +1,73 @@ +package com.fanruan.api.decision.user; + +import com.fr.decision.authority.data.User; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + */ +public class OpenUser { + + private User user; + + static OpenUser wrap(User user) { + return new OpenUser(user); + } + + public OpenUser create(String id) { + return new OpenUser(new User().id(id)); + } + + private OpenUser(User user) { + this.user = user; + } + + User select() { + return user; + } + + public String getUserName() { + return user.getUserName(); + } + + public String getPassword() { + return user.getPassword(); + } + + public void setPassword(String password) { + this.user.setPassword(password); + } + + public String getRealName() { + return user.getRealName(); + } + + public void setRealName(String realName) { + this.user.setRealName(realName); + } + + public String getLanguage() { + return user.getLanguage(); + } + + public void setLanguage(String language) { + this.user.setLanguage(language); + } + + public String getEmail() { + return user.getEmail(); + } + + public void setEmail(String email) { + this.user.setEmail(email); + } + + public String getMobile() { + return user.getMobile(); + } + + public void setMobile(String mobile) { + this.user.setMobile(mobile); + } +} diff --git a/src/main/java/com/fanruan/api/decision/user/UserKit.java b/src/main/java/com/fanruan/api/decision/user/UserKit.java new file mode 100644 index 0000000..eeb1429 --- /dev/null +++ b/src/main/java/com/fanruan/api/decision/user/UserKit.java @@ -0,0 +1,66 @@ +package com.fanruan.api.decision.user; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.User; +import com.fr.decision.webservice.utils.UserSourceFactory; +import com.fr.decision.webservice.utils.user.source.UserSource; +import com.fr.decision.webservice.v10.user.UserService; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + */ +public class UserKit { + + /** + * 根据用户名获取这个用户的来源 + * + * @param username 用户名 + * @return 用户来源 + * @throws Exception 如果在获取用户的过程中出错了,则抛出此异常 + */ + public static UserSource fetchUserSource(String username) throws Exception { + User user = UserService.getInstance().getUserByUserName(username); + return UserSourceFactory.getInstance().getUserSource(user); + } + + public static OpenUser getUserByRequest(HttpServletRequest req) throws Exception { + User user = UserService.getInstance().getUserByRequest(req); + return OpenUser.wrap(user); + } + + /** + * 根据用户名获取用户信息 + * + * @param username 用户名 + * @return 用户信息 + * @throws Exception 如果获取用户出错,则抛出此异常 + */ + public static OpenUser getUser(String username) throws Exception { + User user = UserService.getInstance().getUserByUserName(username); + return OpenUser.wrap(user); + } + + /** + * 更新一个用户信息 + * + * @param user 用户 + * @throws Exception 更新用户信息失败则抛出此异常 + */ + public static void update(OpenUser user) throws Exception { + AuthorityContext.getInstance().getUserController().update(user.select()); + } + + /** + * 添加一个用户 + * + * @param user 用户 + * @throws Exception 添加用户失败则抛出此异常 + */ + public static void add(OpenUser user) throws Exception { + AuthorityContext.getInstance().getUserController().update(user.select()); + } +} diff --git a/src/main/java/com/fanruan/api/design/DesignKit.java b/src/main/java/com/fanruan/api/design/DesignKit.java index 194234a..b4b48d3 100644 --- a/src/main/java/com/fanruan/api/design/DesignKit.java +++ b/src/main/java/com/fanruan/api/design/DesignKit.java @@ -4,6 +4,7 @@ import com.fr.base.TableData; import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerBean; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; @@ -11,14 +12,16 @@ import com.fr.design.mainframe.JTemplate; public class DesignKit { /** * 直接预览数据集,没有实际值及显示值 + * * @param tableData 数据集 */ - public static void previewTableData(TableData tableData){ + public static void previewTableData(TableData tableData) { PreviewTablePane.previewTableData(tableData, -1, -1); } /** * 文本国际化 + * * @param key 国际化键 * @return 国际化后的值 */ @@ -28,7 +31,8 @@ public class DesignKit { /** * 带参数的文本国际化 - * @param key 国际化键 + * + * @param key 国际化键 * @param args 参数 * @return 国际化后的值 */ @@ -38,6 +42,7 @@ public class DesignKit { /** * 单例模式,返回DesignerFrame对象 + * * @return DesignerFrame对象 */ public static DesignerFrame getDesignerFrame() { @@ -46,9 +51,20 @@ public class DesignKit { /** * 得到当前在修改的模板 + * * @return 返回当前正在编辑的模板 */ - public static JTemplate getCurrentEditingTemplate(){ + public static JTemplate getCurrentEditingTemplate() { return HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); } + + /** + * 根据名字获取已经定义的bean对象 + * + * @param name bean的名字 + * @return bean对象 + */ + public static DesignerBean getDesignerBean(String name) { + return DesignerContext.getDesignerBean(name); + } } diff --git a/src/main/java/com/fanruan/api/design/macro/DataSourceConstants.java b/src/main/java/com/fanruan/api/design/macro/DataSourceConstants.java new file mode 100644 index 0000000..1d58b74 --- /dev/null +++ b/src/main/java/com/fanruan/api/design/macro/DataSourceConstants.java @@ -0,0 +1,13 @@ +package com.fanruan.api.design.macro; + +import com.fr.design.gui.NameInspector; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019/9/24 + */ +public class DataSourceConstants { + + public static final String ILLEGAL_NAME_HOLDER = NameInspector.ILLEGAL_NAME_HOLDER; +} diff --git a/src/main/java/com/fanruan/api/design/ui/editor/TextEditor.java b/src/main/java/com/fanruan/api/design/ui/editor/TextEditor.java new file mode 100644 index 0000000..4a08298 --- /dev/null +++ b/src/main/java/com/fanruan/api/design/ui/editor/TextEditor.java @@ -0,0 +1,14 @@ +package com.fanruan.api.design.ui.editor; + +/** + * 文本编辑器 + * */ +public class TextEditor extends com.fr.design.editor.editor.TextEditor{ + public TextEditor(){ + + } + + public TextEditor(String value) { + super(value); + } +} diff --git a/src/main/java/com/fanruan/api/design/util/GUICoreKit.java b/src/main/java/com/fanruan/api/design/util/GUICoreKit.java index 1ff5155..af8661c 100644 --- a/src/main/java/com/fanruan/api/design/util/GUICoreKit.java +++ b/src/main/java/com/fanruan/api/design/util/GUICoreKit.java @@ -118,7 +118,6 @@ public class GUICoreKit { public static JPanel createBorderLayoutPane() { return FRGUIPaneFactory.createBorderLayout_S_Pane(); } - /** * 设置一个窗口居中 */ diff --git a/src/main/java/com/fanruan/api/design/work/AbstractTableDataPane.java b/src/main/java/com/fanruan/api/design/work/AbstractTableDataPane.java index a0bd87a..ee81180 100644 --- a/src/main/java/com/fanruan/api/design/work/AbstractTableDataPane.java +++ b/src/main/java/com/fanruan/api/design/work/AbstractTableDataPane.java @@ -7,6 +7,8 @@ import com.fr.base.TableData; * @version 10.0 * Created by richie on 2019-08-30 * 数据插件继承此抽象类 + * @see com.fanruan.api.design.work.BaseTableDataPane */ -public abstract class AbstractTableDataPane extends com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane { +@Deprecated +public abstract class AbstractTableDataPane extends BaseTableDataPane { } diff --git a/src/main/java/com/fanruan/api/design/work/BaseTableDataPane.java b/src/main/java/com/fanruan/api/design/work/BaseTableDataPane.java new file mode 100644 index 0000000..8120550 --- /dev/null +++ b/src/main/java/com/fanruan/api/design/work/BaseTableDataPane.java @@ -0,0 +1,14 @@ +package com.fanruan.api.design.work; + +import com.fr.base.TableData; +import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019/9/24 + * 数据插件界面实现类,都继承此抽象类 + */ +public abstract class BaseTableDataPane extends AbstractTableDataPane { + +} diff --git a/src/main/java/com/fanruan/api/design/work/ConnectionComboBoxPanel.java b/src/main/java/com/fanruan/api/design/work/ConnectionComboBoxPanel.java index 9e3228b..047e38c 100644 --- a/src/main/java/com/fanruan/api/design/work/ConnectionComboBoxPanel.java +++ b/src/main/java/com/fanruan/api/design/work/ConnectionComboBoxPanel.java @@ -1,9 +1,179 @@ package com.fanruan.api.design.work; +import com.fanruan.api.conf.ConfigurationKit; +import com.fanruan.api.data.ConnectionKit; +import com.fanruan.api.data.open.BaseConnection; +import com.fanruan.api.design.DesignKit; +import com.fanruan.api.design.macro.DataSourceConstants; +import com.fanruan.api.generic.Runner; +import com.fanruan.api.util.AssistKit; +import com.fanruan.api.util.StringKit; import com.fr.data.impl.Connection; +import com.fr.design.DesignerEnvManager; +import com.fr.design.data.datapane.connect.ConnectionListPane; +import com.fr.design.data.datapane.connect.ConnectionShowPane; +import com.fr.design.data.datapane.connect.ItemEditableComboBoxPanel; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.file.ConnectionConfig; +import com.fr.stable.NameReference; +import com.fr.transaction.WorkerCallBack; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.connection.DBConnectAuth; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * 选择数据连接的下拉框 + */ +public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { + + private static final long serialVersionUID = 1L; + private Class cls; + private List nameList = new ArrayList<>(); -public class ConnectionComboBoxPanel extends com.fr.design.data.datapane.connect.ConnectionComboBoxPanel{ public ConnectionComboBoxPanel(Class cls) { - super(cls); + super(); + this.cls = cls; + this.itemComboBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + String selected = ConnectionComboBoxPanel.this.getSelectedItem(); + if (StringKit.isNotBlank(selected)) { + DesignerEnvManager.getEnvManager().setRecentSelectedConnection(selected); + } + } + }); + refreshItems(); + } + + protected Iterator items() { + nameList = new ArrayList<>(); + Iterator nameIt = ConnectionKit.getConnections().keySet().iterator(); + Collection noAuthConnections = WorkContext.getCurrent().get(DBConnectAuth.class).getNoAuthConnections(); + if (noAuthConnections == null) { + return nameList.iterator(); + } + while (nameIt.hasNext()) { + String conName = nameIt.next(); + if (noAuthConnections.contains(conName)) { + continue; + } + Connection connection = ConnectionKit.getConnection(conName); + filterConnection(connection, conName, nameList); + } + return nameList.iterator(); + } + + protected void filterConnection(@Nullable Connection connection, String conName, List nameList) { + if (connection != null) { + connection.addConnection(nameList, conName, new Class[]{BaseConnection.class}); + } + } + + public int getConnectionSize() { + return nameList.size(); + } + + private boolean isEmptyConnection() { + return nameList.isEmpty(); + } + + public String getConnection(int i) { + return nameList.get(i); + } + + + protected void editItems() { + final ConnectionListPane connectionListPane = new ConnectionListPane(); + final ConnectionConfig connectionConfig = ConnectionConfig.getInstance(); + ConnectionConfig cloned = connectionConfig.mirror(); + connectionListPane.populate(cloned); + final BasicDialog connectionListDialog = connectionListPane.showLargeWindow( + SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this), null); + connectionListDialog.addDialogActionListener(new DialogActionAdapter() { + public void doOk() { + if (!connectionListPane.isNamePermitted()) { + connectionListDialog.setDoOKSucceed(false); + return; + } + ConfigurationKit.modify(ConnectionConfig.class, new Runner() { + @Override + public void run() { + connectionListPane.update(connectionConfig); + } + }, new WorkerCallBack() { + @Override + public boolean beforeCommit() { + //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 + return doWithDatasourceManager(connectionConfig, connectionListPane, connectionListDialog); + } + + @Override + public void afterCommit() { + DesignKit.getDesignerBean("databasename").refreshBeanElement(); + } + + @Override + public void afterRollback() { + + } + }); + } + }); + connectionListDialog.setVisible(true); + refreshItems(); + } + + /** + * @param connection 数据库链接 + */ + public void populate(Connection connection) { + editButton.setEnabled(WorkContext.getCurrent().isRoot()); + if (connection instanceof NameReference) { + this.setSelectedItem(((NameReference) connection).getName()); + } else { + String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection(); + if (StringKit.isNotBlank(s)) { + for (int i = 0; i < this.getConnectionSize(); i++) { + String t = this.getConnection(i); + if (AssistKit.equals(s, t)) { + this.setSelectedItem(s); + break; + } + } + } + if (StringKit.isBlank(this.getSelectedItem()) && !isEmptyConnection()) { + this.setSelectedItem(this.getConnection(0)); + } + } + } + + private boolean doWithDatasourceManager(ConnectionConfig datasourceManager, ConnectionShowPane connectionShowPane, BasicDialog databaseListDialog) { + boolean isFailed = false; + //存在请重命名则不能更新 + int index = isConnectionMapContainsRename(datasourceManager); + if (index != -1) { + isFailed = true; + connectionShowPane.setSelectedIndex(index); + } + databaseListDialog.setDoOKSucceed(!isFailed); + + return !isFailed; + } + + private int isConnectionMapContainsRename(ConnectionConfig datasourceManager) { + Map tableDataMap = datasourceManager.getConnections(); + if (tableDataMap.containsKey(DataSourceConstants.ILLEGAL_NAME_HOLDER)) { + return datasourceManager.getConnectionIndex(DataSourceConstants.ILLEGAL_NAME_HOLDER); + } + return -1; } -} +} \ No newline at end of file diff --git a/src/main/java/com/fanruan/api/design/work/ReportletPane.java b/src/main/java/com/fanruan/api/design/work/ReportletPane.java index 4671429..0311bb6 100644 --- a/src/main/java/com/fanruan/api/design/work/ReportletPane.java +++ b/src/main/java/com/fanruan/api/design/work/ReportletPane.java @@ -1,4 +1,139 @@ package com.fanruan.api.design.work; -public class ReportletPane extends com.fr.design.gui.itree.filetree.ReportletPane { +import com.fanruan.api.design.DesignKit; +import com.fanruan.api.design.ui.component.UIButton; +import com.fanruan.api.design.ui.component.UITextArea; +import com.fanruan.api.design.ui.container.UIScrollPane; +import com.fanruan.api.design.util.GUICoreKit; +import com.fr.base.FRContext; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.itree.filetree.ClassFileTree; +import com.fr.design.gui.itree.filetree.TemplateFileTree; +import com.fr.file.filetree.IOFileNodeFilter; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * 模板选择视图面板 + */ +public class ReportletPane extends BasicPane { + + private TemplateFileTree templateReportletTree; + private UIScrollPane templateScrollPane; + private ClassFileTree classReportletTree; + private UIScrollPane classScrollPane; + + private UIButton switchButton; + private CardLayout card; + private JPanel cardPane; + + public ReportletPane() { + this.setLayout(new BorderLayout()); + UITextArea textPane = new UITextArea(); + this.add(textPane, BorderLayout.NORTH); + textPane.setEditable(false); + textPane.setLineWrap(true); + + textPane.setFont(FRContext.getDefaultValues().getFRFont().deriveFont(Font.BOLD, 12)); + textPane.setText(DesignKit.i18nText("Fine-Design_Basic_Schedule_The_Selected_File_Must_Be_End_With_Filter")); + + JPanel centerPane = GUICoreKit.createBorderLayoutPane(); + this.add(centerPane, BorderLayout.CENTER); + + switchButton = new UIButton("switch"); + centerPane.add(GUICoreKit.createBorderLayoutPane(switchButton, BorderLayout.WEST), BorderLayout.NORTH); + switchButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + switchCardPane(templateScrollPane.isVisible()); + } + }); + + cardPane = new JPanel(); + centerPane.add(cardPane, BorderLayout.CENTER); + cardPane.setLayout(card = new CardLayout()); + templateReportletTree = new TemplateFileTree(); + IOFileNodeFilter filter = new IOFileNodeFilter(new String[]{".cpt", ".class", ".frm", ".form"}); + templateReportletTree.setFileNodeFilter(filter); + cardPane.add(templateScrollPane = new UIScrollPane(templateReportletTree), "TEMPLATE"); + classReportletTree = new ClassFileTree(); + cardPane.add(classScrollPane = new UIScrollPane(classReportletTree), "CLASS"); + + this.refreshEnv(); + } + + /* + * 切换CardPane + */ + private void switchCardPane(boolean switch2Class) { + if (switch2Class) { + card.show(cardPane, "CLASS"); + switchButton.setText(DesignKit.i18nText("Fine-Design_Basic_Utils_Switch_To_Template_Reportlet")); + } else { + card.show(cardPane, "TEMPLATE"); + switchButton.setText(DesignKit.i18nText("Fine-Design_Basic_Utils_Switch_To_Class_Reportlet")); + } + } + + /** + * 检查是否符合规范 + * + * @throws Exception 抛错 + */ + public void checkValid() throws Exception { + String path = this.getSelectedReportletPath(); + if (path == null) { + throw new Exception(DesignKit.i18nText("Fine-Design_Basic_Function_The_Selected_File_Cannot_Be_Null")); + } + } + + + /** + * 刷新Env + */ + public void refreshEnv() { + this.templateReportletTree.refreshEnv(); + this.classReportletTree.refreshEnv(); + } + + @Override + protected String title4PopupWindow() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Reportlet"); + } + + /** + * 返回选中的模板的路径 + * + * @return 模板路径 + */ + public String getSelectedReportletPath() { + if (templateScrollPane.isVisible()) { + return templateReportletTree.getSelectedTemplatePath(); + } else if (classScrollPane.isVisible()) { + return classReportletTree.getSelectedClassPath(); + } + + return null; + } + + /** + * 根据路径设置视图中被选中的模板 + * + * @param templatePath 模板路径 + */ + public void setSelectedReportletPath(String templatePath) { + if (templatePath == null) { + return; + } + + if (templatePath.endsWith(".class")) { + switchCardPane(true); + classReportletTree.setSelectedClassPath(templatePath); + } else { + switchCardPane(false); + templateReportletTree.setSelectedTemplatePath(templatePath); + } + } } diff --git a/src/main/java/com/fanruan/api/i18n/I18nKit.java b/src/main/java/com/fanruan/api/i18n/I18nKit.java index a2f3cb1..a72f000 100644 --- a/src/main/java/com/fanruan/api/i18n/I18nKit.java +++ b/src/main/java/com/fanruan/api/i18n/I18nKit.java @@ -1,6 +1,10 @@ package com.fanruan.api.i18n; + import com.fr.locale.InterProviderFactory; +import java.util.Locale; +import java.util.Map; + public class I18nKit { /** * 获取国际化文本 @@ -11,4 +15,25 @@ public class I18nKit { public static String getLocText(String string) { return InterProviderFactory.getProvider().getLocText(string); } + + /** + * 获取国际化文本 + * + * @param string 需要国际化的值对应的键 + * @param args 变量 + * @return 返回国际化文本 + */ + public static String getLocText(String string, String... args) { + return InterProviderFactory.getProvider().getLocText(string, args); + } + + /** + * 获取某种语言下所有的国际化键值对 + * + * @param locale 国际化 + * @return 国际化键值对集合 + */ + public static Map getEntireKV(Locale locale) { + return InterProviderFactory.getClientProvider().getEntireKV(locale); + } } diff --git a/src/main/java/com/fanruan/api/net/NetworkKit.java b/src/main/java/com/fanruan/api/net/NetworkKit.java index ebc52ef..e7d859c 100644 --- a/src/main/java/com/fanruan/api/net/NetworkKit.java +++ b/src/main/java/com/fanruan/api/net/NetworkKit.java @@ -2,12 +2,14 @@ package com.fanruan.api.net; import com.fr.base.ServerConfig; import com.fr.data.NetworkHelper; +import com.fr.decision.webservice.utils.WebServiceUtils; import org.jetbrains.annotations.Nullable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; +import java.util.Locale; import java.util.Map; /** @@ -21,7 +23,7 @@ public class NetworkKit { /** * 生成一个打印输出器 * - * @param res HTTP响应 + * @param res http响应 * @return 打印输出器 * @throws java.io.IOException 如果无法创建输出器则抛出此异常 */ @@ -32,7 +34,7 @@ public class NetworkKit { /** * 生成一个打印输出器 * - * @param res HTTP响应 + * @param res http响应 * @param charsetName 编码 * @return 打印输出器 * @throws java.io.IOException 如果无法创建输出器则抛出此异常 @@ -45,7 +47,7 @@ public class NetworkKit { * 写出指定的模板 * * @param resource 模板路径 - * @param response HTTP响应 + * @param response http响应 * @param map 用于替换模板中参数的的参数集 * @throws java.io.IOException 如果无法创建输出器则抛出此异常 */ @@ -56,7 +58,7 @@ public class NetworkKit { /** * 把HTTP请求中指定名字的参数值转化为整数,参数为空或不是整数则返回-1 * - * @param req HTTP请求 + * @param req http请求 * @param paraName 参数名 * @return 整型参数值 */ @@ -67,7 +69,7 @@ public class NetworkKit { /** * 把HTTP请求中指定名字的参数值转化为整数 * - * @param req HTTP请求 + * @param req http请求 * @param paraName 参数名 * @param defaultValue 默认值 * @return 返回req中参数的整数值。参数为空或不是整数则返回defaultValue @@ -79,7 +81,7 @@ public class NetworkKit { /** * 从http请求中获取sessionID * - * @param req HTTP请求 + * @param req http请求 * @return session编号 */ public static @Nullable String getHTTPRequestSessionIDParameter(HttpServletRequest req) { @@ -89,7 +91,7 @@ public class NetworkKit { /** * 把HTTP请求中指定名字的参数值转化为布尔值 * - * @param req HTTP请求 + * @param req http请求 * @param paraName 参数名 * @return 布尔类型的参数值 */ @@ -100,7 +102,7 @@ public class NetworkKit { /** * 获取HTTP请求中指定名字的参数值 * - * @param req HTTP请求 + * @param req http请求 * @param paraName 参数名 * @return 字符型参数值 */ @@ -111,7 +113,7 @@ public class NetworkKit { /** * 获取第一个不为空的参数 * - * @param req HTTP请求 + * @param req http请求 * @param paraNames 参数列表 * @return 字符型参数值 */ @@ -119,8 +121,34 @@ public class NetworkKit { return NetworkHelper.getHTTPRequestParameter(req, paraNames); } - + /** + * 生成服务器地址 + * + * @param req http请求 + * @return 服务器地址 + */ public static String createServletURL(HttpServletRequest req) { return NetworkHelper.createServletURL(req, ServerConfig.getInstance().getServletName()); } + + /** + * 从http请求中获取用户的国际化信息 + * + * @param req http请求 + * @return 国际化对象 + */ + public static Locale getLocale(HttpServletRequest req) { + return WebServiceUtils.getLocale(req); + } + + /** + *获取HTTP请求中指定名字的参数值 + * @param req 请求 + * @param encode 是否编码 + * @param paraName 参数名 + * @return 参数值 + * */ + public static String getHTTPRequestEncodeParameter(HttpServletRequest req, String paraName, boolean encode) { + return NetworkHelper.getHTTPRequestEncodeParameter(req, paraName, encode); + } } diff --git a/src/main/java/com/fanruan/api/report/form/BaseWidget.java b/src/main/java/com/fanruan/api/report/form/BaseWidget.java index 703fad3..3483a54 100644 --- a/src/main/java/com/fanruan/api/report/form/BaseWidget.java +++ b/src/main/java/com/fanruan/api/report/form/BaseWidget.java @@ -1,7 +1,6 @@ package com.fanruan.api.report.form; import com.fr.data.act.Describer; -import com.fr.data.act.Producer; import com.fr.form.ui.Widget; import com.fr.json.JSONException; import com.fr.json.JSONObject; @@ -13,9 +12,9 @@ import com.fr.stable.web.Repository; * @author richie * @version 10.0 * Created by richie on 2019-09-10 - * 控件的插件接口 + * 控件接口,如果控件支持"控件值"属性,则需要实现接口 {@link com.fr.form.ui.DataControl} */ -public abstract class BaseWidget extends Widget implements Describer, Producer { +public abstract class BaseWidget extends Widget implements Describer { @Override public boolean isEditor() { @@ -23,7 +22,7 @@ public abstract class BaseWidget extends Widget implements Describer, Producer { } @Override - public JSONObject createJSONConfig(Repository repository, Calculator calculator, NodeVisitor nodeVisitor) throws JSONException { + public final JSONObject createJSONConfig(Repository repository, Calculator calculator, NodeVisitor nodeVisitor) throws JSONException { JSONObject jo = super.createJSONConfig(repository, calculator, nodeVisitor); mixinJSON(repository, calculator, jo); return jo; diff --git a/src/main/java/com/fanruan/api/report/form/category/LoadingWidget.java b/src/main/java/com/fanruan/api/report/form/category/LoadingWidget.java new file mode 100644 index 0000000..bc5eaf6 --- /dev/null +++ b/src/main/java/com/fanruan/api/report/form/category/LoadingWidget.java @@ -0,0 +1,14 @@ +package com.fanruan.api.report.form.category; + +import com.fanruan.api.report.form.BaseWidget; +import com.fr.data.act.Producer; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 初始化的时候除了配置,还会有加载数据的控件,典型的控件如下拉框、下拉树、复选框组等 + */ +public abstract class LoadingWidget extends BaseWidget implements Producer { + +} diff --git a/src/main/java/com/fanruan/api/report/form/category/PlainWidget.java b/src/main/java/com/fanruan/api/report/form/category/PlainWidget.java new file mode 100644 index 0000000..199f509 --- /dev/null +++ b/src/main/java/com/fanruan/api/report/form/category/PlainWidget.java @@ -0,0 +1,17 @@ +package com.fanruan.api.report.form.category; + +import com.fanruan.api.report.form.BaseWidget; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 初始化时只有配置的控件,没有数据设置,典型的比如按钮、标签等 + */ +public abstract class PlainWidget extends BaseWidget { + + @Override + public boolean isEditor() { + return false; + } +} diff --git a/src/main/java/com/fanruan/api/report/script/JavaScriptKit.java b/src/main/java/com/fanruan/api/report/script/JavaScriptKit.java new file mode 100644 index 0000000..385f3d9 --- /dev/null +++ b/src/main/java/com/fanruan/api/report/script/JavaScriptKit.java @@ -0,0 +1,23 @@ +package com.fanruan.api.report.script; + +import com.fr.js.JavaScript; +import com.fr.js.JavaScriptImpl; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019/9/20 + * 从服务器端生成给web端使用的javascript代码的工具类 + */ +public class JavaScriptKit { + + /** + * 生成一个简单的JavaScript实例 + * + * @param content 脚本内容 + * @return JavaScript实例 + */ + public JavaScript newSimpleJavaScript(String content) { + return new JavaScriptImpl(content); + } +} diff --git a/src/main/java/com/fanruan/api/runtime/ResourceKit.java b/src/main/java/com/fanruan/api/runtime/ResourceKit.java new file mode 100644 index 0000000..3bb638e --- /dev/null +++ b/src/main/java/com/fanruan/api/runtime/ResourceKit.java @@ -0,0 +1,219 @@ +package com.fanruan.api.runtime; + +import com.fr.io.utils.ResourceIOUtils; +import com.fr.stable.Filter; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 操作运行环境下文件的工具方法 + */ +public class ResourceKit { + + /** + * 路径是否存在 + * + * @param target 路径 + * @return 是否存在 + */ + public static boolean exist(String target) { + return ResourceIOUtils.exist(target); + } + + /** + * 创建文件 + * + * @param file 文件路径 + * @return 是否存在 + */ + public static boolean createFile(String file) { + return ResourceIOUtils.createFile(file); + } + + /** + * 创建文件夹 + * + * @param dir 文件夹路径 + * @return 是否成功 + */ + public static boolean createDirectory(String dir) { + return ResourceIOUtils.createDirectory(dir); + } + + /** + * 是否为文件夹 + * + * @param path 路径 + * @return 是否是文件夹 + */ + public static boolean isDirectory(String path) { + return ResourceIOUtils.isDirectory(path); + } + + /** + * 获取文件或者文件夹的名称 + * + * @param path 路径 + * @return 名称 + */ + public static String getName(String path) { + return ResourceIOUtils.getName(path); + } + + /** + * 列出路径下的所有内容的名称 + * + * @param dir 路径 + * @return 所有内容名称List + */ + public static String[] list(String dir) { + return ResourceIOUtils.list(dir); + } + + /** + * 列出路径下的所有符合要求的内容的名称 + * + * @param dir 路径 + * @param filter 过滤器 + * @return 所有内容名称List + */ + public static String[] list(String dir, Filter filter) { + return ResourceIOUtils.list(dir, filter); + } + + /** + * 文件夹是否存在 + * + * @param dir 文件夹 + * @return 是否存在 + */ + public static boolean isDirectoryExist(String dir) { + return ResourceIOUtils.isDirectoryExist(dir); + } + + + public static String getRealPath(String relativePath) { + return ResourceIOUtils.getRealPath(relativePath); + } + + /** + * 读取文件到流 + *

+ * 相对路径下如果是仓库资源从仓库读取,其它从本地读取 + *

+ * 据对路径按绝对路径读 + * + * @param path 路径 + * @return 流 + */ + public static InputStream read(String path) { + return ResourceIOUtils.read(path); + } + + /** + * 读取文件到bytes + * + * @param path 文件路径 + * @return bytes + */ + public static byte[] readBytes(String path) { + return ResourceIOUtils.readBytes(path); + } + + /** + * 写入数据流到文件 + * + * @param path 文件路径 + * @param data 数据 + */ + public static void write(String path, InputStream data) { + ResourceIOUtils.write(path, data); + } + + /** + * 写入字符串数据到文件 + * + * @param path 文件路径 + * @param data 数据 + */ + public static void write(String path, String data) { + ResourceIOUtils.write(path, data); + } + + /** + * 写入字节数组数据到文件 + * + * @param path 文件路径 + * @param data 数据 + */ + public static void write(String path, byte[] data) { + ResourceIOUtils.write(path, data); + } + + /** + * 获取父路径 + * + * @param path 路径 + * @return 父路径 + */ + public static String getParent(String path) { + return ResourceIOUtils.getParent(path); + } + + /** + * 从仓库删除 + * + * @param path 路径 + * @return 是否删除成功 + */ + public static boolean delete(String path) { + return ResourceIOUtils.delete(path); + } + + /** + * 文件的最后修改时间 + * + * @param path 文件路径 + * @return 修改的时间戳 + */ + public static long lastModified(String path) { + return ResourceIOUtils.lastModified(path); + } + + /** + * 文件大小 + * + * @param path 文件路径 + * @return 文件字节数 + */ + public static long getLength(String path) { + return ResourceIOUtils.getLength(path); + } + + /** + * 重命名 + *

+ * 文件位置根据oldFile来确定 + * + * @param oldFile 原文件path + * @param newFile 新文件path + * @return 是否成功 + */ + public static boolean renameTo(String oldFile, String newFile) { + return ResourceIOUtils.renameTo(oldFile, newFile); + } + + /** + * 拷贝文件到某目录下 + * + * @param src 源文件 + * @param dir 目标文件 + */ + public static void copy(String src, String dir) throws IOException { + ResourceIOUtils.copy(src, dir); + } +} diff --git a/src/main/java/com/fanruan/api/session/SessionKit.java b/src/main/java/com/fanruan/api/session/SessionKit.java index 55c00bc..9f0091c 100644 --- a/src/main/java/com/fanruan/api/session/SessionKit.java +++ b/src/main/java/com/fanruan/api/session/SessionKit.java @@ -1,10 +1,17 @@ package com.fanruan.api.session; +import com.fr.stable.script.NameSpace; import com.fr.stable.web.SessionProvider; +import com.fr.web.core.ReportSessionIDInfor; import com.fr.web.core.SessionPoolManager; +import com.fr.web.session.SessionIDInfo; +import com.fr.web.utils.WebUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + /** * @author richie * @version 10.0 @@ -20,4 +27,22 @@ public class SessionKit { public static @Nullable SessionProvider getSession(@NotNull String sessionID) { return SessionPoolManager.getSessionIDInfor(sessionID, SessionProvider.class); } + + /** + * 生成一个关于回话的用于计算的名字空间 + * @param sessionId 会话ID + * @return 名字空间 + * */ + public static NameSpace asNameSpace(String sessionId) { + return SessionIDInfo.asNameSpace(sessionId); + } + + /** + * 将HTTPServletRequest中的所有参数都读取出来,存储在一个Map中,返回出去 + * @param req 请求 + * @return 参数的map + * */ + public static Map parameters4SessionIDInfor(HttpServletRequest req){ + return WebUtils.parameters4SessionIDInfor(req); + } } diff --git a/src/main/java/com/fanruan/api/util/ArrayKit.java b/src/main/java/com/fanruan/api/util/ArrayKit.java index 5df74b7..ac62c64 100644 --- a/src/main/java/com/fanruan/api/util/ArrayKit.java +++ b/src/main/java/com/fanruan/api/util/ArrayKit.java @@ -55,7 +55,16 @@ public class ArrayKit { * @param array 源数组 * @return 返回数组判断为空的结果 */ - public static boolean isEmpty(Object[] array) { + public static boolean isEmpty(T[] array) { + return ArrayUtils.isEmpty(array); + } + /** + * 判断数组是否为空 + * + * @param array 源数组 + * @return 返回数组判断为空的结果 + */ + public static boolean isEmpty(boolean[] array) { return ArrayUtils.isEmpty(array); } /** diff --git a/src/main/java/com/fanruan/api/util/CodeKit.java b/src/main/java/com/fanruan/api/util/CodeKit.java index 84f6e45..4f1265c 100644 --- a/src/main/java/com/fanruan/api/util/CodeKit.java +++ b/src/main/java/com/fanruan/api/util/CodeKit.java @@ -12,6 +12,14 @@ public class CodeKit { public static String passwordDecode(String passwordText) { return CodeUtils.passwordDecode(passwordText); } + /** + * 将普通的java字符串编码成javascript代码 + * @param string4javascript 待编码的字符串 + * @return 编码后的代码 + * */ + public static String javascriptEncode(String string4javascript) { + return CommonCodeUtils.javascriptEncode(string4javascript); + } /** * 将经过处理的中日韩文字符串解码成原先的中日韩文 diff --git a/src/main/java/com/fanruan/api/util/GeneralKit.java b/src/main/java/com/fanruan/api/util/GeneralKit.java index 60d642b..9c6dc15 100644 --- a/src/main/java/com/fanruan/api/util/GeneralKit.java +++ b/src/main/java/com/fanruan/api/util/GeneralKit.java @@ -96,6 +96,13 @@ public class GeneralKit { public static Locale getLocale() { return FRContext.getLocale(); } - + /** + * 将路径节点数组用路径分隔符"/"连接起来 + * @param nodes 路径节点数组 + * @return 连接后的路径 + * */ + public static String pathJoin(String... nodes) { + return StableUtils.pathJoin(nodes); + } } diff --git a/src/main/java/com/fanruan/api/util/RenderKit.java b/src/main/java/com/fanruan/api/util/RenderKit.java index bd5d003..65d27f7 100644 --- a/src/main/java/com/fanruan/api/util/RenderKit.java +++ b/src/main/java/com/fanruan/api/util/RenderKit.java @@ -33,5 +33,4 @@ public class RenderKit { public static String render(String s, Calculator c) throws Exception { return TemplateUtils.render(s, c); } - } diff --git a/src/main/java/com/fanruan/api/web/FlushKit.java b/src/main/java/com/fanruan/api/web/FlushKit.java new file mode 100644 index 0000000..70de44a --- /dev/null +++ b/src/main/java/com/fanruan/api/web/FlushKit.java @@ -0,0 +1,53 @@ +package com.fanruan.api.web; + +import com.fanruan.api.net.NetworkKit; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; + +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 将内容输入到输出流中 + */ +public class FlushKit { + + /** + * 输出JSON类型的字符串 + * + * @param res HTTP响应 + * @param jo JSON对象 + * @throws Exception 输出出现错误则抛出此异常 + */ + public static void printAsJSON(HttpServletResponse res, JSONObject jo) throws Exception { + printAsString(res, jo.toString()); + } + + /** + * 输出JSON类型的字符串 + * + * @param res HTTP响应 + * @param ja JSON数组对象 + * @throws Exception 输出出现错误则抛出此异常 + */ + public static void printAsJSON(HttpServletResponse res, JSONArray ja) throws Exception { + printAsString(res, ja.toString()); + } + + /** + * 输出字符串,一般来说是JSON格式 + * + * @param res HTTP响应 + * @param jo JSON样式的字符串 + * @throws Exception 输出出现错误则抛出此异常 + */ + public static void printAsString(HttpServletResponse res, String jo) throws Exception { + PrintWriter pw = NetworkKit.createPrintWriter(res); + pw.print(jo); + pw.flush(); + pw.close(); + } +} diff --git a/src/main/java/com/fanruan/api/web/ResponseKit.java b/src/main/java/com/fanruan/api/web/ResponseKit.java new file mode 100644 index 0000000..28663c7 --- /dev/null +++ b/src/main/java/com/fanruan/api/web/ResponseKit.java @@ -0,0 +1,64 @@ +package com.fanruan.api.web; + +import com.fr.decision.webservice.Response; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + * 响应工具类 + */ +public class ResponseKit { + + /** + * 成功的响应,关注结果 + * + * @param obj 响应结果 + * @return 响应 + */ + public static Object ok(Object obj) { + return Response.ok(obj); + } + + /** + * 成功的响应,不关注结果 + * + * @return 响应 + */ + public static Object success() { + return Response.success(); + } + + /** + * 成功的响应,关注操作成功条目数 + * + * @param successNum 操作成功的条目数 + * @return 响应 + */ + public static Object success(int successNum) { + return Response.success(successNum); + } + + /** + * 失败的响应 + * + * @param errorCode 错误码 + * @param errorMsg 错误信息 + * @return 响应 + */ + public static Object error(String errorCode, String errorMsg) { + return Response.error(errorCode, errorMsg); + } + + /** + * 失败的响应 + * + * @param status 状态码 + * @param errorCode 错误码 + * @param errorMsg 错误信息 + * @return 响应 + */ + public static Object error(int status, String errorCode, String errorMsg) { + return Response.error(status, errorCode, errorMsg); + } +} diff --git a/src/main/java/com/fanruan/api/web/TextGeneratorKit.java b/src/main/java/com/fanruan/api/web/TextGeneratorKit.java new file mode 100644 index 0000000..b1a279c --- /dev/null +++ b/src/main/java/com/fanruan/api/web/TextGeneratorKit.java @@ -0,0 +1,21 @@ +package com.fanruan.api.web; + +import com.fr.decision.web.i18n.I18nTextGenerator; +import com.fr.gen.TextGenerator; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-09-19 + */ +public class TextGeneratorKit { + + /** + * 创建一个用于国际化的文本输出器 + * + * @return 文本输出器 + */ + public static TextGenerator newI18nTextGenerator() { + return new I18nTextGenerator(); + } +} diff --git a/src/main/java/com/fanruan/api/xml/XmlKit.java b/src/main/java/com/fanruan/api/xml/XmlKit.java index 9d74d58..e69c136 100644 --- a/src/main/java/com/fanruan/api/xml/XmlKit.java +++ b/src/main/java/com/fanruan/api/xml/XmlKit.java @@ -8,6 +8,7 @@ import com.fr.stable.xml.XMLReadable; import com.fr.stable.xml.XMLTools; import com.fr.stable.xml.XMLable; import com.fr.stable.xml.XMLableReader; +import com.fr.stable.xml.XMLWriter; import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.StableXMLUtils; @@ -78,7 +79,14 @@ public class XmlKit { public static void writeXMLConnection(XMLPrintWriter writer, Connection connection) { DataCoreXmlUtils.writeXMLConnection(writer, connection); } - + /** + * 把一个XMLable写成字符串 + * @param xmlable xml文件 + * @return 返回字符串 + * */ + public static String writeXMLableAsString(XMLWriter xmlable) { + return GeneralXMLTools.writeXMLableAsString(xmlable); + } /** * 读出xml参数 * @@ -96,4 +104,13 @@ public class XmlKit { public static void writeParameters(XMLPrintWriter writer, ParameterProvider[] parameter) { StableXMLUtils.writeParameters(writer,parameter); } + + /** + * 以xml方式读string + * @param xmlString xml字符串 + * @return xml文件 + * */ + public static XMLReadable readStringAsXMLable(String xmlString) { + return GeneralXMLTools.readStringAsXMLable(xmlString); + } } diff --git a/src/main/resources/com/fanruan/api/locale.properties b/src/main/resources/com/fanruan/api/locale.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fanruan/api/locale_en_US.properties b/src/main/resources/com/fanruan/api/locale_en_US.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fanruan/api/locale_ja_JP.properties b/src/main/resources/com/fanruan/api/locale_ja_JP.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fanruan/api/locale_ko_KR.properties b/src/main/resources/com/fanruan/api/locale_ko_KR.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fanruan/api/locale_zh_CN.properties b/src/main/resources/com/fanruan/api/locale_zh_CN.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fanruan/api/locale_zh_TW.properties b/src/main/resources/com/fanruan/api/locale_zh_TW.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/com/fanruan/api/net/NetworkKitTest.java b/src/test/java/com/fanruan/api/net/NetworkKitTest.java index b8c5328..3205c6e 100644 --- a/src/test/java/com/fanruan/api/net/NetworkKitTest.java +++ b/src/test/java/com/fanruan/api/net/NetworkKitTest.java @@ -48,4 +48,8 @@ public class NetworkKitTest extends Prepare { @Test public void testGetHTTPRequestParameter() { } + + @Test + public void getHTTPRequestEncodeParameter() { + } } \ No newline at end of file diff --git a/src/test/java/com/fanruan/api/util/ArrayKitTest.java b/src/test/java/com/fanruan/api/util/ArrayKitTest.java index 45c6096..4803a7c 100644 --- a/src/test/java/com/fanruan/api/util/ArrayKitTest.java +++ b/src/test/java/com/fanruan/api/util/ArrayKitTest.java @@ -11,9 +11,40 @@ public class ArrayKitTest extends Prepare { public void isEmpty() throws Exception{ Object[] emptyArray = new Object[0]; Object[] notEmptyArray = new Object[1]; + Boolean[] booleanEmptyArray = new Boolean[0]; + Boolean[] booleanNotEmptyArray = new Boolean[1]; + Byte[] byteEmptyArray = new Byte[0]; + Byte[] byteNotEmptyArray = new Byte[1]; + Character[] charEmptyArray = new Character[0]; + Character[] charNotEmptyArray = new Character[1]; + Double[] doubleEmptyArray = new Double[0]; + Double[] doubleNotEmptyArray = new Double[1]; + Float[] floatEmptyArray = new Float[0]; + Float[] floatNotEmptyArray = new Float[1]; + Integer[] intEmptyArray = new Integer[0]; + Integer[] intNotEmptyArray = new Integer[1]; + Long[] longEmptyArray = new Long[0]; + Long[] longNotEmptyArray = new Long[1]; + Short[] shortEmptyArray = new Short[0]; + Short[] shortNotEmptyArray = new Short[1]; Assert.assertTrue(ArrayKit.isEmpty(emptyArray)); Assert.assertFalse(ArrayKit.isEmpty(notEmptyArray)); - + Assert.assertTrue(ArrayKit.isEmpty(booleanEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(booleanNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(byteEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(byteNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(charEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(charNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(doubleEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(doubleNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(floatEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(floatNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(intEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(intNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(longEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(longNotEmptyArray)); + Assert.assertTrue(ArrayKit.isEmpty(shortEmptyArray)); + Assert.assertFalse(ArrayKit.isEmpty(shortNotEmptyArray)); } @Test diff --git a/src/test/java/com/fanruan/api/util/CodeKitTest.java b/src/test/java/com/fanruan/api/util/CodeKitTest.java index af99858..400a2b2 100644 --- a/src/test/java/com/fanruan/api/util/CodeKitTest.java +++ b/src/test/java/com/fanruan/api/util/CodeKitTest.java @@ -7,8 +7,8 @@ import org.junit.Test; public class CodeKitTest { @Test - public void passwordDecode(String passwordText) { - Assert.assertEquals(CodeKit.passwordDecode(passwordText), 123); + public void javascriptEncode() { + Assert.assertEquals(CodeKit.javascriptEncode("console.log(123)"), "console.log(123)"); } @Test diff --git a/src/test/java/com/fanruan/api/util/GeneralKitTest.java b/src/test/java/com/fanruan/api/util/GeneralKitTest.java index 6ba3bf6..12882ee 100644 --- a/src/test/java/com/fanruan/api/util/GeneralKitTest.java +++ b/src/test/java/com/fanruan/api/util/GeneralKitTest.java @@ -55,4 +55,10 @@ public class GeneralKitTest extends Prepare { Assert.assertEquals(GeneralKit.getLocale(), Locale.CHINA); } + @Test + public void pathJoin(){ + String strArray[] = {"abc", "def"}; + Assert.assertEquals(GeneralKit.pathJoin(strArray), "abc/def"); + } + } \ No newline at end of file