Palin
5 years ago
53 changed files with 1439 additions and 77 deletions
@ -0,0 +1,41 @@
|
||||
# 非FineKit中的Open类 |
||||
|
||||
com.fr.script.AbstractFunction |
||||
|
||||
com.fr.script.Calculator |
||||
|
||||
com.fr.general.FRFont |
||||
|
||||
com.fr.base.BaseFormula |
||||
|
||||
com.fr.base.Style |
||||
|
||||
com.fr.plugin.ExtraClassManager |
||||
|
||||
com.fr.stable.Primitive |
||||
|
||||
com.fr.stable.os.AbstractOperatingSystem |
||||
|
||||
com.fr.stable.os.Arch |
||||
|
||||
com.fr.stable.os.OperatingSystem |
||||
|
||||
com.fr.plugin.context.PluginContexts |
||||
|
||||
com.fr.config.Status |
||||
|
||||
com.fr.config.holder.Conf |
||||
|
||||
com.fr.stable.ColumnRow |
||||
|
||||
com.fr.web.struct.AssembleComponent |
||||
|
||||
com.fr.web.struct.BaseFilter |
||||
|
||||
com.fr.web.struct.Component |
||||
|
||||
com.fr.web.struct.Registry |
||||
|
||||
com.fr.web.struct.category.ScriptPath |
||||
|
||||
com.fr.web.struct.category.StylePath |
@ -1,41 +0,0 @@
|
||||
package com.fanruan.api.conf; |
||||
|
||||
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.WorkerFacade; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-30 |
||||
* 配置监听管理器 |
||||
*/ |
||||
public class ConfigurationKit { |
||||
|
||||
/** |
||||
* 注册监听配置变化的监听器 |
||||
* |
||||
* @param listener 监听器 |
||||
*/ |
||||
public static void registerListener(ConfigChangeListener listener) { |
||||
ValidateProxy.getInstance().getValidateManager().registerListener(listener); |
||||
} |
||||
|
||||
/** |
||||
* 保存配置 |
||||
* |
||||
* @param type 配置的类型 |
||||
* @param action 保存动作 |
||||
*/ |
||||
public static void modify(Class<? extends Configuration> type, Runner action) { |
||||
Configurations.modify(new WorkerFacade(type) { |
||||
@Override |
||||
public void run() { |
||||
action.run(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,51 @@
|
||||
package com.fanruan.api.data.open; |
||||
|
||||
import com.fanruan.api.util.ArrayKit; |
||||
import com.fr.data.impl.AbstractDatabaseConnection; |
||||
import com.fr.data.impl.Connection; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-06 |
||||
* 用于数据连接插件的抽象类 |
||||
*/ |
||||
public abstract class BaseConnection extends AbstractDatabaseConnection { |
||||
|
||||
/** |
||||
* 测试连接 |
||||
* |
||||
* @throws Exception 异常 |
||||
*/ |
||||
@Override |
||||
public abstract void testConnection() throws Exception; |
||||
|
||||
/** |
||||
* 创建连接 |
||||
* |
||||
* @return 返回连接 |
||||
* @throws Exception 异常 |
||||
*/ |
||||
@Override |
||||
public java.sql.Connection createConnection() throws Exception { |
||||
return Connection.IGNORE; |
||||
} |
||||
|
||||
/** |
||||
* 连接成功或失败时给出的信息 |
||||
* |
||||
* @return 信息 |
||||
*/ |
||||
@Override |
||||
public abstract String connectMessage(boolean status); |
||||
|
||||
|
||||
/** |
||||
* 获取数据连接的摘要信息 |
||||
* |
||||
* @return 摘要 |
||||
*/ |
||||
public String[] summary(String... args) { |
||||
return ArrayKit.EMPTY_STRING_ARRAY; |
||||
} |
||||
} |
@ -0,0 +1,60 @@
|
||||
package com.fanruan.api.data.open; |
||||
|
||||
import com.fanruan.api.err.TableDataException; |
||||
import com.fr.data.AbstractDataModel; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-04 |
||||
* 二维表模型 |
||||
*/ |
||||
public abstract class BaseDataModel extends AbstractDataModel { |
||||
|
||||
/** |
||||
* 获取数据集的列数 |
||||
* |
||||
* @return 列数 |
||||
* @throws TableDataException 如果获取数据集列数失败,则抛出此异常 |
||||
*/ |
||||
@Override |
||||
public abstract int getColumnCount() throws TableDataException; |
||||
|
||||
/** |
||||
* 获取数据集指定列的列名 |
||||
* |
||||
* @param rowIndex 列序号 |
||||
* @return 类名 |
||||
* @throws TableDataException 如果获取列名失败,则抛出此异常 |
||||
*/ |
||||
@Override |
||||
public abstract String getColumnName(int rowIndex) throws TableDataException; |
||||
|
||||
/** |
||||
* 湖区数据集的行数 |
||||
* |
||||
* @return 行数 |
||||
* @throws TableDataException 如果获取数据集行数失败,则抛出此异常 |
||||
*/ |
||||
@Override |
||||
public abstract int getRowCount() throws TableDataException; |
||||
|
||||
/** |
||||
* 获取数据集中指定位置的值 |
||||
* |
||||
* @param rowIndex 行 |
||||
* @param columnIndex 列 |
||||
* @return 值 |
||||
* @throws TableDataException 如果获取值失败,则抛出此异常 |
||||
*/ |
||||
@Override |
||||
public abstract Object getValueAt(int rowIndex, int columnIndex) throws TableDataException; |
||||
|
||||
/** |
||||
* 释放一些构建数据集过程中占用的资源 |
||||
* |
||||
* @throws Exception 释放资源时发生错误,则抛出此异常 |
||||
*/ |
||||
@Override |
||||
public abstract void release() throws Exception; |
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.fanruan.api.data.open; |
||||
|
||||
import com.fr.data.AbstractParameterTableData; |
||||
import com.fr.general.data.DataModel; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.ParameterProvider; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-04 |
||||
* 插件的数据集接口 |
||||
*/ |
||||
public abstract class BaseTableData extends AbstractParameterTableData { |
||||
|
||||
/** |
||||
* 实现这个方法来返回一个数据集 |
||||
* |
||||
* @param calculator 算子 |
||||
* @return 数据集二维表对象 |
||||
*/ |
||||
@Override |
||||
public abstract DataModel createDataModel(Calculator calculator); |
||||
|
||||
/** |
||||
* 返回获取数据的执行对象 |
||||
* 系统取数时,调用此方法来返回一个获取数据的执行对象 |
||||
* 注意! 当数据集需要根据不同参数来多次取数时,此方法在一个计算过程中会被多次调用。 |
||||
* |
||||
* @param calculator 算子 |
||||
* @param rowCount 要获取数据的行数 |
||||
* @return 数据集二维表对象 |
||||
*/ |
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator, int rowCount) { |
||||
return createDataModel(calculator); |
||||
} |
||||
|
||||
/** |
||||
* 返回获取数据的执行对象 |
||||
* 系统取数时,调用此方法来返回一个获取数据的执行对象 |
||||
* 注意! 当数据集需要根据不同参数来多次取数时,此方法在一个计算过程中会被多次调用。 |
||||
* |
||||
* @param calculator 算子 |
||||
* @param name 数据集的名字 |
||||
* @return 数据集二维表对象 |
||||
*/ |
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator, String name) { |
||||
return createDataModel(calculator); |
||||
} |
||||
|
||||
/** |
||||
* 获取数据集中定义的参数 |
||||
* |
||||
* @param calculator 算子 |
||||
* @return 参数数组 |
||||
*/ |
||||
@Override |
||||
public ParameterProvider[] getParameters(Calculator calculator) { |
||||
return super.getParameters(calculator); |
||||
} |
||||
} |
@ -0,0 +1,26 @@
|
||||
package com.fanruan.api.design.ui.component; |
||||
|
||||
import javax.swing.*; |
||||
import java.util.Vector; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 列表组件 |
||||
*/ |
||||
public class UIList extends com.fr.design.gui.ilist.UIList { |
||||
|
||||
public UIList(ListModel dataModel) { |
||||
super(dataModel); |
||||
} |
||||
|
||||
public UIList(Object[] listData) { |
||||
super(listData); |
||||
} |
||||
|
||||
public UIList(Vector<?> listData) { |
||||
super(listData); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,87 @@
|
||||
package com.fanruan.api.design.ui.component.present; |
||||
|
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fr.data.Dictionary; |
||||
import com.fr.data.impl.DynamicSQLDict; |
||||
import com.fr.design.beans.FurtherBasicBeanPane; |
||||
import com.fr.design.constants.LayoutConstants; |
||||
import com.fr.design.data.DataCreatorUI; |
||||
import com.fr.design.gui.frpane.UIComboBoxPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.present.dict.CustomDictPane; |
||||
import com.fr.design.present.dict.DatabaseDictPane; |
||||
import com.fr.design.present.dict.FormulaDictPane; |
||||
import com.fr.design.present.dict.TableDataDictPane; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 数据字典容器,获取数据字典 |
||||
*/ |
||||
public class DictionaryPane extends UIComboBoxPane<Dictionary> implements DataCreatorUI { |
||||
private TableDataDictPane tableDataDictPane; |
||||
|
||||
@Override |
||||
protected void initLayout() { |
||||
this.setLayout(new BorderLayout(0, 4)); |
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] columnSize = {p, f}; |
||||
double[] rowSize = {p, p}; |
||||
int[][] rowCount = {{1, 1}, {1, 1}}; |
||||
|
||||
Component[][] components = new Component[][]{ |
||||
new Component[]{new UILabel(DesignKit.i18nText("Fine-Design_Basic_Type_Set"), UILabel.LEFT), jcb}, |
||||
new Component[]{null, null} |
||||
}; |
||||
JPanel northPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_HUGER, LayoutConstants.VGAP_MEDIUM); |
||||
this.add(northPane, BorderLayout.NORTH); |
||||
this.add(cardPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return DesignKit.i18nText("Fine-Design_Form_DS_Dictionary"); |
||||
} |
||||
|
||||
@Override |
||||
public JComponent toSwingComponent() { |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(Dictionary ob) { |
||||
for (int i = 0; i < this.cards.size(); i++) { |
||||
FurtherBasicBeanPane pane = cards.get(i); |
||||
if (pane.accept(ob)) { |
||||
pane.populateBean(ob); |
||||
jcb.setSelectedIndex(i); |
||||
} else { |
||||
pane.reset(); |
||||
} |
||||
} |
||||
if (ob instanceof DynamicSQLDict) { |
||||
jcb.setSelectedIndex(1); |
||||
tableDataDictPane.populateBean((DynamicSQLDict) ob); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected List<FurtherBasicBeanPane<? extends Dictionary>> initPaneList() { |
||||
List<FurtherBasicBeanPane<? extends Dictionary>> paneList = new ArrayList<FurtherBasicBeanPane<? extends Dictionary>>(); |
||||
paneList.add(new DatabaseDictPane()); |
||||
paneList.add(tableDataDictPane = new TableDataDictPane()); |
||||
paneList.add(new CustomDictPane()); |
||||
paneList.add(new FormulaDictPane()); |
||||
return paneList; |
||||
} |
||||
} |
@ -1,4 +0,0 @@
|
||||
package com.fanruan.api.design.ui.container; |
||||
|
||||
public abstract class BasicBeanPane<T> extends com.fr.design.beans.BasicBeanPane<T> { |
||||
} |
@ -0,0 +1,15 @@
|
||||
package com.fanruan.api.design.work.form.basic; |
||||
|
||||
import com.fr.design.mainframe.widget.accessibles.AccessibleEditor; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 可以通过按钮或其他方式进去编辑面板的编辑器 |
||||
*/ |
||||
public class AccessiblePropertyEditor extends com.fr.design.mainframe.widget.accessibles.AccessiblePropertyEditor { |
||||
public AccessiblePropertyEditor(AccessibleEditor editor) { |
||||
super(editor); |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
package com.fanruan.api.design.work.form.basic; |
||||
|
||||
import com.fr.design.designer.properties.Encoder; |
||||
import com.fr.design.mainframe.widget.renderer.GenericCellRenderer; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 根据控件属性渲染单元格 |
||||
*/ |
||||
public class EncoderCellRenderer extends GenericCellRenderer { |
||||
|
||||
private static int LEFT = 1; |
||||
protected Encoder encoder; |
||||
protected Object value; |
||||
|
||||
public EncoderCellRenderer(Encoder encoder) { |
||||
this.encoder = encoder; |
||||
} |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
int width = getWidth(); |
||||
int height = getHeight(); |
||||
g.setColor(getBackground()); |
||||
g.fillRect(0, 0, width, height); |
||||
|
||||
int x = LEFT; |
||||
g.setColor(getForeground()); |
||||
|
||||
FontMetrics fm = g.getFontMetrics(); |
||||
int y = ((height - fm.getHeight()) / 2) + fm.getAscent(); |
||||
String txt = getValueText(); |
||||
if (txt != null) { |
||||
g.drawString(txt, x, y); |
||||
} |
||||
if (getBorder() != null) { |
||||
getBorder().paintBorder(this, g, 0, 0, width, height); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setValue(Object value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
private String getValueText() { |
||||
return encoder.encode(value); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.fanruan.api.design.work.form.basic; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
*/ |
||||
public class Item extends com.fr.design.designer.properties.items.Item { |
||||
public Item(String name, Object value) { |
||||
super(name, value); |
||||
} |
||||
} |
@ -0,0 +1,15 @@
|
||||
package com.fanruan.api.design.work.form.basic; |
||||
|
||||
import com.fr.design.designer.properties.items.Item; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 用作左中右对齐设置的下拉框Editor |
||||
*/ |
||||
public class ItemCellEditor extends com.fr.design.mainframe.widget.editors.ItemCellEditor { |
||||
public ItemCellEditor(Item[] items) { |
||||
super(items); |
||||
} |
||||
} |
@ -0,0 +1,15 @@
|
||||
package com.fanruan.api.design.work.form.basic; |
||||
|
||||
import com.fr.design.designer.properties.Encoder; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 无法修改的编辑器 |
||||
*/ |
||||
public abstract class UneditableAccessibleEditor extends com.fr.design.mainframe.widget.accessibles.UneditableAccessibleEditor { |
||||
public UneditableAccessibleEditor(Encoder enc) { |
||||
super(enc); |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.fanruan.api.design.work.form.container; |
||||
|
||||
/** |
||||
* 抽象数据定义,实现数据可序列化 |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/3 |
||||
*/ |
||||
public abstract class AbstractDataModify<T> extends com.fr.design.widget.ui.AbstractDataModify<T> { |
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.fanruan.api.design.work.form.container; |
||||
|
||||
import com.fr.form.ui.container.WLayout; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* |
||||
* 属性设置部分布局容器 |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/3 |
||||
*/ |
||||
public abstract class XLayoutContainer extends com.fr.design.designer.creator.XLayoutContainer { |
||||
|
||||
public XLayoutContainer(WLayout widget, Dimension initSize) { |
||||
super(widget, initSize); |
||||
this.addContainerListener(this); |
||||
} |
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.fanruan.api.design.work.form.creator; |
||||
|
||||
import com.fr.form.ui.FieldEditor; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* 控件树 |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/3 |
||||
*/ |
||||
public abstract class XFieldEditor extends com.fr.design.designer.creator.XFieldEditor { |
||||
public XFieldEditor(FieldEditor widget, Dimension initSize) { |
||||
super(widget, initSize); |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fanruan.api.design.work.form.editor; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-05 |
||||
* 字符串编辑器 |
||||
*/ |
||||
public class StringEditor extends com.fr.design.mainframe.widget.editors.StringEditor { |
||||
|
||||
public StringEditor() { |
||||
super(); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.fanruan.api.design.work.form.editor; |
||||
|
||||
/** |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
* 控件值编辑器 |
||||
*/ |
||||
public class WidgetValueEditor extends com.fr.design.mainframe.widget.editors.WidgetValueEditor { |
||||
|
||||
public WidgetValueEditor(Object o) { |
||||
super(o); |
||||
} |
||||
|
||||
public WidgetValueEditor(Object o, boolean onlyServer) { |
||||
super(o, onlyServer); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.fanruan.api.design.work.form.macro; |
||||
|
||||
/** |
||||
* 存放XCreator的常量 |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/3 |
||||
*/ |
||||
public class XCreatorConstants { |
||||
|
||||
public static final String PROPERTY_CATEGORY = com.fr.design.form.util.XCreatorConstants.PROPERTY_CATEGORY; |
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.fanruan.api.err; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-04 |
||||
* 数据集异常 |
||||
*/ |
||||
public class TableDataException extends com.fr.general.data.TableDataException { |
||||
|
||||
public TableDataException(String s) { |
||||
super(s); |
||||
} |
||||
|
||||
public TableDataException(String s, Throwable throwable) { |
||||
super(s, throwable); |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
package com.fanruan.api.io; |
||||
|
||||
import com.fr.io.base.provider.RepositoryFactoryProvider; |
||||
import com.fr.io.context.ResourceModuleContext; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
/** |
||||
* |
||||
* 资源仓库插件开发套件 |
||||
* |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2019/9/5 |
||||
*/ |
||||
public class ResourceModuleKit { |
||||
|
||||
|
||||
/** |
||||
* 添加一个资源仓库工厂 |
||||
* |
||||
* @param factory 工厂 |
||||
* @param <T> 工厂类型 |
||||
*/ |
||||
public static <T extends RepositoryFactoryProvider> void addFactory(@NotNull T factory) { |
||||
ResourceModuleContext.addFactory(factory); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 移除一个资源仓库工厂 |
||||
* |
||||
* @param factory 工厂 |
||||
* @param <T> 工厂类型 |
||||
*/ |
||||
public static <T extends RepositoryFactoryProvider> void removeFactory(@NotNull T factory) { |
||||
ResourceModuleContext.removeFactory(factory.getIdentity()); |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.fanruan.api.report; |
||||
|
||||
import com.fr.stable.html.Tag; |
||||
import com.fr.stable.web.Repository; |
||||
import com.fr.web.BaseHTMLWriterUtils; |
||||
|
||||
import java.awt.*; |
||||
|
||||
public class BaseHTMLWriterKit { |
||||
|
||||
/** |
||||
* 根据原始的图片和指定的尺寸以及报表上下文生成图片的HTML标签,该方法只生成一个简单的img标签 |
||||
* @param image 原始图片 |
||||
* @param dimension 指定尺寸 |
||||
* @param repo 报表上下文 |
||||
* @return img图片标签 |
||||
*/ |
||||
public static Tag createImageTag4RepoWithCheckVml(Image image, Dimension dimension, Repository repo){ |
||||
return BaseHTMLWriterUtils.createImageTag4RepoWithCheckVml(image, dimension, repo); |
||||
} |
||||
} |
@ -0,0 +1,22 @@
|
||||
package com.fanruan.api.report; |
||||
|
||||
import com.fr.base.Style; |
||||
import com.fr.report.cell.cellattr.core.CellUtils; |
||||
|
||||
import java.awt.*; |
||||
|
||||
public class PaintKit { |
||||
|
||||
/** |
||||
* 如果value是ImageWithSuffix类的一个实例,则创建一个宽为width,高为height,类型为TYPE_4BYTE_ABGR的image,并将其按照比例和Style绘制。 |
||||
* @param value 传入的需要判断为是否是ImageWithSuffix实例的对象 |
||||
* @param resolution 缩放比例的分母,缩放比例为1/resolution |
||||
* @param style 绘制image的style |
||||
* @param width 绘制image的宽 |
||||
* @param height 绘制image的高 |
||||
* @return 返回宽为width,高为height,类型为TYPE_4BYTE_ABGR的image |
||||
*/ |
||||
public static Image value2Image(Object value, int resolution, Style style, int width, int height){ |
||||
return CellUtils.value2Image(value, resolution, style, width, height); |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.fanruan.api.report.form; |
||||
|
||||
/** |
||||
* 允许自定义值的、允许直接编辑的、带重复的 --- 下拉框 下拉复选框 下拉树 |
||||
* @author Kalven |
||||
* @version 10.0 |
||||
* Created by Kalven on 2019/9/4 |
||||
*/ |
||||
public abstract class CustomWriteAbleRepeatEditor extends com.fr.form.ui.CustomWriteAbleRepeatEditor { |
||||
} |
@ -0,0 +1,213 @@
|
||||
package com.fanruan.api.security; |
||||
|
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fr.cert.token.JwtBuilder; |
||||
import com.fr.cert.token.Jwts; |
||||
import com.fr.cert.token.SignatureAlgorithm; |
||||
import com.fr.cert.token.SignatureException; |
||||
import com.fr.cert.token.impl.DefaultClaims; |
||||
import com.fr.security.KeySecretSeedConfig; |
||||
import com.fr.security.SecurityToolbox; |
||||
|
||||
import java.io.IOException; |
||||
import java.security.Key; |
||||
import java.util.Date; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-03 |
||||
* 用于生成和解析基于JWT的token |
||||
*/ |
||||
public class JwtKit { |
||||
|
||||
private static final String JWT_ID = "jwt"; |
||||
private static final String ISSUER = "fanruan"; |
||||
private static final SignatureAlgorithm DEFAULT_ALGORITHM = SignatureAlgorithm.HS256; |
||||
|
||||
/** |
||||
* 创建完整token |
||||
* |
||||
* @param issuer jwt签发者 |
||||
* @param subject jwt所面向的用户 |
||||
* @param audience 接收jwt的一方 |
||||
* @param expiration jwt的过期时间,这个过期时间必须要大于签发时间 |
||||
* @param notBeforeTime 定义在什么时间之前,该jwt都是不可用的. |
||||
* @param issuerAtTime jwt的签发时间 |
||||
* @param jwtId jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 |
||||
* @param algorithm 加密算法 |
||||
* @param secretKey 秘钥 |
||||
* @return 签名后的token |
||||
*/ |
||||
public static String createJWT(String issuer, String subject, String audience, Date expiration, Date notBeforeTime, |
||||
Date issuerAtTime, String jwtId, SignatureAlgorithm algorithm, Key secretKey) { |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(issuer) |
||||
.setSubject(subject) |
||||
.setAudience(audience) |
||||
.setExpiration(expiration) |
||||
.setNotBefore(notBeforeTime) |
||||
.setIssuedAt(issuerAtTime) |
||||
.setId(jwtId) |
||||
.signWith(algorithm, secretKey); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 创建默认的token,用不超时 |
||||
* |
||||
* @param subject 主题 |
||||
* @return token |
||||
*/ |
||||
public static String createDefaultJWT(String subject) { |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(new Date()) |
||||
.setSubject(subject) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, getKeyBytes()); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 创建默认的token |
||||
* |
||||
* @param subject 主题 |
||||
* @param description 描述 |
||||
* @return token |
||||
*/ |
||||
public static String createDefaultJWT(String subject, String description) { |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(new Date()) |
||||
.setSubject(subject) |
||||
.setDescription(description) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, getKeyBytes()); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 创建默认token |
||||
* |
||||
* @param subject 主题 |
||||
* @param description 描述 |
||||
* @param timeout 超时时长 |
||||
* @return token |
||||
*/ |
||||
public static String createDefaultJWT(String subject, String description, long timeout) { |
||||
Date currentTime = new Date(); |
||||
Date timeoutTime = new Date(currentTime.getTime() + timeout); |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(currentTime) |
||||
.setExpiration(timeoutTime) |
||||
.setSubject(subject) |
||||
.setDescription(description) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, getKeyBytes()); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 创建有超时时限的token |
||||
* |
||||
* @param subject 主题 |
||||
* @param timeout 超时时长 |
||||
* @return token |
||||
*/ |
||||
public static String createDefaultJWT(String subject, long timeout) { |
||||
Date currentTime = new Date(); |
||||
Date timeoutTime = new Date(currentTime.getTime() + timeout); |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(currentTime) |
||||
.setExpiration(timeoutTime) |
||||
.setSubject(subject) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, getKeyBytes()); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 解析token |
||||
* |
||||
* @param jwt token字符串 |
||||
* @return 签名通过之后的结果集 |
||||
* @throws SignatureException 签名错误异常 |
||||
*/ |
||||
public static Map<String, Object> parseJWT(String jwt) { |
||||
try { |
||||
return Jwts.parser().setSigningKey(getKeyBytes()).parseClaimsJws(jwt).getBody(); |
||||
} catch (SignatureException e) { |
||||
LogKit.warn(e.getMessage()); |
||||
} |
||||
return new DefaultClaims(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 根据自定义的key,创建token |
||||
* |
||||
* @param signatureKey 秘钥 |
||||
* @param claims token携带的信息 |
||||
* @return token |
||||
*/ |
||||
public static String createVariedJWT(String signatureKey, Map<String, Object> claims) { |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(new Date()) |
||||
.setClaims(claims) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, signatureKey); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 根据自定义的key,创建token |
||||
* |
||||
* @param signatureKey 秘钥 |
||||
* @param timeout 有效期 |
||||
* @param claims token携带的信息 |
||||
* @return token |
||||
*/ |
||||
public static String createVariedJWT(String signatureKey, long timeout, Map<String, Object> claims) { |
||||
Date currentTime = new Date(); |
||||
Date timeoutTime = new Date(currentTime.getTime() + timeout); |
||||
JwtBuilder builder = Jwts.builder() |
||||
.setIssuer(ISSUER) |
||||
.setIssuedAt(new Date()) |
||||
.setExpiration(timeoutTime) |
||||
.setClaims(claims) |
||||
.setId(JWT_ID) |
||||
.signWith(DEFAULT_ALGORITHM, signatureKey); |
||||
return builder.compact(); |
||||
} |
||||
|
||||
/** |
||||
* 解析token, 先对key进行utf-8解码 |
||||
* |
||||
* @param jwt token字符串 |
||||
* @param signatureKey 秘钥 |
||||
* @return 签名通过之后的结果集 |
||||
* @throws SignatureException 签名错误异常 |
||||
*/ |
||||
public static Map<String, Object> parseJWT(String jwt, String signatureKey) { |
||||
try { |
||||
return Jwts.parser().setSigningKey(signatureKey).parseClaimsJws(jwt).getBody(); |
||||
} catch (SignatureException e) { |
||||
LogKit.warn(e.getMessage()); |
||||
} |
||||
return new DefaultClaims(); |
||||
} |
||||
|
||||
private static byte[] getKeyBytes() { |
||||
try { |
||||
return SecurityToolbox.base642Byte(KeySecretSeedConfig.getInstance().getTrustSeed()); |
||||
} catch (IOException e) { |
||||
LogKit.error("key secret seed base64 decode error"); |
||||
} |
||||
return new byte[0]; |
||||
} |
||||
} |
@ -0,0 +1,67 @@
|
||||
package com.fanruan.api.data.open; |
||||
|
||||
import com.fr.general.data.DataModel; |
||||
import com.fr.script.Calculator; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-04 |
||||
*/ |
||||
public class BaseTableDataTest { |
||||
|
||||
@Test |
||||
public void testCreate() throws Exception { |
||||
Calculator calculator = Calculator.createCalculator(); |
||||
DemoTableData tableData = new DemoTableData(); |
||||
DataModel model = tableData.createDataModel(calculator); |
||||
Object r = model.getValueAt(0, 0); |
||||
Assert.assertTrue(model.hasRow(0)); |
||||
Assert.assertFalse(model.hasRow(1)); |
||||
Assert.assertEquals(1, model.getColumnCount()); |
||||
Assert.assertEquals(1, model.getRowCount()); |
||||
Assert.assertEquals("abc", r); |
||||
} |
||||
|
||||
|
||||
private static class DemoTableData extends BaseTableData { |
||||
|
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator) { |
||||
return new BaseDataModel() { |
||||
|
||||
@Override |
||||
public int getColumnCount() { |
||||
return 1; |
||||
} |
||||
|
||||
@Override |
||||
public String getColumnName(int i) { |
||||
return "test"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasRow(int i) { |
||||
return i < 1; |
||||
} |
||||
|
||||
@Override |
||||
public int getRowCount() { |
||||
return 1; |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int i, int i1) { |
||||
return "abc"; |
||||
} |
||||
|
||||
@Override |
||||
public void release() throws Exception { |
||||
|
||||
} |
||||
}; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,124 @@
|
||||
package com.fanruan.api.io; |
||||
|
||||
import com.fr.io.base.provider.FactoryLoaderProvider; |
||||
import com.fr.io.base.provider.RepositoryFactoryProvider; |
||||
import com.fr.io.base.provider.RepositoryInstallerProvider; |
||||
import com.fr.io.base.provider.RepositoryManagerProvider; |
||||
import com.fr.io.config.RepositoryConfig; |
||||
import com.fr.io.config.ResourceModuleConfigProvider; |
||||
import com.fr.io.context.RepositoryContextProvider; |
||||
import com.fr.io.context.ResourceModuleContext; |
||||
import com.fr.io.lock.LockFactory; |
||||
import org.easymock.EasyMock; |
||||
import org.junit.After; |
||||
import org.junit.Assert; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* ResourceModuleKit Tester. |
||||
* |
||||
* @author <Authors name> |
||||
* @version 1.0 |
||||
* @since <pre>9月 5, 2019</pre> |
||||
*/ |
||||
public class ResourceModuleKitTest { |
||||
|
||||
@Before |
||||
public void before() throws Exception { |
||||
final FactoryLoaderProvider loaderProvider = new FactoryLoaderProvider() { |
||||
final Map<String, RepositoryFactoryProvider> map = new HashMap<>(); |
||||
|
||||
@Override |
||||
public <T extends RepositoryConfig> void add(RepositoryFactoryProvider<T> factory) { |
||||
map.put(factory.getIdentity(), factory); |
||||
} |
||||
|
||||
@Override |
||||
public void remove(String identity) { |
||||
map.remove(identity); |
||||
} |
||||
|
||||
@Override |
||||
@SuppressWarnings("unchecked") |
||||
public <T extends RepositoryConfig> RepositoryFactoryProvider<T> get(String identity) { |
||||
return map.get(identity); |
||||
} |
||||
}; |
||||
|
||||
ResourceModuleContext.setRepositoryContext(new RepositoryContextProvider() { |
||||
@Override |
||||
public FactoryLoaderProvider getFactoryLoader() { |
||||
|
||||
return loaderProvider; |
||||
} |
||||
|
||||
@Override |
||||
public ResourceModuleConfigProvider getConfig() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public RepositoryManagerProvider getManager() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public RepositoryInstallerProvider getInstaller() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public LockFactory getLockFactory() { |
||||
return null; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@After |
||||
public void after() throws Exception { |
||||
ResourceModuleContext.setRepositoryContext(null); |
||||
} |
||||
|
||||
/** |
||||
* Method: addFactory(@NotNull T factory) |
||||
*/ |
||||
@Test |
||||
public void testAddFactory() throws Exception { |
||||
RepositoryFactoryProvider factory = EasyMock.createMock(RepositoryFactoryProvider.class); |
||||
EasyMock.expect(factory.getIdentity()).andReturn("MockRF").anyTimes(); |
||||
|
||||
EasyMock.replay(factory); |
||||
|
||||
Assert.assertNull(ResourceModuleContext.getFactory("MockRF")); |
||||
|
||||
ResourceModuleKit.addFactory(factory); |
||||
|
||||
Assert.assertNotNull(ResourceModuleContext.getFactory("MockRF")); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Method: addFactory(@NotNull T factory) |
||||
*/ |
||||
@Test |
||||
public void testRemoveFactory() throws Exception { |
||||
RepositoryFactoryProvider factory = EasyMock.createMock(RepositoryFactoryProvider.class); |
||||
EasyMock.expect(factory.getIdentity()).andReturn("MockRF").anyTimes(); |
||||
|
||||
EasyMock.replay(factory); |
||||
|
||||
Assert.assertNull(ResourceModuleContext.getFactory("MockRF")); |
||||
|
||||
ResourceModuleKit.addFactory(factory); |
||||
|
||||
Assert.assertNotNull(ResourceModuleContext.getFactory("MockRF")); |
||||
|
||||
ResourceModuleKit.removeFactory(factory); |
||||
|
||||
Assert.assertNull(ResourceModuleContext.getFactory("MockRF")); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
package com.fanruan.api.plugin; |
||||
|
||||
import com.fanruan.api.runtime.PluginKit; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
public class PluginKitTest { |
||||
@Test |
||||
public void getArray() { |
||||
Assert.assertFalse(PluginKit.isCurrentPluginAvailable()); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,77 @@
|
||||
package com.fanruan.api.security; |
||||
|
||||
import com.fanruan.api.Prepare; |
||||
import com.fr.cert.token.JwtBuilder; |
||||
import com.fr.cert.token.Jwts; |
||||
import com.fr.cert.token.SignatureAlgorithm; |
||||
import com.fr.security.SecurityToolbox; |
||||
import com.fr.stable.CodeUtils; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
import java.io.UnsupportedEncodingException; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-09-03 |
||||
*/ |
||||
public class JwtKitTest extends Prepare { |
||||
|
||||
@Test |
||||
public void testCreateDefaultJWT() throws Exception { |
||||
String tokenCN = JwtKit.createDefaultJWT("你好,我是中国人"); |
||||
Map<String, Object> claims = JwtKit.parseJWT(tokenCN); |
||||
Assert.assertEquals("你好,我是中国人", CodeUtils.cjkDecode(String.valueOf(claims.get("sub")))); |
||||
|
||||
String tokenEN = JwtKit.createDefaultJWT("Hello, world"); |
||||
Map<String, Object> claims2 = JwtKit.parseJWT(tokenEN); |
||||
Assert.assertEquals("Hello, world", CodeUtils.cjkDecode(String.valueOf(claims2.get("sub")))); |
||||
} |
||||
|
||||
@Test |
||||
public void testClaims() throws Exception { |
||||
String token = JwtKit.createDefaultJWT("千万", "我是千万的爹"); |
||||
Map<String, Object> claims2 = JwtKit.parseJWT(token); |
||||
String text = CodeUtils.cjkDecode(String.valueOf(claims2.get("description"))); |
||||
Assert.assertEquals("我是千万的爹", text); |
||||
} |
||||
|
||||
@Test |
||||
public void test1() throws UnsupportedEncodingException { |
||||
String token = createToken().compact(); |
||||
Assert.assertEquals(Jwts.parser().setSigningKey("abc=啊").parseClaimsJws(token).getBody().getSubject(), "hello.cpt"); |
||||
|
||||
token = createToken().signWithBase64SecretKey(SignatureAlgorithm.HS256, SecurityToolbox.byte2Base64("abc=啊".getBytes())).compact(); |
||||
Assert.assertEquals(Jwts.parser() |
||||
.setBase64SigningKey(SecurityToolbox.byte2Base64("abc=啊".getBytes())) |
||||
.parseClaimsJws(token).getBody().getSubject(), "hello.cpt"); |
||||
|
||||
token = createToken() |
||||
.signWith(SignatureAlgorithm.HS256, "abc=啊".getBytes("GBK")) |
||||
.compact(); |
||||
Assert.assertEquals("hello.cpt", Jwts.parser().setSigningKey("abc=啊".getBytes("GBK")).parseClaimsJws(token).getBody().getSubject()); |
||||
} |
||||
|
||||
private JwtBuilder createToken() { |
||||
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; |
||||
|
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.set(2019, Calendar.FEBRUARY, 20, 18, 0, 0); |
||||
Date currentTime = calendar.getTime(); |
||||
calendar.set(2029, Calendar.FEBRUARY, 20, 18, 0, 0); |
||||
Date expirationTime = calendar.getTime(); |
||||
return Jwts.builder() |
||||
.setHeaderParam("typ", "JWT") |
||||
.setIssuer("fanruan") |
||||
.setSubject("hello.cpt") |
||||
.setExpiration(expirationTime) |
||||
.setIssuedAt(currentTime) |
||||
.setId("01") |
||||
.signWith(signatureAlgorithm, "abc=啊"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.fanruan.api.security; |
||||
|
||||
import java.util.*; |
||||
|
||||
import com.fr.stable.CommonCodeUtils; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
public class SecurityKitTest { |
||||
@Test |
||||
public void passwordDecode(){ |
||||
Assert.assertEquals(SecurityKit.passwordDecode("1234"), CommonCodeUtils.passwordDecode("1234")); |
||||
} |
||||
@Test |
||||
public void passwordEncode(){ |
||||
Assert.assertEquals(SecurityKit.passwordEncode("1234"), CommonCodeUtils.passwordEncode("1234")); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.fanruan.api.util; |
||||
|
||||
import com.fanruan.api.report.PaintKit; |
||||
import com.fr.base.Style; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
import java.awt.*; |
||||
import java.awt.image.BufferedImage; |
||||
|
||||
public class PaintKitTest { |
||||
|
||||
@Test |
||||
public void value2Image() { |
||||
BufferedImage bi = new BufferedImage(40, 50, BufferedImage.TYPE_BYTE_GRAY); |
||||
Style style = Style.getInstance(); |
||||
Image image = PaintKit.value2Image(bi, 1, style, 30, 50); |
||||
Assert.assertEquals(30, image.getWidth(null)); |
||||
Assert.assertEquals(50, image.getHeight(null)); |
||||
} |
||||
} |
@ -0,0 +1,38 @@
|
||||
package com.fanruan.api.xml; |
||||
|
||||
import com.fr.base.Parameter; |
||||
import com.fr.base.TableData; |
||||
import com.fr.plugin.db.json.core.JSONTableData; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.bridge.StableFactory; |
||||
import com.fr.stable.xml.StableXMLUtils; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLUtils; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
import com.fr.third.javax.xml.stream.XMLStreamException; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
public class XmlKitTest { |
||||
|
||||
@Test |
||||
public void readParameter() { |
||||
try { |
||||
XMLableReader xml = XMLableReader.createXMLableReader("<!-- Edited by XMLSpy® -->\n" + |
||||
"<note>\n" + |
||||
"<Parameter>Tove</Parameter>\n" + |
||||
"<from>Jani</from>\n" + |
||||
"<heading>Reminder</heading>\n" + |
||||
"<body>Don't forget me this weekend!</body>\n" + |
||||
"</note>"); |
||||
Parameter parameter = new Parameter("test", 1); |
||||
StableFactory.registerXMLDescription("Parameter",parameter); |
||||
Parameter p = (Parameter)XmlKit.readParameter(xml); |
||||
Assert.assertTrue(p.getName().equals("test")); |
||||
} catch (XMLStreamException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue