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; |
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.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) { |
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; |
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