forked from fanruan/finekit
白岳
5 years ago
47 changed files with 1349 additions and 44 deletions
@ -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,包括但不限于:用户管理、登入登出、权限管理、模板管理等。 |
@ -0,0 +1,11 @@
|
||||
package com.fanruan.api.decision; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-19 |
||||
* 权限相关的工具类 |
||||
*/ |
||||
public class AuthorityKit { |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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<T extends Passport> extends PassportBean<T> { |
||||
|
||||
/** |
||||
* 用于标记认证类型的字符串 |
||||
* |
||||
* @return 字符串 |
||||
*/ |
||||
@Override |
||||
public abstract String markType(); |
||||
|
||||
/** |
||||
* 根据配置对象生成认证配置数据层对象 |
||||
* |
||||
* @param t 配置对象 |
||||
* @return 配属数据层 |
||||
*/ |
||||
@Override |
||||
public abstract BasePassportBean<T> createPassportBean(T t); |
||||
|
||||
/** |
||||
* 生成配置对象 |
||||
* |
||||
* @return 配置 |
||||
*/ |
||||
@Override |
||||
public abstract Passport createPassport(); |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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()); |
||||
} |
||||
} |
@ -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; |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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<T extends TableData> extends AbstractTableDataPane<T> { |
||||
|
||||
} |
@ -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<? extends Connection> cls; |
||||
private List<String> nameList = new ArrayList<>(); |
||||
|
||||
public class ConnectionComboBoxPanel extends com.fr.design.data.datapane.connect.ConnectionComboBoxPanel{ |
||||
public ConnectionComboBoxPanel(Class<? extends Connection> 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<String> items() { |
||||
nameList = new ArrayList<>(); |
||||
Iterator<String> nameIt = ConnectionKit.getConnections().keySet().iterator(); |
||||
Collection<String> 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<String> 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<String, Connection> tableDataMap = datasourceManager.getConnections(); |
||||
if (tableDataMap.containsKey(DataSourceConstants.ILLEGAL_NAME_HOLDER)) { |
||||
return datasourceManager.getConnectionIndex(DataSourceConstants.ILLEGAL_NAME_HOLDER); |
||||
} |
||||
return -1; |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
|
@ -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 { |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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<String> 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); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到流 |
||||
* <p> |
||||
* 相对路径下如果是仓库资源从仓库读取,其它从本地读取 |
||||
* <p> |
||||
* 据对路径按绝对路径读 |
||||
* |
||||
* @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); |
||||
} |
||||
|
||||
/** |
||||
* 重命名 |
||||
* <p> |
||||
* 文件位置根据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); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
Loading…
Reference in new issue