帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

390 lines
13 KiB

package com.fr.design.extra;
import com.fr.base.FRContext;
import com.fr.design.RestartHelper;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.*;
import com.fr.general.FRLogger;
import com.fr.general.Inter;
import com.fr.general.SiteCenter;
import com.fr.plugin.Plugin;
import com.fr.plugin.PluginLicense;
import com.fr.plugin.PluginLicenseManager;
import com.fr.plugin.PluginLoader;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/**
* 开放给Web组件的接口,用于安装,卸载,更新以及更改插件可用状态
*/
public class PluginWebBridge {
private static PluginWebBridge helper;
private UIDialog uiDialog;
public static final String PLUGIN_SHOP = SiteCenter.getInstance().acquireUrlByKind("plugin.plist");
public static PluginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (PluginWebBridge.class) {
if (helper == null) {
helper = new PluginWebBridge();
}
return helper;
}
}
public static PluginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setEngine(webEngine);
return helper;
}
private WebEngine webEngine;
private PluginWebBridge() {
}
public void setEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public void setDialogHandle(UIDialog uiDialog) {
this.uiDialog = uiDialog;
}
/**
* 从插件服务器上安装插件
*
* @param pluginID 插件的ID
* @param callback 回调函数
*/
public void installPluginOnline(final String pluginID, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new InstallOnlineExecutor(pluginID));
new Thread(task).start();
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
public void installPluginFromDisk(final String filePath, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new InstallFromDiskExecutor(filePath));
new Thread(task).start();
}
/**
* 卸载当前选中的插件
*
* @param pluginIDs 插件集合
*/
public void uninstallPlugin(JSObject pluginIDs, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new UninstallExecutor(jsObjectToStringArray(pluginIDs)));
new Thread(task).start();
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
public void updatePluginOnline(JSObject pluginIDs, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new UpdateOnlineExecutor(jsObjectToStringArray(pluginIDs)));
new Thread(task).start();
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new UpdateFromDiskExecutor(filePath));
new Thread(task).start();
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
public void setPluginActive(String pluginID, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new ModifyStatusExecutor(pluginID));
new Thread(task).start();
}
/**
* 已安装插件检查更新
*/
public void readUpdateOnline(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new ReadUpdateOnlineExecutor());
new Thread(task).start();
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
public String showFileChooserWithFilter(String des, String filter) {
FileChooser fileChooser = new FileChooser();
if (StringUtils.isNotEmpty(filter)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filter));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
public String showFileChooserWithFilters(String des, JSObject args) {
FileChooser fileChooser = new FileChooser();
String[] filters = jsObjectToStringArray(args);
if (ArrayUtils.isNotEmpty(filters)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filters));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 获取已经安装的插件的数组
*
* @return 已安装的插件组成的数组
*/
public Plugin[] getInstalledPlugins() {
return PluginLoader.getLoader().getInstalled();
}
/**
* 获取已经安装的插件的授权情况
*
* @return 已安装的插件授权对象
*/
public PluginLicense getPluginLicenseByID(String pluginID ) {
return PluginLicenseManager.getInstance().getPluginLicenseByID(pluginID);
}
private String[] jsObjectToStringArray(JSObject obj) {
if (obj == null) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
int len = (int) obj.getMember("length");
List<String> list = new ArrayList<>();
for (int i = 0; i < len; i++) {
list.add(obj.getSlot(i).toString());
}
return list.toArray(new String[len]);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
public void searchPlugin(String keyword, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new SearchOnlineExecutor(keyword));
new Thread(task).start();
}
/**
* 根据条件获取在线插件的
*
* @param category 分类
* @param seller 卖家性质
* @param fee 收费类型
* @param callback 回调函数
*/
public void getPluginFromStore(String category, String seller, String fee, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(category, seller, fee));
new Thread(task).start();
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
public void getPluginCategories(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginCategoriesExecutor());
new Thread(task).start();
}
/**
* 展示一个重启的对话框(少用,莫名其妙会有bug)
*
* @param message 展示的消息
*/
public void showRestartMessage(String message) {
int rv = JOptionPane.showOptionDialog(
null,
message,
Inter.getLocText("FR-Designer-Plugin_Warning"),
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{Inter.getLocText("FR-Designer-Basic_Restart_Designer"), Inter.getLocText("FR-Designer-Basic_Restart_Designer_Later")},
null
);
if (rv == JOptionPane.OK_OPTION) {
RestartHelper.restart();
}
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
}
/**
* 窗口是否无装饰(判断是否使用系统标题栏)
*/
public boolean isCustomTitleBar() {
if (uiDialog != null) {
return uiDialog.isUndecorated();
}
return false;
}
/**
* 在本地浏览器里打开url
* tips:重载的时候,需要给js调用的方法需要放在前面,否则可能不会被调用(此乃坑)
* 所以最好的是不要重载在js可以访问的接口文件中
*
* @param url 要打开的地址
*/
public void openShopUrlAtWebBrowser(String url) {
openUrlAtLocalWebBrowser(webEngine, url);
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (NullPointerException e) {
//此为uri为空时抛出异常
FRLogger.getLogger().error(e.getMessage());
} catch (IOException e) {
//此为无法获取系统默认浏览器
FRLogger.getLogger().error(e.getMessage());
}
}
}
/**
* 从硬盘升级
*
* @param fileOnDisk 硬盘上的文件
*/
public void updateFileFromDisk(File fileOnDisk) {
try {
Plugin plugin = PluginHelper.readPlugin(fileOnDisk);
if (plugin == null) {
JOptionPane.showMessageDialog(null, Inter.getLocText("FR-Designer-Plugin_Illegal_Plugin_Zip"), Inter.getLocText("FR-Designer-Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
return;
}
Plugin oldPlugin = PluginLoader.getLoader().getPluginById(plugin.getId());
if (oldPlugin != null) {
// 说明安装了同ID的插件,再比较两个插件的版本
if (PluginHelper.isNewThan(plugin, oldPlugin)) {
// 说明是新的插件,删除老的然后安装新的
final String[] files = PluginHelper.uninstallPlugin(FRContext.getCurrentEnv(), oldPlugin);
PluginHelper.installPluginFromUnzippedTempDir(FRContext.getCurrentEnv(), plugin, new After() {
@Override
public void done() {
int rv = JOptionPane.showOptionDialog(
null,
Inter.getLocText("FR-Designer-Plugin_Update_Successful"),
Inter.getLocText("FR-Designer-Plugin_Warning"),
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{Inter.getLocText("FR-Designer-Basic_Restart_Designer"),
Inter.getLocText("FR-Designer-Basic_Restart_Designer_Later")
},
null
);
if (rv == JOptionPane.OK_OPTION) {
RestartHelper.restart();
}
// 如果不是立即重启,就把要删除的文件存放起来
if (rv == JOptionPane.CANCEL_OPTION || rv == JOptionPane.CLOSED_OPTION) {
RestartHelper.saveFilesWhichToDelete(files);
}
}
});
} else {
JOptionPane.showMessageDialog(null, Inter.getLocText("FR-Designer-Plugin_Version_Is_Lower_Than_Current"), Inter.getLocText("FR-Designer-Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(null, Inter.getLocText("FR-Designer-Plugin_Cannot_Update_Not_Install"), Inter.getLocText("FR-Designer-Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
}
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), Inter.getLocText("FR-Designer-Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
}
}
}