Mars.Ma
5 years ago
59 changed files with 3534 additions and 134 deletions
@ -0,0 +1,37 @@ |
|||||||
|
package com.fanruan.api.cal; |
||||||
|
|
||||||
|
import com.fr.general.FArray; |
||||||
|
import com.fr.stable.ArrayProvider; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
* 创建容器的工具类 |
||||||
|
*/ |
||||||
|
public class ContainerKit { |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建一个插件可识别的数组对象 |
||||||
|
* |
||||||
|
* @param array 原始数组 |
||||||
|
* @param <T> 数组元素类型 |
||||||
|
* @return 插件可识别的数组对象 |
||||||
|
*/ |
||||||
|
public static <T> ArrayProvider<T> newArray(T[] array) { |
||||||
|
return new FArray<>(array); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建一个插件可识别的数组对象 |
||||||
|
* |
||||||
|
* @param collection 原始集合 |
||||||
|
* @param <T> 数组元素类型 |
||||||
|
* @return 插件可识别的数组对象 |
||||||
|
*/ |
||||||
|
public static <T> ArrayProvider<T> newArray(Collection<T> collection) { |
||||||
|
return new FArray<>(collection); |
||||||
|
} |
||||||
|
} |
@ -1,22 +0,0 @@ |
|||||||
package com.fanruan.api.consts; |
|
||||||
import com.fr.stable.EncodeConstants; |
|
||||||
|
|
||||||
public class EncodeConstantsKit { |
|
||||||
|
|
||||||
public static final String ENCODING_UTF_8 = EncodeConstants.ENCODING_UTF_8; |
|
||||||
|
|
||||||
public static final String ENCODING_GBK = EncodeConstants.ENCODING_GBK; |
|
||||||
|
|
||||||
public static final String ENCODING_BIG5 = EncodeConstants.ENCODING_BIG5; |
|
||||||
|
|
||||||
public static final String ENCODING_ISO_8859_1 = EncodeConstants.ENCODING_ISO_8859_1; |
|
||||||
|
|
||||||
|
|
||||||
public static final String ENCODING_UTF_16 = EncodeConstants.ENCODING_UTF_16; |
|
||||||
|
|
||||||
public static final String ENCODING_EUC_JP = EncodeConstants.ENCODING_EUC_JP; |
|
||||||
|
|
||||||
public static final String ENCODING_EUC_KR = EncodeConstants.ENCODING_EUC_KR; |
|
||||||
|
|
||||||
public static final String ENCODING_CP850 = EncodeConstants.ENCODING_CP850; |
|
||||||
} |
|
@ -0,0 +1,38 @@ |
|||||||
|
package com.fanruan.api.data; |
||||||
|
|
||||||
|
import com.fanruan.api.util.TypeKit; |
||||||
|
import com.fr.data.impl.Connection; |
||||||
|
import com.fr.file.ConnectionConfig; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据连接相关工具类 |
||||||
|
*/ |
||||||
|
public class ConnectionKit { |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取指定名字的数据连接 |
||||||
|
* |
||||||
|
* @param name 名字 |
||||||
|
* @return 数据连接 |
||||||
|
*/ |
||||||
|
public @Nullable Connection getConnection(@NotNull String name) { |
||||||
|
return ConnectionConfig.getInstance().getConnection(name); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取指定名字和指定类型的数据连接 |
||||||
|
* |
||||||
|
* @param name 数据连接的名字 |
||||||
|
* @param type 类型 |
||||||
|
* @return 数据连接 |
||||||
|
*/ |
||||||
|
public <T extends Connection> @Nullable T getConnection(@NotNull String name, Class<? extends Connection> type) { |
||||||
|
Connection connection = getConnection(name); |
||||||
|
if (TypeKit.objectInstanceOf(connection, type)) { |
||||||
|
return (T) connection; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
package com.fanruan.api.data.connection; |
||||||
|
|
||||||
|
public class NameDatabaseConnection extends com.fr.data.impl.NameDatabaseConnection{ |
||||||
|
} |
@ -1,8 +1,8 @@ |
|||||||
package com.fanruan.api.design.ui.action; |
package com.fanruan.api.design.ui.action; |
||||||
|
|
||||||
import java.awt.event.ActionEvent; |
/** |
||||||
|
* 用于各种菜单动作实现的抽象类 |
||||||
|
*/ |
||||||
|
public abstract class UpdateAction extends com.fr.design.actions.UpdateAction { |
||||||
|
|
||||||
public class UpdateAction extends com.fr.design.actions.UpdateAction{ |
|
||||||
@Override |
|
||||||
public void actionPerformed(ActionEvent evt) {} |
|
||||||
} |
} |
||||||
|
@ -0,0 +1,28 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author zhaojunzhe |
||||||
|
* @version 10.0 |
||||||
|
* Created by zhaojunzhe on 2019-08-28 |
||||||
|
* 复选框组件 |
||||||
|
*/ |
||||||
|
public class UICheckBox extends com.fr.design.gui.icheckbox.UICheckBox { |
||||||
|
|
||||||
|
public UICheckBox() { |
||||||
|
} |
||||||
|
|
||||||
|
public UICheckBox(String text) { |
||||||
|
super(text); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public UICheckBox(String text, boolean checked) { |
||||||
|
super(text, checked); |
||||||
|
} |
||||||
|
|
||||||
|
public UICheckBox(String text, Icon icon) { |
||||||
|
super(text, icon); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import com.fanruan.api.util.AssistKit; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.stable.Constants; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.plaf.basic.BasicComboBoxEditor; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.lang.reflect.Method; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Vector; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 下拉框 |
||||||
|
*/ |
||||||
|
public class UIComboBox<T> extends com.fr.design.gui.icombobox.UIComboBox { |
||||||
|
|
||||||
|
public UIComboBox() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UIComboBox(ComboBoxModel<T> model) { |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
public UIComboBox(T[] items) { |
||||||
|
super(items); |
||||||
|
} |
||||||
|
|
||||||
|
public UIComboBox(Vector<T> items) { |
||||||
|
super(items); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 重新设置下拉选项 |
||||||
|
* |
||||||
|
* @param list 下拉选项的集合 |
||||||
|
*/ |
||||||
|
public void refreshSelectableItems(List<T> list) { |
||||||
|
T el = (T) getSelectedItem(); |
||||||
|
removeAllItems(); |
||||||
|
for (T t : list) { |
||||||
|
addItem(t); |
||||||
|
} |
||||||
|
getModel().setSelectedItem(el); |
||||||
|
} |
||||||
|
|
||||||
|
public static class UIComboBoxEditor extends BasicComboBoxEditor { |
||||||
|
protected UITextField textField; |
||||||
|
private Object oldValue; |
||||||
|
|
||||||
|
public UIComboBoxEditor() { |
||||||
|
textField = new UITextField(); |
||||||
|
textField.setRectDirection(Constants.RIGHT); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getEditorComponent() { |
||||||
|
return textField; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setItem(Object anObject) { |
||||||
|
if (anObject != null) { |
||||||
|
textField.setText(anObject.toString()); |
||||||
|
oldValue = anObject; |
||||||
|
} else { |
||||||
|
textField.setText(StringUtils.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getItem() { |
||||||
|
Object newValue = textField.getText(); |
||||||
|
if (oldValue != null && !(oldValue instanceof String)) { |
||||||
|
if (AssistKit.equals(newValue, oldValue.toString())) { |
||||||
|
return oldValue; |
||||||
|
} else { |
||||||
|
Class cls = oldValue.getClass(); |
||||||
|
try { |
||||||
|
Method method = cls.getMethod("valueOf", new Class[]{String.class}); |
||||||
|
newValue = method.invoke(oldValue, new Object[]{textField.getText()}); |
||||||
|
} catch (Exception ignore) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return newValue; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void selectAll() { |
||||||
|
textField.selectAll(); |
||||||
|
textField.requestFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addActionListener(ActionListener l) { |
||||||
|
textField.addActionListener(l); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeActionListener(ActionListener l) { |
||||||
|
textField.removeActionListener(l); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
public class UIDescriptionTextArea extends com.fr.design.gui.itextarea.DescriptionTextArea{ |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 带字典数据的下拉框,显示值和实际值通过字典进行对应 |
||||||
|
*/ |
||||||
|
public class UIDictionaryComboBox<T> extends com.fr.design.gui.icombobox.UIDictionaryComboBox<T> { |
||||||
|
|
||||||
|
public UIDictionaryComboBox(T[] keys, String[] values) { |
||||||
|
super(keys, values); |
||||||
|
} |
||||||
|
} |
@ -1,5 +1,29 @@ |
|||||||
package com.fanruan.api.design.ui.component; |
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
/** |
||||||
|
* 整数控件,该控件只能输入整数数字 |
||||||
|
*/ |
||||||
public class UIIntNumberField extends com.fr.design.gui.itextfield.UIIntNumberField { |
public class UIIntNumberField extends com.fr.design.gui.itextfield.UIIntNumberField { |
||||||
|
|
||||||
|
public UIIntNumberField() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取整数数值 |
||||||
|
* |
||||||
|
* @return 整数值 |
||||||
|
*/ |
||||||
|
public int getInt() { |
||||||
|
return (int) getValue(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置整数数值 |
||||||
|
* |
||||||
|
* @param value 整数值 |
||||||
|
*/ |
||||||
|
public void setInt(int value) { |
||||||
|
setValue(value); |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,191 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.util.StringKit; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.DocumentEvent; |
||||||
|
import javax.swing.event.DocumentListener; |
||||||
|
import javax.swing.event.PopupMenuEvent; |
||||||
|
import javax.swing.event.PopupMenuListener; |
||||||
|
import java.awt.*; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 懒加载下拉框,点击下拉之后才开始加载数据 |
||||||
|
*/ |
||||||
|
public abstract class UILazyComboBox<T> extends UIComboBox<T> implements PopupMenuListener { |
||||||
|
|
||||||
|
private static final int NUM = 80; |
||||||
|
private static final String[] PENDING_CONTENT = new String[]{StringKit.EMPTY, DesignKit.i18nText("Fine-Design_Basic_Loading") + "..."}; |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否加载完成 |
||||||
|
*/ |
||||||
|
protected boolean loaded = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化选项 |
||||||
|
*/ |
||||||
|
private Object initialSelected = null; |
||||||
|
|
||||||
|
|
||||||
|
protected UILazyComboBox() { |
||||||
|
super(); |
||||||
|
this.setEditor(new UILazyComboBox.FilterComboBoxEditor()); |
||||||
|
addPopupMenuListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoaded(boolean loaded) { |
||||||
|
this.loaded = loaded; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 加载下拉框中的选项 |
||||||
|
* |
||||||
|
* @return 下拉框中的选项 |
||||||
|
*/ |
||||||
|
public abstract Object[] load(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSelectedItem(Object anObject) { |
||||||
|
initialSelected = anObject; |
||||||
|
if (loaded) { |
||||||
|
super.setSelectedItem(anObject); |
||||||
|
} else { |
||||||
|
this.setModel(new DefaultComboBoxModel<>(new Object[]{anObject})); |
||||||
|
super.setSelectedItem(anObject); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void popupMenuWillBecomeVisible(PopupMenuEvent e) { |
||||||
|
if (loaded) { |
||||||
|
return; |
||||||
|
} |
||||||
|
DefaultComboBoxModel<String> loadingModel = new DefaultComboBoxModel<>(PENDING_CONTENT); |
||||||
|
this.setModel(loadingModel); |
||||||
|
new SwingWorker<Object[], Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Object[] doInBackground() { |
||||||
|
return load(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void done() { |
||||||
|
try { |
||||||
|
UILazyComboBox.this.loadList(get()); |
||||||
|
} catch (InterruptedException | ExecutionException exception) { |
||||||
|
LogKit.debug(exception.getMessage()); |
||||||
|
} |
||||||
|
UILazyComboBox.this.showPopup(); |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 加载下拉列表 |
||||||
|
*/ |
||||||
|
public void loadList() { |
||||||
|
DefaultComboBoxModel<Object> model = new DefaultComboBoxModel<>(load()); |
||||||
|
model.setSelectedItem(initialSelected); |
||||||
|
this.setModel(model); |
||||||
|
this.selectedItemReminder = initialSelected; |
||||||
|
loaded = true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 加载下拉列表 |
||||||
|
* |
||||||
|
* @param contents 下拉列表内容 |
||||||
|
*/ |
||||||
|
private void loadList(Object[] contents) { |
||||||
|
DefaultComboBoxModel<Object> model = new DefaultComboBoxModel<>(contents); |
||||||
|
model.setSelectedItem(initialSelected); |
||||||
|
this.setModel(model); |
||||||
|
this.selectedItemReminder = initialSelected; |
||||||
|
loaded = true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void popupMenuCanceled(PopupMenuEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() { |
||||||
|
Dimension dim = super.getPreferredSize(); |
||||||
|
dim.width = NUM; |
||||||
|
return dim; |
||||||
|
} |
||||||
|
|
||||||
|
class FilterComboBoxEditor extends UIComboBoxEditor implements DocumentListener { |
||||||
|
private Object item; |
||||||
|
private volatile boolean filtering = false; |
||||||
|
private volatile boolean setting = false; |
||||||
|
|
||||||
|
public FilterComboBoxEditor() { |
||||||
|
super(); |
||||||
|
textField.getDocument().addDocumentListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setItem(Object item) { |
||||||
|
if (filtering) { |
||||||
|
return; |
||||||
|
} |
||||||
|
this.item = item; |
||||||
|
this.setting = true; |
||||||
|
textField.setSetting(true); |
||||||
|
String newText = (item == null) ? "" : item.toString(); |
||||||
|
textField.setText(newText); |
||||||
|
textField.setSetting(false); |
||||||
|
this.setting = false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getItem() { |
||||||
|
return this.item; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void insertUpdate(DocumentEvent e) { |
||||||
|
handleChange(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeUpdate(DocumentEvent e) { |
||||||
|
handleChange(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void changedUpdate(DocumentEvent e) { |
||||||
|
handleChange(); |
||||||
|
} |
||||||
|
|
||||||
|
void handleChange() { |
||||||
|
if (setting) { |
||||||
|
return; |
||||||
|
} |
||||||
|
filtering = true; |
||||||
|
String xx = textField.getText(); |
||||||
|
UILazyComboBox.this.setSelectedItem(xx); |
||||||
|
this.item = textField.getText(); |
||||||
|
|
||||||
|
setPopupVisible(true); |
||||||
|
filtering = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 数字文本框 |
||||||
|
*/ |
||||||
|
public class UINumberField extends com.fr.design.gui.itextfield.UINumberField { |
||||||
|
|
||||||
|
/** |
||||||
|
* 默认的数字文本框,限制最大的输入整数位数为32位,限制最大的小数输入位数为16位 |
||||||
|
*/ |
||||||
|
public UINumberField() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 默认的数字文本框,限制最大的输入整数位数为32位,限制最大的小数输入位数为16位 |
||||||
|
* @param columns 最大的文本输入列数 |
||||||
|
*/ |
||||||
|
public UINumberField(int columns) { |
||||||
|
super(columns); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 限制整数和小数位数的数字文本框 |
||||||
|
* @param maxIntegerLength 最大整数位数 |
||||||
|
* @param maxDecimalLength 最大小数位数 |
||||||
|
*/ |
||||||
|
public UINumberField(int maxIntegerLength, int maxDecimalLength) { |
||||||
|
super(maxIntegerLength, maxDecimalLength); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 限制整数和小数位数、最大值以及最小值的数字文本框 |
||||||
|
* @param maxIntegerLength 最大整数位数 |
||||||
|
* @param maxDecimalLength 最大小数位数 |
||||||
|
* @param minValue 最小值 |
||||||
|
* @param maxValue 最大值 |
||||||
|
*/ |
||||||
|
public UINumberField(int maxIntegerLength, int maxDecimalLength, double minValue, double maxValue) { |
||||||
|
super(maxIntegerLength, maxDecimalLength, minValue, maxValue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 密码输入控件 |
||||||
|
*/ |
||||||
|
public class UIPasswordField extends com.fr.design.gui.ipasswordfield.UIPassWordField { |
||||||
|
|
||||||
|
public UIPasswordField() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UIPasswordField(String text) { |
||||||
|
super(text); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.itextfield.PlaceholderTextField; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 带占位文本的文本编辑器(当没有输入文本的时候,会显示占位符) |
||||||
|
*/ |
||||||
|
public class UIPlaceholderTextField extends PlaceholderTextField { |
||||||
|
|
||||||
|
public UIPlaceholderTextField() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UIPlaceholderTextField(String placeHolder) { |
||||||
|
super(); |
||||||
|
setPlaceholder(placeHolder); |
||||||
|
} |
||||||
|
|
||||||
|
public UIPlaceholderTextField(String text, String placeHolder) { |
||||||
|
super(text); |
||||||
|
setPlaceholder(placeHolder); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 数字滚动控件 |
||||||
|
*/ |
||||||
|
public class UISpinner extends com.fr.design.gui.ispinner.UISpinner { |
||||||
|
|
||||||
|
public UISpinner(double minValue, double maxValue, double delta) { |
||||||
|
super(minValue, maxValue, delta); |
||||||
|
} |
||||||
|
|
||||||
|
public UISpinner(double minValue, double maxValue, double delta, double defaultValue) { |
||||||
|
super(minValue, maxValue, delta, defaultValue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 表格控件 |
||||||
|
*/ |
||||||
|
public class UITable extends com.fr.design.gui.itable.UITable { |
||||||
|
|
||||||
|
public UITable() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UITable(int columnSize) { |
||||||
|
super(columnSize); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param values 一个列表,里面装有字符串数组,每个数组代表一行内容 |
||||||
|
*/ |
||||||
|
public UITable(@NotNull List<Object[]> values) { |
||||||
|
super(values); |
||||||
|
} |
||||||
|
|
||||||
|
public UITable(int columnSize, boolean needAWTEventListener) { |
||||||
|
super(columnSize, needAWTEventListener); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fanruan.api.design.ui.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.itoolbar.UIToolBarUI; |
||||||
|
|
||||||
|
public class UIToolbar extends com.fr.design.gui.itoolbar.UIToolbar{ |
||||||
|
public UIToolbar(){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public UIToolbar(int align) { |
||||||
|
super(align); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.code; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 代码编辑器用到的常量 |
||||||
|
*/ |
||||||
|
public interface SyntaxConstants { |
||||||
|
|
||||||
|
/** |
||||||
|
* 普通文本编辑器 |
||||||
|
*/ |
||||||
|
String SYNTAX_STYLE_NONE = "text/plain"; |
||||||
|
|
||||||
|
/** |
||||||
|
* java编辑器 |
||||||
|
*/ |
||||||
|
String SYNTAX_STYLE_JAVA = "text/java"; |
||||||
|
|
||||||
|
/** |
||||||
|
* javascript编辑器 |
||||||
|
*/ |
||||||
|
String SYNTAX_STYLE_JAVASCRIPT = "text/javascript"; |
||||||
|
|
||||||
|
/** |
||||||
|
* sql编辑器 |
||||||
|
*/ |
||||||
|
String SYNTAX_STYLE_SQL = "text/sql"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 公式编辑器 |
||||||
|
*/ |
||||||
|
String SYNTAX_STYLE_FORMULA = "text/formula"; |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.code; |
||||||
|
|
||||||
|
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 代码编辑器,支持javascript、sql、java、公式和普通文本 |
||||||
|
* @see com.fanruan.api.design.ui.component.code.SyntaxConstants |
||||||
|
* <p> |
||||||
|
* UISyntaxTextArea contentTextArea = new UISyntaxTextArea(); |
||||||
|
* contentTextArea.setCloseCurlyBraces(true); |
||||||
|
* contentTextArea.setLineWrap(true); |
||||||
|
* contentTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT); |
||||||
|
* contentTextArea.setCodeFoldingEnabled(true); |
||||||
|
* contentTextArea.setAntiAliasingEnabled(true); |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public class UISyntaxTextArea extends RSyntaxTextArea { |
||||||
|
|
||||||
|
public UISyntaxTextArea() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextArea(String text) { |
||||||
|
super(text); |
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextArea(int rows, int cols) { |
||||||
|
super(rows, cols); |
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextArea(String text, int rows, int cols) { |
||||||
|
super(text, rows, cols); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.code; |
||||||
|
|
||||||
|
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 可滚动的代码编辑器容器 |
||||||
|
*/ |
||||||
|
public class UISyntaxTextScrollPane extends RTextScrollPane { |
||||||
|
|
||||||
|
public UISyntaxTextScrollPane() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextScrollPane(Component component) { |
||||||
|
super(component); |
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextScrollPane(Component component, boolean lineNumbers) { |
||||||
|
super(component, lineNumbers); |
||||||
|
} |
||||||
|
|
||||||
|
public UISyntaxTextScrollPane(Component component, boolean lineNumbers, Color lineNumberColor) { |
||||||
|
super(component, lineNumbers, lineNumberColor); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.formula; |
||||||
|
|
||||||
|
import com.fr.design.formula.TinyFormulaPane; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 带公式选择器的公式输入文本框 |
||||||
|
*/ |
||||||
|
public class UIFormulaTextField extends TinyFormulaPane { |
||||||
|
|
||||||
|
public UIFormulaTextField() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public UIFormulaTextField(String text) { |
||||||
|
super(); |
||||||
|
setText(text); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置公式文本框的内容 |
||||||
|
* @param text 公式文本 |
||||||
|
*/ |
||||||
|
public void setText(String text) { |
||||||
|
populateBean(text); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取公式文本框的内容 |
||||||
|
* @return 公式内容 |
||||||
|
*/ |
||||||
|
public String getText() { |
||||||
|
return updateBean(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 公式窗口点击确定后的事件接口,该方法一般用于重载 |
||||||
|
*/ |
||||||
|
public void okEvent() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.table; |
||||||
|
|
||||||
|
|
||||||
|
import com.fanruan.api.design.ui.component.table.model.UITableModelAdapter; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 可增、删、改的表格控件 |
||||||
|
*/ |
||||||
|
public class UITableEditorPane<T> extends com.fr.design.gui.itableeditorpane.UITableEditorPane<T> { |
||||||
|
|
||||||
|
public UITableEditorPane(UITableModelAdapter<T> adapter) { |
||||||
|
super(adapter); |
||||||
|
} |
||||||
|
|
||||||
|
public UITableEditorPane(UITableModelAdapter<T> adapter, String leftLabelName) { |
||||||
|
super(adapter, leftLabelName); |
||||||
|
} |
||||||
|
} |
@ -1,28 +1,350 @@ |
|||||||
package com.fanruan.api.design.ui.component.table.model; |
package com.fanruan.api.design.ui.component.table.model; |
||||||
|
|
||||||
|
|
||||||
|
import com.fanruan.api.cal.ParameterKit; |
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.UILabel; |
||||||
|
import com.fanruan.api.design.ui.component.UITextField; |
||||||
|
import com.fanruan.api.design.ui.component.table.action.UITableEditAction; |
||||||
import com.fanruan.api.design.ui.editor.ValueEditorPane; |
import com.fanruan.api.design.ui.editor.ValueEditorPane; |
||||||
|
import com.fanruan.api.design.ui.editor.ValueEditors; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.util.IOKit; |
||||||
|
import com.fanruan.api.util.StringKit; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.stable.ParameterProvider; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.CellEditorListener; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.table.DefaultTableCellRenderer; |
||||||
|
import javax.swing.table.TableCellEditor; |
||||||
import java.awt.*; |
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.util.Collections; |
||||||
|
|
||||||
/** |
/** |
||||||
* 表格模型 |
* 编辑参数的表格模型,通常来说就是两列:参数名和参数值 |
||||||
*/ |
*/ |
||||||
public class ParameterTableModel extends com.fr.design.gui.itableeditorpane.ParameterTableModel { |
public class ParameterTableModel extends UITableModelAdapter<ParameterProvider> { |
||||||
|
|
||||||
|
public static final int NO_CHART_USE = 0; |
||||||
|
public static final int CHART_NORMAL_USE = 1; |
||||||
|
public static final int FORM_NORMAL_USE = -1; |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
protected Component component = null; |
||||||
|
|
||||||
public ParameterTableModel() { |
public ParameterTableModel() { |
||||||
super(); |
this(NO_CHART_USE); |
||||||
} |
} |
||||||
|
|
||||||
public ParameterTableModel(int paraUseType) { |
public ParameterTableModel(int paraUseType) { |
||||||
super(paraUseType); |
super(new String[]{DesignKit.i18nText("Fine-Design_Basic_Parameter"), DesignKit.i18nText("Fine-Design_Basic_Value")}); |
||||||
|
this.setColumnClass(new Class[]{ParameterEditor.class, ParameterValueEditor.class}); |
||||||
|
this.setDefaultEditor(ParameterValueEditor.class, new ParameterValueEditor(paraUseType)); |
||||||
|
this.setDefaultEditor(ParameterEditor.class, new ParameterEditor()); |
||||||
|
this.setDefaultRenderer(ParameterValueEditor.class, new ParameterValueRenderer(paraUseType)); |
||||||
} |
} |
||||||
|
|
||||||
public ParameterTableModel(int paraUseType, Component component) { |
public ParameterTableModel(int paraUseType, Component component) { |
||||||
super(paraUseType, component); |
super(new String[]{DesignKit.i18nText("Fine-Design_Basic_Parameter"), DesignKit.i18nText("Fine-Design_Basic_Value")}); |
||||||
|
this.setColumnClass(new Class[]{ParameterEditor.class, ParameterValueEditor.class}); |
||||||
|
this.setDefaultEditor(ParameterValueEditor.class, new ParameterValueEditor(paraUseType)); |
||||||
|
this.setDefaultEditor(ParameterEditor.class, new ParameterEditor()); |
||||||
|
this.setDefaultRenderer(ParameterValueEditor.class, new ParameterValueRenderer(paraUseType)); |
||||||
|
this.component = component; |
||||||
} |
} |
||||||
|
|
||||||
public ParameterTableModel(ValueEditorPane valueEditorPane, ValueEditorPane valueRenderPane, Component component) { |
public ParameterTableModel(ValueEditorPane valueEditorPane, ValueEditorPane valueRenderPane, Component component) { |
||||||
super(valueEditorPane, valueRenderPane, component); |
super(new String[]{DesignKit.i18nText("Fine-Design_Basic_Parameter"), DesignKit.i18nText("Fine-Design_Basic_Value")}); |
||||||
|
this.setColumnClass(new Class[]{ParameterEditor.class, ParameterValueEditor.class}); |
||||||
|
this.setDefaultEditor(ParameterValueEditor.class, new ParameterValueEditor(valueEditorPane)); |
||||||
|
this.setDefaultEditor(ParameterEditor.class, new ParameterEditor()); |
||||||
|
this.setDefaultRenderer(ParameterValueEditor.class, new ParameterValueRenderer(valueRenderPane)); |
||||||
|
this.component = component; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 单元格是否可编辑 |
||||||
|
* |
||||||
|
* @param row 行 |
||||||
|
* @param col 列 |
||||||
|
* @return 是否可以编辑 |
||||||
|
*/ |
||||||
|
public boolean isCellEditable(int row, int col) { |
||||||
|
if (col == 1) { |
||||||
|
return this.getList().get(row) != null && StringKit.isNotEmpty(this.getList().get(row).getName()); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) { |
||||||
|
ParameterProvider para = this.getList().get(rowIndex); |
||||||
|
switch (columnIndex) { |
||||||
|
case 0: |
||||||
|
return para.getName(); |
||||||
|
case 1: |
||||||
|
return para.getValue(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 生成工具栏上的一系列动作按钮 |
||||||
|
* |
||||||
|
* @return 返回table上的action数组. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public UITableEditAction[] createAction() { |
||||||
|
return new UITableEditAction[]{new AddParameterAction(), new DeleteAction(), new MoveUpAction(), new MoveDownAction()}; |
||||||
|
} |
||||||
|
|
||||||
|
protected class AddParameterAction extends AddTableRowAction { |
||||||
|
|
||||||
|
public AddParameterAction() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
super.actionPerformed(e); |
||||||
|
addParameter(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void addParameter() { |
||||||
|
ParameterProvider para = ParameterKit.newParameter(); |
||||||
|
addRow(para); |
||||||
|
fireTableDataChanged(); |
||||||
|
table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
protected class DeleteAction extends UITableEditAction { |
||||||
|
|
||||||
|
private Component component = null; |
||||||
|
|
||||||
|
public DeleteAction() { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Report_Delete")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/base/images/cell/control/remove.png")); |
||||||
|
} |
||||||
|
|
||||||
|
public DeleteAction(Component component) { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Report_Delete")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/base/images/cell/control/remove.png")); |
||||||
|
this.component = component; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
int[] selectedRow = table.getSelectedRows(); |
||||||
|
if (isMultiSelected()) { |
||||||
|
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), DesignKit.i18nText("Fine-Design_Basic_Multiple_Select_Warn_Text")); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (table.getCellEditor() != null) { |
||||||
|
try { |
||||||
|
table.getCellEditor().stopCellEditing(); |
||||||
|
} catch (Exception ee) { |
||||||
|
LogKit.error(ee.getMessage(), ee); |
||||||
|
} |
||||||
|
} |
||||||
|
if (getRowCount() < 1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (component == null) { |
||||||
|
component = DesignerContext.getDesignerFrame(); |
||||||
|
} |
||||||
|
int val = JOptionPane.showConfirmDialog(component, |
||||||
|
DesignKit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", DesignKit.i18nText("Fine-Design_Basic_Remove"), |
||||||
|
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); |
||||||
|
if (val != JOptionPane.OK_OPTION) { |
||||||
|
return; |
||||||
|
} |
||||||
|
for (int i = 0; i < selectedRow.length; i++) { |
||||||
|
if (selectedRow[i] - i < 0) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
removeRow(selectedRow[i] - i); |
||||||
|
} |
||||||
|
fireTableDataChanged(); |
||||||
|
int selection = selectedRow[0] > table.getRowCount() ? table.getRowCount() - 1 |
||||||
|
: (selectedRow[0] > 1 ? selectedRow[0] - 1 : 0); |
||||||
|
table.getSelectionModel().setSelectionInterval(selection, selection); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isMultiSelected() { |
||||||
|
int[] selectedRow = table.getSelectedRows(); |
||||||
|
return (selectedRow.length == 1 && (selectedRow[0] > table.getRowCount() - 1 || selectedRow[0] < 0)) || selectedRow.length == 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkEnabled() { |
||||||
|
setEnabled(!isMultiSelected()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected class MoveUpAction extends UITableEditAction { |
||||||
|
|
||||||
|
public MoveUpAction() { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Basic_Utils_Move_Up")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/design/images/control/up.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
int selectedRow = table.getSelectedRow(); |
||||||
|
stopCellEditing(); |
||||||
|
if (getList().size() < 2 || selectedRow == 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Collections.swap(getList(), selectedRow, selectedRow - 1); |
||||||
|
fireTableDataChanged(); |
||||||
|
table.getSelectionModel().setSelectionInterval(selectedRow - 1, selectedRow - 1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkEnabled() { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected class MoveDownAction extends UITableEditAction { |
||||||
|
|
||||||
|
public MoveDownAction() { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Basic_Utils_Move_Down")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/design/images/control/down.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
int selectedRow = table.getSelectedRow(); |
||||||
|
stopCellEditing(); |
||||||
|
if (getList().size() < 2 || selectedRow == getRowCount() - 1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Collections.swap(getList(), selectedRow, selectedRow + 1); |
||||||
|
fireTableDataChanged(); |
||||||
|
table.getSelectionModel().setSelectionInterval(selectedRow + 1, selectedRow + 1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkEnabled() { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class ParameterEditor extends AbstractCellEditor implements TableCellEditor { |
||||||
|
|
||||||
|
private UITextField textField; |
||||||
|
|
||||||
|
public ParameterEditor() { |
||||||
|
textField = new UITextField(); |
||||||
|
this.addCellEditorListener(new CellEditorListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void editingCanceled(ChangeEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void editingStopped(ChangeEvent e) { |
||||||
|
if (table.getSelectedRow() == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
ParameterProvider para = getList().get(table.getSelectedRow()); |
||||||
|
String value = StringKit.trimToNull(textField.getText()); |
||||||
|
para.setName(value); |
||||||
|
fireTableDataChanged(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
textField.setText((String) value); |
||||||
|
return textField; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return textField.getText(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class ParameterValueEditor extends AbstractCellEditor implements TableCellEditor { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
private ValueEditorPane editor; |
||||||
|
|
||||||
|
public ParameterValueEditor(int paraUseType) { |
||||||
|
this(ValueEditors.createValueEditorPaneWithUseType(paraUseType)); |
||||||
|
} |
||||||
|
|
||||||
|
public ParameterValueEditor(ValueEditorPane valueEditorPane) { |
||||||
|
|
||||||
|
editor = valueEditorPane; |
||||||
|
|
||||||
|
this.addCellEditorListener(new CellEditorListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void editingCanceled(ChangeEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void editingStopped(ChangeEvent e) { |
||||||
|
if (table.getSelectedRow() == -1) { |
||||||
|
return; |
||||||
} |
} |
||||||
|
ParameterProvider para = getList().get(table.getSelectedRow()); |
||||||
|
para.setValue(getCellEditorValue()); |
||||||
|
fireTableDataChanged(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
editor.populate(value == null ? StringKit.EMPTY : value); |
||||||
|
return editor; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return editor.update(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private class ParameterValueRenderer extends DefaultTableCellRenderer { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
private ValueEditorPane editor; |
||||||
|
private UILabel disableLabel; |
||||||
|
|
||||||
|
public ParameterValueRenderer(int paraUseType) { |
||||||
|
this(ValueEditors.createValueEditorPaneWithUseType(paraUseType)); |
||||||
|
} |
||||||
|
|
||||||
|
public ParameterValueRenderer(ValueEditorPane valueEditorPane) { |
||||||
|
disableLabel = new UILabel(DesignKit.i18nText("Fine-Design_Basic_Set_Paramete_Name")); |
||||||
|
disableLabel.setForeground(Color.pink); |
||||||
|
disableLabel.setHorizontalAlignment(SwingConstants.CENTER); |
||||||
|
|
||||||
|
editor = valueEditorPane; |
||||||
|
} |
||||||
|
|
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||||
|
if (table.isCellEditable(row, column)) { |
||||||
|
if (value == null) { |
||||||
|
editor.populate(StringKit.EMPTY); |
||||||
|
} else { |
||||||
|
editor.populate(value); |
||||||
|
} |
||||||
|
return editor; |
||||||
|
} else { |
||||||
|
return disableLabel; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -0,0 +1,62 @@ |
|||||||
|
package com.fanruan.api.design.ui.component.table.model; |
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.table.action.UITableEditAction; |
||||||
|
import com.fanruan.api.util.IOKit; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public abstract class UITableModelAdapter<T> extends com.fr.design.gui.itableeditorpane.UITableModelAdapter<T> { |
||||||
|
|
||||||
|
protected UITableModelAdapter(String[] strings) { |
||||||
|
super(strings); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract UITableEditAction[] createAction(); |
||||||
|
|
||||||
|
|
||||||
|
protected abstract class AddTableRowAction extends UITableEditAction { |
||||||
|
|
||||||
|
public AddTableRowAction() { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Report_Insert")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/base/images/cell/control/add.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
stopCellEditing(); |
||||||
|
} |
||||||
|
|
||||||
|
public void checkEnabled() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract class EditAction extends UITableEditAction { |
||||||
|
|
||||||
|
public EditAction() { |
||||||
|
this.setName(DesignKit.i18nText("Fine-Design_Report_Edit")); |
||||||
|
this.setSmallIcon(IOKit.readIcon("/com/fr/design/images/control/edit.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
final int selectedRow = table.getSelectedRow(); |
||||||
|
if (selectedRow > table.getRowCount() - 1 || selectedRow < 0) { |
||||||
|
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), DesignKit.i18nText("Fine-Design_Basic_No-Alternatives")); |
||||||
|
return; |
||||||
|
} |
||||||
|
stopCellEditing(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
package com.fanruan.api.design.ui.container; |
||||||
|
|
||||||
|
public abstract class BasicBeanPane extends com.fr.design.beans.BasicBeanPane{ |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.fanruan.api.design.ui.container; |
||||||
|
|
||||||
|
import com.fanruan.api.design.ui.container.BasicPane; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
public class BasicDialog extends com.fr.design.dialog.BasicDialog{ |
||||||
|
public BasicDialog(Dialog parent){ |
||||||
|
super(parent); |
||||||
|
} |
||||||
|
|
||||||
|
public BasicDialog(Dialog parent, BasicPane pane){ |
||||||
|
super(parent, pane); |
||||||
|
} |
||||||
|
|
||||||
|
public BasicDialog(Dialog parent, BasicPane pane, boolean isNeedButton){ |
||||||
|
super(parent, pane, isNeedButton); |
||||||
|
} |
||||||
|
|
||||||
|
public BasicDialog(Frame parent){ |
||||||
|
super(parent); |
||||||
|
} |
||||||
|
|
||||||
|
public BasicDialog(Frame parent, BasicPane pane){ |
||||||
|
super(parent, pane); |
||||||
|
} |
||||||
|
|
||||||
|
public BasicDialog(Frame parent, BasicPane pane, boolean isNedButtonPane){ |
||||||
|
super(parent, pane, isNedButtonPane); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkValid(){ |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package com.fanruan.api.design.ui.container; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
|
||||||
|
public class DialogActionAdapter extends com.fr.design.dialog.DialogActionAdapter{ |
||||||
|
public DialogActionAdapter(){ |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.fanruan.api.design.ui.container; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 可滚动容器 |
||||||
|
*/ |
||||||
|
public class UIScrollPane extends com.fr.design.gui.icontainer.UIScrollPane { |
||||||
|
|
||||||
|
public UIScrollPane(Component component) { |
||||||
|
super(component); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,445 @@ |
|||||||
|
package com.fanruan.api.design.ui.editor; |
||||||
|
|
||||||
|
import com.fanruan.api.design.DesignKit; |
||||||
|
import com.fanruan.api.design.ui.component.table.model.ParameterTableModel; |
||||||
|
import com.fanruan.api.util.StringKit; |
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.design.editor.editor.BooleanEditor; |
||||||
|
import com.fr.design.editor.editor.ColumnRowEditor; |
||||||
|
import com.fr.design.editor.editor.ColumnRowGroupEditor; |
||||||
|
import com.fr.design.editor.editor.ColumnSelectedEditor; |
||||||
|
import com.fr.design.editor.editor.ConstantsEditor; |
||||||
|
import com.fr.design.editor.editor.CursorEditor; |
||||||
|
import com.fr.design.editor.editor.DateEditor; |
||||||
|
import com.fr.design.editor.editor.DoubleEditor; |
||||||
|
import com.fr.design.editor.editor.Editor; |
||||||
|
import com.fr.design.editor.editor.FormulaEditor; |
||||||
|
import com.fr.design.editor.editor.IntegerEditor; |
||||||
|
import com.fr.design.editor.editor.NoneEditor; |
||||||
|
import com.fr.design.editor.editor.ParameterEditor; |
||||||
|
import com.fr.design.editor.editor.SpinnerIntegerEditor; |
||||||
|
import com.fr.design.editor.editor.TextEditor; |
||||||
|
import com.fr.design.editor.editor.WidgetNameEditor; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-28 |
||||||
|
* 工厂类,创建多种组合编辑器 |
||||||
|
*/ |
||||||
|
public class ValueEditors { |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建带编辑器的ValueEditorPane |
||||||
|
* |
||||||
|
* @param editors 自定义的编辑器 |
||||||
|
* @return 返回pane |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createValueEditorPane(Editor<?>[] editors) { |
||||||
|
return createValueEditorPane(editors, StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建编辑器 名称 弹出的ValueEditorPane |
||||||
|
* |
||||||
|
* @param editors 编辑器 |
||||||
|
* @param popupName 弹出的名字 |
||||||
|
* @param textEditorValue 值 |
||||||
|
* @return 返回pane |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createValueEditorPane(Editor<?>[] editors, String popupName, String textEditorValue) { |
||||||
|
return new ValueEditorPane(editors, popupName, textEditorValue); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建编辑器 名称 弹出的ValueEditorPane |
||||||
|
* |
||||||
|
* @param editors 编辑器 |
||||||
|
* @param popupName 弹出的名字 |
||||||
|
* @param textEditorValue 值 |
||||||
|
* @param editor_center_width 编辑器主体的宽度 |
||||||
|
* @return 返回pane |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createValueEditorPane(Editor<?>[] editors, String popupName, String textEditorValue, int editor_center_width) { |
||||||
|
return new ValueEditorPane(editors, popupName, textEditorValue, editor_center_width); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建基本的值编辑器面板 |
||||||
|
* |
||||||
|
* @return 返回值编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createBasicValueEditorPane() { |
||||||
|
return createValueEditorPane(basicEditors(), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建公式编辑器面板 |
||||||
|
* |
||||||
|
* @return 返回公式编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createFormulaValueEditorPane() { |
||||||
|
return createValueEditorPane(new Editor[]{new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula"))}, |
||||||
|
StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建基本的值编辑器面板 |
||||||
|
* |
||||||
|
* @param editorCenterWidth 指定值编辑器的主体宽度 |
||||||
|
* @return 返回值编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createBasicValueEditorPane(int editorCenterWidth) { |
||||||
|
return createValueEditorPane(basicEditors(), StringKit.EMPTY, StringKit.EMPTY, editorCenterWidth); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Process用的editorPane |
||||||
|
* |
||||||
|
* @return 值编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createFormEditorPane() { |
||||||
|
return createValueEditorPane(formEditors(), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* URL使用的ValueEditorPane |
||||||
|
* |
||||||
|
* @param popupName 弹出的名字 |
||||||
|
* @param textEditorValue 编辑器值 |
||||||
|
* @return 值编辑器返回 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createURLValueEditorPane(String popupName, String textEditorValue) { |
||||||
|
return createValueEditorPane(URLEditors(popupName, textEditorValue), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建日期的ValueEditorPane |
||||||
|
* |
||||||
|
* @param popupName 名字 |
||||||
|
* @param textEditorValue 值 |
||||||
|
* @return 值编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createDateValueEditorPane(String popupName, String textEditorValue) { |
||||||
|
return createValueEditorPane(dateEditors(popupName, textEditorValue), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 带有所有编辑器的ValueEditorPane |
||||||
|
* |
||||||
|
* @return 值编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createAllValueEditorPane() { |
||||||
|
return createValueEditorPane(allEditors(), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建不带公式面板的pane |
||||||
|
* |
||||||
|
* @return 编辑器面板 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createBasicEditorWithoutFormulaPane() { |
||||||
|
return createValueEditorPane(basicEditorsWithoutFormula(), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建日期编辑器 |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createDateValueEditorPane() { |
||||||
|
return createValueEditorPane(dateEditors(), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据参数paraUseType 创建编辑器类型. |
||||||
|
* |
||||||
|
* @param paraUseType 参数类型 |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createValueEditorPaneWithUseType(int paraUseType) { |
||||||
|
return createValueEditorPaneWithUseType(paraUseType, null); |
||||||
|
} |
||||||
|
|
||||||
|
public static ValueEditorPane createValueEditorPaneWithUseType(int paraUseType, Map<String, BaseFormula> hyperLinkEditorMap) { |
||||||
|
if (paraUseType == ParameterTableModel.NO_CHART_USE) { |
||||||
|
return createBasicValueEditorPane(); |
||||||
|
} else if (paraUseType == ParameterTableModel.FORM_NORMAL_USE) { |
||||||
|
return createFormEditorPane(); |
||||||
|
} else { |
||||||
|
return createChartHotValueEditorPane(hyperLinkEditorMap); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 图表用的参数编辑器的ValueEditorPane |
||||||
|
* |
||||||
|
* @param hyperLinkEditorMap 超链下拉参数类型 |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createChartHotValueEditorPane(Map<String, BaseFormula> hyperLinkEditorMap) { |
||||||
|
return createValueEditorPane(chartHotEditors(hyperLinkEditorMap), StringKit.EMPTY, StringKit.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 基础的一些ValueEditorPane所用到的Editors |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] basicEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new SpinnerIntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 表单的一些编辑器. |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] formEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor, |
||||||
|
new WidgetNameEditor(DesignKit.i18nText("Fine-Design_Report_Widget")) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 扩展单元格的一些编辑器 |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] extendedEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
new ColumnRowEditor(DesignKit.i18nText("Fine-Design_Basic_Cell")) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 带单元格组的编辑器 |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] extendedCellGroupEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
new ColumnRowEditor(DesignKit.i18nText("Fine-Design_Basic_Cell")), |
||||||
|
new ColumnRowGroupEditor(DesignKit.i18nText("Fine-Design_Basic_Cell_Group")) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 只有单元格和单元格组的编辑器 |
||||||
|
* |
||||||
|
* @return 编辑器b |
||||||
|
*/ |
||||||
|
public static Editor<?>[] cellGroupEditor() { |
||||||
|
return new Editor[]{ |
||||||
|
new ColumnRowEditor(DesignKit.i18nText("Fine-Design_Basic_Cell")), |
||||||
|
new ColumnRowGroupEditor(DesignKit.i18nText("Fine-Design_Basic_Cell_Group")) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* URL的一些编辑器. |
||||||
|
* |
||||||
|
* @param popupName 名字 |
||||||
|
* @param textEditorValue 值 |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] URLEditors(String popupName, String textEditorValue) { |
||||||
|
return new Editor[]{ |
||||||
|
new NoneEditor(textEditorValue, StringKit.isEmpty(popupName) ? DesignKit.i18nText("Fine-Design_Basic_None") : popupName), |
||||||
|
new TextEditor() |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 日期类型的一些编辑器 |
||||||
|
* |
||||||
|
* @param popupName 名字 |
||||||
|
* @param textEditorValue 值 |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] dateEditors(String popupName, String textEditorValue) { |
||||||
|
return new Editor[]{ |
||||||
|
new NoneEditor(textEditorValue, StringKit.isEmpty(popupName) ? DesignKit.i18nText("Fine-Design_Basic_None") : popupName), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 所有类型的编辑器 |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] allEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
new ColumnRowEditor(DesignKit.i18nText("Fine-Design_Basic_Cell")), |
||||||
|
new ColumnSelectedEditor(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 不带公式编辑器 |
||||||
|
* |
||||||
|
* @return 编辑器不带公式 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] basicEditorsWithoutFormula() { |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* noCRnoColumn编辑器 |
||||||
|
* |
||||||
|
* @return 编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] noCRnoColumnEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 数值编辑器 |
||||||
|
* |
||||||
|
* @return 编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] numberEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 日期编辑器 |
||||||
|
* |
||||||
|
* @return 编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] dateEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
return new Editor[]{ |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
formulaEditor, |
||||||
|
new ParameterEditor(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 存储的一些编辑器 |
||||||
|
* |
||||||
|
* @return 存储过程的编辑器 |
||||||
|
*/ |
||||||
|
public static Editor<?>[] StoreProcedureEditors() { |
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
formulaEditor.setEnabled(true); |
||||||
|
return new Editor[]{ |
||||||
|
new CursorEditor(), |
||||||
|
new TextEditor(), |
||||||
|
new IntegerEditor(), |
||||||
|
new DoubleEditor(), |
||||||
|
new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date")), |
||||||
|
new BooleanEditor(), |
||||||
|
formulaEditor |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 图表热点的一些编辑器 |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
public static Editor[] chartHotEditors(Map<String, BaseFormula> hyperLinkEditorMap) { |
||||||
|
List<Editor> list = createEditors4Chart(hyperLinkEditorMap); |
||||||
|
|
||||||
|
list.add(new TextEditor()); |
||||||
|
list.add(new IntegerEditor()); |
||||||
|
list.add(new DoubleEditor()); |
||||||
|
list.add(new DateEditor(true, DesignKit.i18nText("Fine-Design_Basic_Date"))); |
||||||
|
list.add(new BooleanEditor()); |
||||||
|
|
||||||
|
FormulaEditor formulaEditor = new FormulaEditor(DesignKit.i18nText("Fine-Design_Basic_Parameter_Formula")); |
||||||
|
formulaEditor.setEnabled(true); |
||||||
|
list.add(formulaEditor); |
||||||
|
|
||||||
|
return list.toArray(new Editor[0]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 为图表创建编辑器. |
||||||
|
* |
||||||
|
* @return 值编辑器 |
||||||
|
*/ |
||||||
|
private static List<Editor> createEditors4Chart(Map<String, BaseFormula> hyperLinkEditorMap) { |
||||||
|
List<Editor> lists = new ArrayList<>(); |
||||||
|
if (hyperLinkEditorMap == null) { |
||||||
|
return lists; |
||||||
|
} |
||||||
|
Iterator<Map.Entry<String, BaseFormula>> entries = hyperLinkEditorMap.entrySet().iterator(); |
||||||
|
while (entries.hasNext()) { |
||||||
|
Map.Entry<String, BaseFormula> entry = entries.next(); |
||||||
|
ConstantsEditor editor = new ConstantsEditor(entry.getKey(), entry.getValue()); |
||||||
|
editor.setEnabled(false); |
||||||
|
lists.add(editor); |
||||||
|
} |
||||||
|
return lists; |
||||||
|
} |
||||||
|
} |
@ -1,31 +0,0 @@ |
|||||||
package com.fanruan.api.design.util; |
|
||||||
|
|
||||||
import com.fr.design.i18n.Toolkit; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author richie |
|
||||||
* @version 10.0 |
|
||||||
* Created by richie on 2019-08-28 |
|
||||||
* 设计器国际化工具类,设计器相关类的国际化都需要调用这个类才行 |
|
||||||
*/ |
|
||||||
public class I18nDesignKit { |
|
||||||
|
|
||||||
/** |
|
||||||
* 文本国际化 |
|
||||||
* @param key 国际化键 |
|
||||||
* @return 国际化后的值 |
|
||||||
*/ |
|
||||||
public String i18nText(String key) { |
|
||||||
return Toolkit.i18nText(key); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 带参数的文本国际化 |
|
||||||
* @param key 国际化键 |
|
||||||
* @param args 参数 |
|
||||||
* @return 国际化后的值 |
|
||||||
*/ |
|
||||||
public String i18nText(String key, Object... args) { |
|
||||||
return Toolkit.i18nText(key, args); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,9 @@ |
|||||||
|
package com.fanruan.api.design.work; |
||||||
|
|
||||||
|
import com.fr.data.impl.Connection; |
||||||
|
|
||||||
|
public class ConnectionComboBoxPanel extends com.fr.design.data.datapane.connect.ConnectionComboBoxPanel{ |
||||||
|
public ConnectionComboBoxPanel(Class<? extends Connection> cls) { |
||||||
|
super(cls); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package com.fanruan.api.design.work; |
||||||
|
|
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
public abstract class DatabaseConnectionPane extends com.fr.design.data.datapane.connect.DatabaseConnectionPane{ |
||||||
|
|
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
package com.fanruan.api.err; |
||||||
|
|
||||||
|
public class UtilEvalError extends com.fr.stable.UtilEvalError{ |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fanruan.api.macro; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 编码常量 |
||||||
|
*/ |
||||||
|
public interface EncodeConstants { |
||||||
|
|
||||||
|
/** |
||||||
|
* utf-8编码 |
||||||
|
*/ |
||||||
|
String ENCODING_UTF_8 = com.fr.stable.EncodeConstants.ENCODING_UTF_8; |
||||||
|
|
||||||
|
/** |
||||||
|
* gbk编码 |
||||||
|
*/ |
||||||
|
String ENCODING_GBK = com.fr.stable.EncodeConstants.ENCODING_GBK; |
||||||
|
|
||||||
|
/** |
||||||
|
* big5编码,一般用于繁体中文 |
||||||
|
*/ |
||||||
|
String ENCODING_BIG5 = com.fr.stable.EncodeConstants.ENCODING_BIG5; |
||||||
|
|
||||||
|
/** |
||||||
|
* ios-8859-1编码 |
||||||
|
*/ |
||||||
|
String ENCODING_ISO_8859_1 = com.fr.stable.EncodeConstants.ENCODING_ISO_8859_1; |
||||||
|
|
||||||
|
/** |
||||||
|
* utf16编码 |
||||||
|
*/ |
||||||
|
String ENCODING_UTF_16 = com.fr.stable.EncodeConstants.ENCODING_UTF_16; |
||||||
|
|
||||||
|
/** |
||||||
|
* euc-jp编码 |
||||||
|
*/ |
||||||
|
String ENCODING_EUC_JP = com.fr.stable.EncodeConstants.ENCODING_EUC_JP; |
||||||
|
|
||||||
|
/** |
||||||
|
* euc-kr编码 |
||||||
|
*/ |
||||||
|
String ENCODING_EUC_KR = com.fr.stable.EncodeConstants.ENCODING_EUC_KR; |
||||||
|
|
||||||
|
/** |
||||||
|
* cp850编码 |
||||||
|
*/ |
||||||
|
String ENCODING_CP850 = com.fr.stable.EncodeConstants.ENCODING_CP850; |
||||||
|
} |
@ -0,0 +1,677 @@ |
|||||||
|
package com.fanruan.api.net.http; |
||||||
|
|
||||||
|
import com.fanruan.api.macro.EncodeConstants; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.net.http.rs.BaseHttpResponseHandle; |
||||||
|
import com.fanruan.api.net.http.rs.HttpRequest; |
||||||
|
import com.fanruan.api.net.http.rs.HttpRequestType; |
||||||
|
import com.fanruan.api.net.http.rs.HttpResponseType; |
||||||
|
import com.fanruan.api.net.http.rs.StreamResponseHandle; |
||||||
|
import com.fanruan.api.net.http.rs.TextResponseHandle; |
||||||
|
import com.fanruan.api.net.http.rs.UploadResponseHandle; |
||||||
|
import com.fr.third.guava.collect.Maps; |
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.HttpEntityEnclosingRequest; |
||||||
|
import com.fr.third.org.apache.http.HttpHost; |
||||||
|
import com.fr.third.org.apache.http.NameValuePair; |
||||||
|
import com.fr.third.org.apache.http.NoHttpResponseException; |
||||||
|
import com.fr.third.org.apache.http.client.HttpRequestRetryHandler; |
||||||
|
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||||
|
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpEntityEnclosingRequestBase; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpRequestBase; |
||||||
|
import com.fr.third.org.apache.http.client.protocol.HttpClientContext; |
||||||
|
import com.fr.third.org.apache.http.client.utils.URIBuilder; |
||||||
|
import com.fr.third.org.apache.http.config.Registry; |
||||||
|
import com.fr.third.org.apache.http.config.RegistryBuilder; |
||||||
|
import com.fr.third.org.apache.http.conn.routing.HttpRoute; |
||||||
|
import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory; |
||||||
|
import com.fr.third.org.apache.http.conn.socket.LayeredConnectionSocketFactory; |
||||||
|
import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory; |
||||||
|
import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||||
|
import com.fr.third.org.apache.http.entity.FileEntity; |
||||||
|
import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode; |
||||||
|
import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder; |
||||||
|
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||||
|
import com.fr.third.org.apache.http.impl.client.HttpClients; |
||||||
|
import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||||
|
import com.fr.third.org.apache.http.message.BasicNameValuePair; |
||||||
|
import com.fr.third.org.apache.http.protocol.HttpContext; |
||||||
|
import com.fr.third.org.apache.http.ssl.SSLContexts; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext; |
||||||
|
import javax.net.ssl.SSLException; |
||||||
|
import javax.net.ssl.SSLHandshakeException; |
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InterruptedIOException; |
||||||
|
import java.io.UnsupportedEncodingException; |
||||||
|
import java.net.URI; |
||||||
|
import java.net.URISyntaxException; |
||||||
|
import java.net.URLEncoder; |
||||||
|
import java.net.UnknownHostException; |
||||||
|
import java.nio.charset.Charset; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static com.fanruan.api.net.http.rs.HttpRequestType.POST; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
* <p> |
||||||
|
* http请求工具类,封装了用于http请求的各种方法 |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public class HttpKit { |
||||||
|
|
||||||
|
private static final int RETRY_TIMES = 5; |
||||||
|
|
||||||
|
private static CloseableHttpClient httpClient = null; |
||||||
|
|
||||||
|
private final static Object SYNC_LOCK = new Object(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据请求地址创建HttpClient对象 |
||||||
|
* |
||||||
|
* @param url 请求地址 |
||||||
|
* @return HttpClient对象 |
||||||
|
*/ |
||||||
|
public static CloseableHttpClient getHttpClient(String url) { |
||||||
|
String hostname = url.split("/")[2]; |
||||||
|
int port = 80; |
||||||
|
if (hostname.contains(":")) { |
||||||
|
String[] arr = hostname.split(":"); |
||||||
|
hostname = arr[0]; |
||||||
|
port = Integer.parseInt(arr[1]); |
||||||
|
} |
||||||
|
if (httpClient == null) { |
||||||
|
synchronized (SYNC_LOCK) { |
||||||
|
if (httpClient == null) { |
||||||
|
httpClient = createHttpClient(hostname, port, SSLContexts.createDefault()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return httpClient; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static CloseableHttpClient createHttpClient(String hostname, int port, SSLContext sslContext) { |
||||||
|
return createHttpClient(200, 40, 100, hostname, port, sslContext); |
||||||
|
} |
||||||
|
|
||||||
|
private static CloseableHttpClient createHttpClient(int maxTotal, |
||||||
|
int maxPerRoute, |
||||||
|
int maxRoute, |
||||||
|
String hostname, |
||||||
|
int port, |
||||||
|
SSLContext sslContext) { |
||||||
|
ConnectionSocketFactory socketFactory = PlainConnectionSocketFactory.getSocketFactory(); |
||||||
|
LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext); |
||||||
|
Registry<ConnectionSocketFactory> registry = RegistryBuilder |
||||||
|
.<ConnectionSocketFactory>create() |
||||||
|
.register("http", socketFactory) |
||||||
|
.register("https", sslConnectionSocketFactory) |
||||||
|
.build(); |
||||||
|
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); |
||||||
|
// 将最大连接数增加
|
||||||
|
cm.setMaxTotal(maxTotal); |
||||||
|
// 将每个路由基础的连接增加
|
||||||
|
cm.setDefaultMaxPerRoute(maxPerRoute); |
||||||
|
HttpHost httpHost = new HttpHost(hostname, port); |
||||||
|
// 将目标主机的最大连接数增加
|
||||||
|
cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute); |
||||||
|
|
||||||
|
// 请求重试处理
|
||||||
|
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { |
||||||
|
@Override |
||||||
|
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { |
||||||
|
if (executionCount >= RETRY_TIMES) {// 如果已经重试了5次,就放弃
|
||||||
|
return false; |
||||||
|
} |
||||||
|
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
|
||||||
|
return true; |
||||||
|
} |
||||||
|
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
|
||||||
|
return false; |
||||||
|
} |
||||||
|
if (exception instanceof InterruptedIOException) {// 超时
|
||||||
|
return false; |
||||||
|
} |
||||||
|
if (exception instanceof UnknownHostException) {// 目标服务器不可达
|
||||||
|
return false; |
||||||
|
} |
||||||
|
if (exception instanceof SSLException) {// SSL握手异常
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
HttpClientContext clientContext = HttpClientContext.adapt(context); |
||||||
|
com.fr.third.org.apache.http.HttpRequest request = clientContext.getRequest(); |
||||||
|
// 如果请求是幂等的,就再次尝试
|
||||||
|
return !(request instanceof HttpEntityEnclosingRequest); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return HttpClients.custom() |
||||||
|
.setConnectionManager(cm) |
||||||
|
.setRetryHandler(httpRequestRetryHandler) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置 httpEntity |
||||||
|
* |
||||||
|
* @param requestBase 请求体 |
||||||
|
* @param httpRequest 请求 |
||||||
|
*/ |
||||||
|
private static void setHttpEntity(@NotNull HttpEntityEnclosingRequestBase requestBase, @NotNull HttpRequest httpRequest) { |
||||||
|
HttpEntity httpEntity = httpRequest.getHttpEntity(); |
||||||
|
if (httpEntity != null) { |
||||||
|
// 如果存在 httpEntity 直接设置
|
||||||
|
requestBase.setEntity(httpEntity); |
||||||
|
return; |
||||||
|
} |
||||||
|
Map<String, String> params = httpRequest.getParams(); |
||||||
|
if (params == null || params.isEmpty()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
List<NameValuePair> pairs = new ArrayList<NameValuePair>(); |
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||||
|
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); |
||||||
|
} |
||||||
|
try { |
||||||
|
requestBase.setEntity(new UrlEncodedFormEntity(pairs, httpRequest.getEncoding())); |
||||||
|
} catch (UnsupportedEncodingException e) { |
||||||
|
LogKit.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static <V> Map<String, String> transformMap(Map<String, V> oldMap) { |
||||||
|
if (oldMap == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return Maps.transformEntries(oldMap, new Maps.EntryTransformer<String, V, String>() { |
||||||
|
@Override |
||||||
|
public String transformEntry(@Nullable String key, @Nullable V value) { |
||||||
|
return value == null ? null : value.toString(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
*/ |
||||||
|
public static <V> String post(String url, Map<String, V> params) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param responseType 返回类型 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static <T, V> T post(String url, Map<String, V> params, HttpResponseType<T> responseType) throws IOException { |
||||||
|
CloseableHttpResponse response = execute(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.build()); |
||||||
|
return responseType.result(response, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param headers 请求头 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest) |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static <V> String post(String url, Map<String, V> params, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.headers(headers) |
||||||
|
.build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param headers 请求头 |
||||||
|
* @param responseType 返回类型 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static <T, V> T post(String url, Map<String, V> params, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||||
|
CloseableHttpResponse response = execute(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.headers(headers) |
||||||
|
.build()); |
||||||
|
return responseType.result(response, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param responseEncoding 响应的文本的编码 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static <V> String post(String url, Map<String, V> params, String responseEncoding) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.build(), |
||||||
|
new TextResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param responseEncoding 响应的文本的编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static <V> String post(String url, Map<String, V> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.headers(headers) |
||||||
|
.build(), |
||||||
|
new TextResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param responseEncoding 响应的文本的编码 |
||||||
|
* @param paramsEncoding 参数编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
public static <V> String post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.encoding(paramsEncoding) |
||||||
|
.headers(headers) |
||||||
|
.build(), |
||||||
|
new TextResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起POST请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params POST请求的参数 |
||||||
|
* @param responseEncoding 响应的文本的编码 |
||||||
|
* @param paramsEncoding 参数编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @param responseType 返回值类型 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||||
|
*/ |
||||||
|
public static <T, V> T post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||||
|
CloseableHttpResponse response = execute(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(transformMap(params)) |
||||||
|
.encoding(paramsEncoding) |
||||||
|
.headers(headers) |
||||||
|
.build()); |
||||||
|
return responseType.result(response, responseEncoding); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起GET请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
*/ |
||||||
|
public static String get(String url) throws IOException { |
||||||
|
return executeAndParse(HttpRequest.custom().url(url).build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起GET请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params 参数 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
*/ |
||||||
|
public static String get(String url, Map<String, String> params) throws IOException { |
||||||
|
return executeAndParse(HttpRequest.custom().url(url).params(params).build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起GET请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params 参数 |
||||||
|
* @param headers 请求头 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest.custom().url(url).params(params).headers(headers).build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起GET请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params 参数 |
||||||
|
* @param responseEncoding 返回的文本的编码 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
public static String get(String url, Map<String, String> params, String responseEncoding) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.params(params) |
||||||
|
.build(), |
||||||
|
new TextResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发起GET请求并获取返回的文本 |
||||||
|
* |
||||||
|
* @param url 响应请求的的服务器地址 |
||||||
|
* @param params 参数 |
||||||
|
* @param responseEncoding 返回的文本的编码 |
||||||
|
* @return 服务器返回的文本内容 |
||||||
|
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||||
|
*/ |
||||||
|
public static String get(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.params(params) |
||||||
|
.headers(headers) |
||||||
|
.build(), |
||||||
|
new TextResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从指定的地址下载文件 |
||||||
|
* @param url 文件下载地址 |
||||||
|
* @return 文件的字节流 |
||||||
|
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static ByteArrayInputStream download(String url) throws IOException { |
||||||
|
return executeAndParse(HttpRequest.custom().url(url).build(), StreamResponseHandle.DEFAULT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从指定的地址下载文件 |
||||||
|
* @param url 文件下载地址 |
||||||
|
* @param params 参数对 |
||||||
|
* @param responseEncoding 响应的文件编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @return 文件的字节流 |
||||||
|
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static ByteArrayInputStream download(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||||
|
return executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.params(params) |
||||||
|
.headers(headers) |
||||||
|
.build(), |
||||||
|
new StreamResponseHandle(responseEncoding)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param file 要上传的文件,默认的文件编码为utf-8 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, File file) throws IOException { |
||||||
|
upload(url, file, Charset.forName("utf-8")); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param file 要上传的文件 |
||||||
|
* @param charset 文件的编码 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, File file, Charset charset) throws IOException { |
||||||
|
upload(url, new FileEntity(file), charset); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param builder 附件构造器 |
||||||
|
* @param charset 文件的编码 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, MultipartEntityBuilder builder, Charset charset) throws IOException { |
||||||
|
upload(url, builder, charset, Collections.<String, String>emptyMap(), POST); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param fileEntity 文件实体 |
||||||
|
* @param charset 文件的编码 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, FileEntity fileEntity, Charset charset) throws IOException { |
||||||
|
upload(url, fileEntity, charset, Collections.<String, String>emptyMap(), POST); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传多文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param builder 附件构造器 |
||||||
|
* @param charset 文件的编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @param httpRequestType 请求类型 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, MultipartEntityBuilder builder, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||||
|
// richie:采用浏览器模式,防止出现乱码
|
||||||
|
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); |
||||||
|
HttpEntity reqEntity = builder.setCharset(charset).build(); |
||||||
|
upload(url, reqEntity, charset, headers, httpRequestType); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传文件到指定的服务器 |
||||||
|
* |
||||||
|
* @param url 接收文件的服务器地址 |
||||||
|
* @param reqEntity 请求实体 |
||||||
|
* @param charset 文件的编码 |
||||||
|
* @param headers 请求头 |
||||||
|
* @param httpRequestType 请求类型 |
||||||
|
* @throws IOException 上传中出现错误则抛出此异常 |
||||||
|
*/ |
||||||
|
public static void upload(String url, HttpEntity reqEntity, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||||
|
executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.headers(headers) |
||||||
|
.method(httpRequestType) |
||||||
|
.httpEntity(reqEntity) |
||||||
|
.encoding(charset.toString()) |
||||||
|
.build(), |
||||||
|
UploadResponseHandle.DEFAULT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求资源或服务,使用默认文本http解析器,UTF-8编码 |
||||||
|
* |
||||||
|
* @param httpRequest httpRequest |
||||||
|
* @return 返回处理结果 |
||||||
|
*/ |
||||||
|
public static String executeAndParse(HttpRequest httpRequest) throws IOException { |
||||||
|
return executeAndParse(httpRequest, TextResponseHandle.DEFAULT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求资源或服务,自请求参数,并指定 http 响应处理器 |
||||||
|
* 例: |
||||||
|
* <pre> |
||||||
|
* String res = HttpToolbox.executeAndParse(HttpRequest |
||||||
|
* .custom() |
||||||
|
* .url("") |
||||||
|
* .build(), |
||||||
|
* TextResponseHandle.DEFAULT); |
||||||
|
* </pre> |
||||||
|
* |
||||||
|
* @param httpRequest httpRequest |
||||||
|
* @param handle http 解析器 |
||||||
|
* @return 返回处理结果 |
||||||
|
*/ |
||||||
|
public static <T> T executeAndParse(HttpRequest httpRequest, BaseHttpResponseHandle<T> handle) throws IOException { |
||||||
|
return handle.parse(execute(httpRequest)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求资源或服务,传入请求参数 |
||||||
|
* |
||||||
|
* @param httpRequest httpRequest |
||||||
|
* @return 返回处理结果 |
||||||
|
*/ |
||||||
|
public static CloseableHttpResponse execute(HttpRequest httpRequest) throws IOException { |
||||||
|
return execute(getHttpClient(httpRequest.getUrl()), httpRequest); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求资源或服务,自定义client对象,传入请求参数 |
||||||
|
* |
||||||
|
* @param httpClient http客户端 |
||||||
|
* @param httpRequest httpRequest |
||||||
|
* @return 返回处理结果 |
||||||
|
*/ |
||||||
|
public static CloseableHttpResponse execute(CloseableHttpClient httpClient, HttpRequest httpRequest) throws IOException { |
||||||
|
String url = httpRequest.getUrl(); |
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
HttpRequestBase httpRequestBase = httpRequest.getMethod().createHttpRequest(url); |
||||||
|
|
||||||
|
// 设置header信息
|
||||||
|
httpRequestBase.setHeader("User-Agent", "Mozilla/5.0"); |
||||||
|
Map<String, String> headers = httpRequest.getHeaders(); |
||||||
|
if (headers != null && !headers.isEmpty()) { |
||||||
|
for (Map.Entry<String, String> entry : headers.entrySet()) { |
||||||
|
httpRequestBase.setHeader(entry.getKey(), entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 配置请求的设置
|
||||||
|
RequestConfig requestConfig = httpRequest.getConfig(); |
||||||
|
if (requestConfig != null) { |
||||||
|
httpRequestBase.setConfig(requestConfig); |
||||||
|
} |
||||||
|
|
||||||
|
// 判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
|
||||||
|
if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(httpRequestBase.getClass())) { |
||||||
|
setHttpEntity((HttpEntityEnclosingRequestBase) httpRequestBase, httpRequest); |
||||||
|
} else { |
||||||
|
Map<String, String> params = httpRequest.getParams(); |
||||||
|
if (params != null && !params.isEmpty()) { |
||||||
|
// 注意get等不支持设置entity需要更新拼接之后的URL,但是url变量没有更新
|
||||||
|
httpRequestBase.setURI(URI.create(buildUrl(url, params, httpRequest.getEncoding()))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return httpClient.execute(httpRequestBase); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 构建 Url |
||||||
|
* |
||||||
|
* @param url 请求地址 |
||||||
|
* @param params 参数 |
||||||
|
* @return 拼接之后的地址 |
||||||
|
*/ |
||||||
|
public static String buildUrl(String url, Map<String, String> params) { |
||||||
|
try { |
||||||
|
return buildUrl(url, params, EncodeConstants.ENCODING_UTF_8); |
||||||
|
} catch (UnsupportedEncodingException ignore) { |
||||||
|
} |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 构建 Url |
||||||
|
* |
||||||
|
* @param url 请求地址 |
||||||
|
* @param params 参数 |
||||||
|
* @return 拼接之后的地址 |
||||||
|
* @throws UnsupportedEncodingException 不支持的编码 |
||||||
|
*/ |
||||||
|
private static String buildUrl(String url, Map<String, String> params, String paramsEncoding) throws UnsupportedEncodingException { |
||||||
|
if (params == null || params.isEmpty()) { |
||||||
|
return url; |
||||||
|
} |
||||||
|
URIBuilder builder; |
||||||
|
try { |
||||||
|
builder = new URIBuilder(url); |
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||||
|
String key = URLEncoder.encode(entry.getKey(), paramsEncoding); |
||||||
|
String value = URLEncoder.encode(entry.getValue(), paramsEncoding); |
||||||
|
builder.setParameter(key, value); |
||||||
|
} |
||||||
|
return builder.build().toString(); |
||||||
|
} catch (URISyntaxException e) { |
||||||
|
LogKit.debug("Error to build url, please check the arguments."); |
||||||
|
} |
||||||
|
return url; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.stable.EncodeConstants; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* http 结果解析器 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @date 2019-07-14 |
||||||
|
*/ |
||||||
|
public abstract class BaseHttpResponseHandle<T> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 解析编码,默认为 UTF_8 |
||||||
|
*/ |
||||||
|
private String encoding = EncodeConstants.ENCODING_UTF_8; |
||||||
|
|
||||||
|
public BaseHttpResponseHandle() { |
||||||
|
} |
||||||
|
|
||||||
|
public BaseHttpResponseHandle(String encoding) { |
||||||
|
this.encoding = encoding; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取解析编码 |
||||||
|
* |
||||||
|
* @return 解析编码 |
||||||
|
*/ |
||||||
|
public String getEncoding() { |
||||||
|
return encoding; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置解析编码 |
||||||
|
* |
||||||
|
* @param encoding 解析编码 |
||||||
|
*/ |
||||||
|
public void setEncoding(String encoding) { |
||||||
|
this.encoding = encoding; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 解析响应结果 |
||||||
|
* |
||||||
|
* @param response 响应 |
||||||
|
* @return 解析结果 |
||||||
|
* @throws IOException io异常 |
||||||
|
*/ |
||||||
|
public abstract T parse(CloseableHttpResponse response) throws IOException; |
||||||
|
} |
@ -0,0 +1,215 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fanruan.api.macro.EncodeConstants; |
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
*/ |
||||||
|
public class HttpRequest { |
||||||
|
|
||||||
|
private static final int TIME_OUT = 10 * 1000; |
||||||
|
private static final RequestConfig DEFAULT = RequestConfig |
||||||
|
.custom() |
||||||
|
.setConnectionRequestTimeout(TIME_OUT) |
||||||
|
.setConnectTimeout(TIME_OUT) |
||||||
|
.setSocketTimeout(TIME_OUT) |
||||||
|
.build(); |
||||||
|
/** |
||||||
|
* 请求地址 |
||||||
|
*/ |
||||||
|
private String url; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求头 |
||||||
|
*/ |
||||||
|
private Map<String, String> headers; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求参数 |
||||||
|
*/ |
||||||
|
private Map<String, String> params; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求参数 |
||||||
|
* |
||||||
|
* @see RequestConfig |
||||||
|
*/ |
||||||
|
@Nullable |
||||||
|
private RequestConfig config; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求参数 |
||||||
|
* |
||||||
|
* @see HttpEntity |
||||||
|
*/ |
||||||
|
@Nullable |
||||||
|
private HttpEntity httpEntity; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求方法 |
||||||
|
*/ |
||||||
|
private HttpRequestType method; |
||||||
|
|
||||||
|
/** |
||||||
|
* 参数字符集 |
||||||
|
*/ |
||||||
|
private String encoding; |
||||||
|
|
||||||
|
private HttpRequest(Builder builder) { |
||||||
|
this.url = builder.url; |
||||||
|
this.headers = builder.headers; |
||||||
|
this.params = builder.params; |
||||||
|
this.config = builder.config; |
||||||
|
this.encoding = builder.encoding; |
||||||
|
this.httpEntity = builder.httpEntity; |
||||||
|
this.method = builder.method; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUrl() { |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getHeaders() { |
||||||
|
return headers; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getParams() { |
||||||
|
return params; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestConfig getConfig() { |
||||||
|
return config; |
||||||
|
} |
||||||
|
|
||||||
|
public String getEncoding() { |
||||||
|
return encoding; |
||||||
|
} |
||||||
|
|
||||||
|
public HttpEntity getHttpEntity() { |
||||||
|
return httpEntity; |
||||||
|
} |
||||||
|
|
||||||
|
public HttpRequestType getMethod() { |
||||||
|
return method; |
||||||
|
} |
||||||
|
|
||||||
|
public static Builder custom() { |
||||||
|
return new Builder(); |
||||||
|
} |
||||||
|
|
||||||
|
public static final class Builder { |
||||||
|
private String url; |
||||||
|
private Map<String, String> headers = Collections.emptyMap(); |
||||||
|
private Map<String, String> params = Collections.emptyMap(); |
||||||
|
@Nullable |
||||||
|
private RequestConfig config = DEFAULT; |
||||||
|
@Nullable |
||||||
|
private HttpEntity httpEntity; |
||||||
|
private String encoding = EncodeConstants.ENCODING_UTF_8; |
||||||
|
private HttpRequestType method = HttpRequestType.GET; |
||||||
|
|
||||||
|
private Builder() { |
||||||
|
} |
||||||
|
|
||||||
|
public HttpRequest build() { |
||||||
|
if (this.url == null) { |
||||||
|
throw new IllegalStateException("url == null"); |
||||||
|
} |
||||||
|
return new HttpRequest(this); |
||||||
|
} |
||||||
|
|
||||||
|
public Builder url(@NotNull String url) { |
||||||
|
if (url == null) { |
||||||
|
throw new NullPointerException("url == null"); |
||||||
|
} |
||||||
|
this.url = url; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder headers(Map<String, String> headers) { |
||||||
|
if (headers != null) { |
||||||
|
this.headers = headers; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder params(Map<String, String> params) { |
||||||
|
if (params != null) { |
||||||
|
this.params = params; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder config(RequestConfig config) { |
||||||
|
this.config = config; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder get() { |
||||||
|
this.method = HttpRequestType.GET; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder post(HttpEntity httpEntity) { |
||||||
|
this.method = HttpRequestType.POST; |
||||||
|
this.httpEntity(httpEntity); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder post(Map<String, String> params) { |
||||||
|
this.method = HttpRequestType.POST; |
||||||
|
this.params(params); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder put(HttpEntity httpEntity) { |
||||||
|
this.method = HttpRequestType.PUT; |
||||||
|
this.httpEntity(httpEntity); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder put(Map<String, String> params) { |
||||||
|
this.method = HttpRequestType.PUT; |
||||||
|
this.params(params); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder delete() { |
||||||
|
this.method = HttpRequestType.DELETE; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder encoding(String encoding) { |
||||||
|
if (encoding == null) { |
||||||
|
throw new NullPointerException("httpEntity == null"); |
||||||
|
} |
||||||
|
this.encoding = encoding; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder httpEntity(HttpEntity httpEntity) { |
||||||
|
this.httpEntity = httpEntity; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder method(@NotNull HttpRequestType method) { |
||||||
|
if (method == null) { |
||||||
|
throw new NullPointerException("method == null"); |
||||||
|
} |
||||||
|
this.method = method; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpDelete; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpGet; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpHead; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpOptions; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpPatch; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpPost; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpPut; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpRequestBase; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpTrace; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
*/ |
||||||
|
public enum HttpRequestType { |
||||||
|
/** |
||||||
|
* 求获取Request-URI所标识的资源 |
||||||
|
*/ |
||||||
|
GET("GET") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpGet(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 |
||||||
|
* POST请求可能会导致新的资源的建立和/或已有资源的修改 |
||||||
|
*/ |
||||||
|
POST("POST") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpPost(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。 |
||||||
|
* 这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息 |
||||||
|
* 只获取响应信息报头 |
||||||
|
*/ |
||||||
|
HEAD("HEAD") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpHead(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 向指定资源位置上传其最新内容(全部更新,操作幂等) |
||||||
|
*/ |
||||||
|
PUT("PUT") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpPut(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求服务器删除Request-URI所标识的资源 |
||||||
|
*/ |
||||||
|
DELETE("DELETE") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpDelete(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求服务器回送收到的请求信息,主要用于测试或诊断 |
||||||
|
*/ |
||||||
|
TRACE("TRACE") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpTrace(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 向指定资源位置上传其最新内容(部分更新,非幂等) |
||||||
|
*/ |
||||||
|
PATCH("PATCH") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpPatch(url); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回服务器针对特定资源所支持的HTTP请求方法。 |
||||||
|
* 也可以利用向Web服务器发送'*'的请求来测试服务器的功能性 |
||||||
|
*/ |
||||||
|
OPTIONS("OPTIONS") { |
||||||
|
@Override |
||||||
|
public HttpRequestBase createHttpRequest(String url) { |
||||||
|
return new HttpOptions(url); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public abstract HttpRequestBase createHttpRequest(String url); |
||||||
|
|
||||||
|
private String name; |
||||||
|
|
||||||
|
HttpRequestType(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpUriRequest; |
||||||
|
import com.fr.third.org.apache.http.client.protocol.HttpClientContext; |
||||||
|
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||||
|
import com.fr.third.org.apache.http.util.EntityUtils; |
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
*/ |
||||||
|
public interface HttpResponseType<T> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 处理http响应 |
||||||
|
* |
||||||
|
* @param client 客户端 |
||||||
|
* @param url 地址 |
||||||
|
* @param request 请求 |
||||||
|
* @param charset 字符集 |
||||||
|
* @return 处理之后的响应 |
||||||
|
* @throws IOException 异常 |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
T result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 处理http响应 |
||||||
|
* |
||||||
|
* @param response 响应 |
||||||
|
* @param charset 字符集 |
||||||
|
* @return 处理之后的响应 |
||||||
|
* @throws IOException 异常 |
||||||
|
*/ |
||||||
|
T result(CloseableHttpResponse response, String charset) throws IOException; |
||||||
|
|
||||||
|
HttpResponseType<String> TEXT = new HttpResponseType<String>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException { |
||||||
|
CloseableHttpResponse response = client.execute(request, HttpClientContext.create()); |
||||||
|
return result(response, charset); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String result(CloseableHttpResponse response, String charset) throws IOException { |
||||||
|
try { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
String result = EntityUtils.toString(entity, charset); |
||||||
|
EntityUtils.consume(entity); |
||||||
|
return result; |
||||||
|
} finally { |
||||||
|
if (response != null) { |
||||||
|
response.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
HttpResponseType<ByteArrayInputStream> STREAM = new HttpResponseType<ByteArrayInputStream>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public ByteArrayInputStream result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException { |
||||||
|
CloseableHttpResponse response = client.execute(request, HttpClientContext.create()); |
||||||
|
return result(response, charset); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ByteArrayInputStream result(CloseableHttpResponse response, String charset) throws IOException { |
||||||
|
InputStream in = null; |
||||||
|
try { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
if (entity != null) { |
||||||
|
in = entity.getContent(); |
||||||
|
byte[] buff = new byte[8000]; |
||||||
|
int bytesRead; |
||||||
|
ByteArrayOutputStream bao = new ByteArrayOutputStream(); |
||||||
|
while ((bytesRead = in.read(buff)) != -1) { |
||||||
|
bao.write(buff, 0, bytesRead); |
||||||
|
} |
||||||
|
byte[] data = bao.toByteArray(); |
||||||
|
return new ByteArrayInputStream(data); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} finally { |
||||||
|
if (response != null) { |
||||||
|
response.close(); |
||||||
|
} |
||||||
|
if (in != null) { |
||||||
|
in.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* 流响应解析器 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @date 2019-07-14 |
||||||
|
*/ |
||||||
|
public class StreamResponseHandle extends BaseHttpResponseHandle<ByteArrayInputStream> { |
||||||
|
|
||||||
|
public static final StreamResponseHandle DEFAULT = new StreamResponseHandle(); |
||||||
|
private static final int BUFFER_LENGTH = 8000; |
||||||
|
|
||||||
|
public StreamResponseHandle() { |
||||||
|
} |
||||||
|
|
||||||
|
public StreamResponseHandle(String encoding) { |
||||||
|
super(encoding); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ByteArrayInputStream parse(CloseableHttpResponse response) throws IOException { |
||||||
|
InputStream in = null; |
||||||
|
try { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
if (entity != null) { |
||||||
|
in = entity.getContent(); |
||||||
|
byte[] buff = new byte[BUFFER_LENGTH]; |
||||||
|
int bytesRead; |
||||||
|
ByteArrayOutputStream bao = new ByteArrayOutputStream(); |
||||||
|
while ((bytesRead = in.read(buff)) != -1) { |
||||||
|
bao.write(buff, 0, bytesRead); |
||||||
|
} |
||||||
|
byte[] data = bao.toByteArray(); |
||||||
|
return new ByteArrayInputStream(data); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} finally { |
||||||
|
if (response != null) { |
||||||
|
response.close(); |
||||||
|
} |
||||||
|
if (in != null) { |
||||||
|
in.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
import com.fr.third.org.apache.http.util.EntityUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 文本响应解析器 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @date 2019-07-14 |
||||||
|
*/ |
||||||
|
public class TextResponseHandle extends BaseHttpResponseHandle<String> { |
||||||
|
|
||||||
|
public static final TextResponseHandle DEFAULT = new TextResponseHandle(); |
||||||
|
|
||||||
|
public TextResponseHandle() { |
||||||
|
} |
||||||
|
|
||||||
|
public TextResponseHandle(String encoding) { |
||||||
|
super(encoding); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String parse(CloseableHttpResponse response) throws IOException { |
||||||
|
try { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
String result = EntityUtils.toString(entity, getEncoding()); |
||||||
|
EntityUtils.consume(entity); |
||||||
|
return result; |
||||||
|
} finally { |
||||||
|
if (response != null) { |
||||||
|
response.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fanruan.api.net.http.rs; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.http.HttpEntity; |
||||||
|
import com.fr.third.org.apache.http.HttpStatus; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
import com.fr.third.org.apache.http.util.EntityUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传响应解析器 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @date 2019-07-14 |
||||||
|
*/ |
||||||
|
public class UploadResponseHandle extends BaseHttpResponseHandle<Void> { |
||||||
|
|
||||||
|
public static final UploadResponseHandle DEFAULT = new UploadResponseHandle(); |
||||||
|
|
||||||
|
public UploadResponseHandle() { |
||||||
|
} |
||||||
|
|
||||||
|
public UploadResponseHandle(String encoding) { |
||||||
|
super(encoding); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Void parse(CloseableHttpResponse response) throws IOException { |
||||||
|
try { |
||||||
|
int statusCode = response.getStatusLine().getStatusCode(); |
||||||
|
if (statusCode == HttpStatus.SC_OK) { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
if (entity != null) { |
||||||
|
EntityUtils.consume(entity); |
||||||
|
} |
||||||
|
} else { |
||||||
|
HttpEntity entity = response.getEntity(); |
||||||
|
String result = EntityUtils.toString(entity, getEncoding()); |
||||||
|
throw new IOException("Connect error, error code:" + statusCode + "; message:" + result); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
if (response != null) { |
||||||
|
response.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fanruan.api.script; |
||||||
|
import com.fr.script.ScriptFactory; |
||||||
|
|
||||||
|
import javax.script.ScriptEngine; |
||||||
|
|
||||||
|
public class ScriptKit { |
||||||
|
/** |
||||||
|
* 获取一个全新的脚本执行引擎 |
||||||
|
* @return 一个全新的脚本执行引擎 |
||||||
|
*/ |
||||||
|
public static ScriptEngine newScriptEngine() { |
||||||
|
return ScriptFactory.newScriptEngine(); |
||||||
|
} |
||||||
|
} |
@ -1,16 +0,0 @@ |
|||||||
package com.fanruan.api.util; |
|
||||||
|
|
||||||
import com.fr.stable.StableUtils; |
|
||||||
|
|
||||||
public class ReflectKit { |
|
||||||
|
|
||||||
/** |
|
||||||
* 判断一个类是否是另一个类的子类 |
|
||||||
* @param current 当前类 |
|
||||||
* @param target 目标类 |
|
||||||
* @return 如果当前类是目标类的子类,则返回true,否则返回false |
|
||||||
*/ |
|
||||||
public static boolean classInstanceOf(Class current, Class target) { |
|
||||||
return StableUtils.classInstanceOf(current, target); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,32 @@ |
|||||||
|
package com.fanruan.api.util; |
||||||
|
|
||||||
|
public class TypeKit { |
||||||
|
|
||||||
|
/** |
||||||
|
* 判读指定的类是否是另一个类的子类 |
||||||
|
* |
||||||
|
* @param current 指定的类 |
||||||
|
* @param targetClass 另一个类 |
||||||
|
* @return 如果当前类是目标类的子类则返回true,否则返回false |
||||||
|
*/ |
||||||
|
public static boolean classInstanceOf(Class<?> current, Class<?> targetClass) { |
||||||
|
if (current == null || targetClass == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return targetClass.isAssignableFrom(current); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判读指定的类是否是另一个类的子类 |
||||||
|
* |
||||||
|
* @param object 指定的类 |
||||||
|
* @param clazz 另一个类 |
||||||
|
* @return 如果指定类是另一个类的子类则返回true,否则返回false |
||||||
|
*/ |
||||||
|
public static boolean objectInstanceOf(Object object, Class clazz) { |
||||||
|
if (object == null || clazz == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return clazz.isInstance(object); |
||||||
|
} |
||||||
|
} |
@ -1,20 +1,49 @@ |
|||||||
package com.fanruan.api.xml; |
package com.fanruan.api.xml; |
||||||
|
|
||||||
|
import com.fr.general.xml.GeneralXMLTools; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
import com.fr.stable.xml.XMLReadable; |
import com.fr.stable.xml.XMLReadable; |
||||||
import com.fr.stable.xml.XMLTools; |
import com.fr.stable.xml.XMLTools; |
||||||
|
import com.fr.stable.xml.XMLable; |
||||||
import com.fr.stable.xml.XMLableReader; |
import com.fr.stable.xml.XMLableReader; |
||||||
import com.fr.stable.xml.XMLPrintWriter; |
|
||||||
|
|
||||||
import java.io.InputStream; |
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* xml读写相关类 |
||||||
|
*/ |
||||||
public class XmlKit { |
public class XmlKit { |
||||||
/** |
/** |
||||||
* 从输入流中读取对象 |
* 从输入流中读取对象 |
||||||
* @param xmlReadable xml读取对象 |
|
||||||
* @param inputStream xml输入流 |
|
||||||
* |
* |
||||||
|
* @param read xml读取对象 |
||||||
|
* @param in xml输入流 |
||||||
|
*/ |
||||||
|
public static void readInputStreamXML(XMLReadable read, InputStream in) throws Exception { |
||||||
|
XMLTools.readInputStreamXML(read, in); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 将xml读取为具体的java对象 |
||||||
|
* |
||||||
|
* @param reader xml读取器 |
||||||
|
* @return java对象 |
||||||
|
*/ |
||||||
|
public static XMLable readXMLable(XMLableReader reader) { |
||||||
|
return GeneralXMLTools.readXMLable(reader); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 将java对象写为xml文件 |
||||||
|
* |
||||||
|
* @param writer xml写入器 |
||||||
|
* @param xml 实际java对象 |
||||||
|
* @param tagName xml标签名 |
||||||
*/ |
*/ |
||||||
public static void readInputStreamXML(XMLReadable xmlReadable, InputStream inputStream) throws Exception { |
public static void writeXMLable(XMLPrintWriter writer, XMLable xml, String tagName) { |
||||||
XMLTools.readInputStreamXML(xmlReadable, inputStream); |
GeneralXMLTools.writeXMLable(writer, xml, tagName); |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
} |
} |
||||||
|
@ -0,0 +1,24 @@ |
|||||||
|
package com.fanruan.api.cal; |
||||||
|
|
||||||
|
import com.fr.stable.ArrayProvider; |
||||||
|
import com.fr.third.guava.collect.Lists; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
*/ |
||||||
|
public class ContainerKitTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void newArray() { |
||||||
|
|
||||||
|
ArrayProvider<String> array = ContainerKit.newArray(new String[]{"abc", "xyz"}); |
||||||
|
Assert.assertEquals("xyz", array.elementAt(1)); |
||||||
|
|
||||||
|
ArrayProvider<String> array2 = ContainerKit.newArray(Lists.newArrayList("abc", "xyz")); |
||||||
|
Assert.assertEquals("abc", array2.elementAt(0)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,153 @@ |
|||||||
|
package com.fanruan.api.net.http; |
||||||
|
|
||||||
|
import com.fanruan.api.Prepare; |
||||||
|
import com.fanruan.api.net.http.rs.HttpRequest; |
||||||
|
import com.fanruan.api.net.http.rs.HttpResponseType; |
||||||
|
import com.fanruan.api.net.http.rs.StreamResponseHandle; |
||||||
|
import com.fanruan.api.util.IOKit; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import okhttp3.HttpUrl; |
||||||
|
import okhttp3.mockwebserver.MockResponse; |
||||||
|
import okhttp3.mockwebserver.MockWebServer; |
||||||
|
import okhttp3.mockwebserver.RecordedRequest; |
||||||
|
import org.junit.AfterClass; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.net.SocketTimeoutException; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNotNull; |
||||||
|
import static org.junit.Assert.fail; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-08-29 |
||||||
|
*/ |
||||||
|
public class HttpKitTest extends Prepare { |
||||||
|
|
||||||
|
private static MockWebServer server = new MockWebServer(); |
||||||
|
|
||||||
|
@AfterClass |
||||||
|
public static void tearDown() throws Exception { |
||||||
|
server.shutdown(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGet() { |
||||||
|
String text = null; |
||||||
|
try { |
||||||
|
text = HttpKit.get("http://www.baidu.com"); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
assertNotNull(text); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPost() { |
||||||
|
Map<String, String> map = new HashMap<String, String>(); |
||||||
|
map.put("key", "bbs"); |
||||||
|
try { |
||||||
|
String resText = HttpKit.post("https://cloud.fanruan.com/site", map); |
||||||
|
assertEquals("http://bbs.fanruan.com/", new JSONObject(resText).get("value")); |
||||||
|
} catch (SocketTimeoutException ignore) { |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
fail(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testStream() { |
||||||
|
Map<String, Object> map = new HashMap<String, Object>(); |
||||||
|
map.put("key", "bbs"); |
||||||
|
try { |
||||||
|
InputStream in = HttpKit.post("https://cloud.fanruan.com/site", map, HttpResponseType.STREAM); |
||||||
|
String text = IOKit.inputStream2String(in, StandardCharsets.UTF_8); |
||||||
|
assertEquals("{\"value\":\"http://bbs.fanruan.com/\"}", text); |
||||||
|
} catch (SocketTimeoutException ignore) { |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
fail(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testStreamMock() { |
||||||
|
server.enqueue(new MockResponse().setBody("{\"value\":\"http://bbs.fanruan.com/\"}")); |
||||||
|
String url = server.url("/site").toString(); |
||||||
|
Map<String, String> map = new HashMap<String, String>(); |
||||||
|
map.put("key", "bbs"); |
||||||
|
try { |
||||||
|
InputStream in = HttpKit.executeAndParse(HttpRequest |
||||||
|
.custom() |
||||||
|
.url(url) |
||||||
|
.post(map) |
||||||
|
.build(), |
||||||
|
new StreamResponseHandle()); |
||||||
|
String text = IOKit.inputStream2String(in, StandardCharsets.UTF_8); |
||||||
|
RecordedRequest takeRequest = server.takeRequest(); |
||||||
|
assertEquals("{\"value\":\"http://bbs.fanruan.com/\"}", text); |
||||||
|
assertEquals("POST", takeRequest.getMethod()); |
||||||
|
assertEquals("key=bbs", takeRequest.getBody().readUtf8()); |
||||||
|
} catch (SocketTimeoutException ignore) { |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
fail(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testMethod() throws Exception { |
||||||
|
server.enqueue(new MockResponse().setBody("get")); |
||||||
|
server.enqueue(new MockResponse().setBody("post")); |
||||||
|
server.enqueue(new MockResponse().setBody("put")); |
||||||
|
server.enqueue(new MockResponse().setBody("delete")); |
||||||
|
String url = server.url("/v1/chat/").toString(); |
||||||
|
HttpKit.get(url); |
||||||
|
assertEquals(server.takeRequest().getMethod(), "GET"); |
||||||
|
HttpKit.post(url, Collections.<String, String>emptyMap()); |
||||||
|
assertEquals(server.takeRequest().getMethod(), "POST"); |
||||||
|
HttpKit.executeAndParse(HttpRequest.custom().url(url).put(Collections.<String, String>emptyMap()).build()); |
||||||
|
assertEquals(server.takeRequest().getMethod(), "PUT"); |
||||||
|
HttpKit.executeAndParse(HttpRequest.custom().url(url).delete().build()); |
||||||
|
assertEquals(server.takeRequest().getMethod(), "DELETE"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testHeader() throws Exception { |
||||||
|
server.enqueue(new MockResponse().setBody("hello, world!")); |
||||||
|
HttpUrl baseUrl = server.url("/v1/chat/"); |
||||||
|
|
||||||
|
HashMap<String, String> headers = new HashMap<String, String>(1); |
||||||
|
headers.put("Authorization", "abc"); |
||||||
|
String s = HttpKit.executeAndParse(HttpRequest.custom().url(baseUrl.toString()).post(Collections.<String, String>emptyMap()).headers(headers).build()); |
||||||
|
assertEquals("hello, world!", s); |
||||||
|
// 测试请求头
|
||||||
|
RecordedRequest request = server.takeRequest(); |
||||||
|
assertEquals(request.getHeader("Authorization"), "abc"); |
||||||
|
assertEquals("POST /v1/chat/ HTTP/1.1", request.getRequestLine()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testParams() throws Exception { |
||||||
|
server.enqueue(new MockResponse().setBody("hello, world!")); |
||||||
|
HttpUrl baseUrl = server.url("/v1/chat/"); |
||||||
|
|
||||||
|
HashMap<String, String> params = new HashMap<String, String>(1); |
||||||
|
params.put("key", "value"); |
||||||
|
String s = HttpKit.executeAndParse(HttpRequest.custom().url(baseUrl.toString()).post(params).build()); |
||||||
|
assertEquals("hello, world!", s); |
||||||
|
// 测试参数
|
||||||
|
RecordedRequest request = server.takeRequest(); |
||||||
|
assertEquals("key=value", request.getBody().readUtf8()); |
||||||
|
assertEquals("POST /v1/chat/ HTTP/1.1", request.getRequestLine()); |
||||||
|
} |
||||||
|
} |
@ -1,14 +0,0 @@ |
|||||||
package com.fanruan.api.util; |
|
||||||
|
|
||||||
import org.junit.Test; |
|
||||||
|
|
||||||
import static org.junit.Assert.*; |
|
||||||
|
|
||||||
public class ReflectKitTest { |
|
||||||
|
|
||||||
@Test |
|
||||||
public void classInstanceOf() { |
|
||||||
assertEquals(ReflectKit.classInstanceOf(Integer.class,Object.class),true); |
|
||||||
assertEquals(ReflectKit.classInstanceOf(Object.class,Integer.class),false); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,19 @@ |
|||||||
|
package com.fanruan.api.util; |
||||||
|
|
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
public class TypeKitTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void classInstanceOf() { |
||||||
|
Assert.assertTrue(TypeKit.classInstanceOf(Integer.class, Object.class)); |
||||||
|
Assert.assertFalse(TypeKit.classInstanceOf(Object.class, Integer.class)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void objectInstanceOf() { |
||||||
|
Assert.assertTrue(TypeKit.objectInstanceOf(1, Integer.class)); |
||||||
|
Assert.assertFalse(TypeKit.objectInstanceOf(1.0, Integer.class)); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue