Skip to content

Commit cfad017

Browse files
committed
WIP: 允许加载本地打包插件
1 parent c3aad63 commit cfad017

11 files changed

Lines changed: 174 additions & 70 deletions

File tree

src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import com.xwintop.xJavaFxTool.event.AppEvents;
55
import com.xwintop.xJavaFxTool.event.PluginEvent;
66
import com.xwintop.xJavaFxTool.model.PluginJarInfo;
7+
import com.xwintop.xJavaFxTool.plugin.AddPluginResult;
78
import com.xwintop.xJavaFxTool.plugin.PluginClassLoader;
89
import com.xwintop.xJavaFxTool.plugin.PluginManager;
910
import com.xwintop.xJavaFxTool.plugin.PluginParser;
1011
import com.xwintop.xJavaFxTool.services.index.PluginManageService;
1112
import com.xwintop.xJavaFxTool.view.index.PluginManageView;
13+
import com.xwintop.xcore.util.javafx.FileChooserUtil;
1214
import com.xwintop.xcore.util.javafx.JavaFxViewUtil;
1315
import com.xwintop.xcore.util.javafx.TooltipUtil;
1416
import java.io.File;
@@ -20,26 +22,25 @@
2022
import javafx.collections.FXCollections;
2123
import javafx.collections.ObservableList;
2224
import javafx.collections.transformation.FilteredList;
23-
import javafx.event.ActionEvent;
24-
import javafx.fxml.FXML;
2525
import javafx.fxml.FXMLLoader;
2626
import javafx.scene.control.Button;
2727
import javafx.scene.control.ContentDisplay;
2828
import javafx.scene.control.ContextMenu;
2929
import javafx.scene.control.MenuItem;
3030
import javafx.scene.control.TableCell;
3131
import javafx.scene.control.TableColumn;
32+
import javafx.stage.FileChooser.ExtensionFilter;
3233
import javafx.stage.Window;
3334
import javafx.util.Callback;
3435
import lombok.Getter;
3536
import lombok.Setter;
3637
import lombok.extern.slf4j.Slf4j;
3738

3839
/**
39-
* @ClassName: PluginManageController
40-
* @Description: 插件管理
41-
* @author: xufeng
42-
* @date: 2020/1/19 17:41
40+
* 插件管理
41+
*
42+
* @author xufeng
43+
* @since 2020/1/19 17:41
4344
*/
4445

4546
@Getter
@@ -75,6 +76,8 @@ public void setOnPluginDownloaded(Consumer<File> onPluginDownloaded) {
7576
}
7677

7778
private void initView() {
79+
addLocalPluginButton.setVisible(Boolean.parseBoolean(System.getProperty("localPluginEnabled", "false")));
80+
7881
JavaFxViewUtil.setTableColumnMapValueFactory(nameTableColumn, "nameTableColumn");
7982
JavaFxViewUtil.setTableColumnMapValueFactory(synopsisTableColumn, "synopsisTableColumn");
8083
JavaFxViewUtil.setTableColumnMapValueFactory(versionTableColumn, "versionTableColumn");
@@ -169,8 +172,18 @@ private void initService() {
169172
pluginManageService.getPluginList();
170173
}
171174

172-
@FXML
173-
private void selectPluginAction(ActionEvent event) {
175+
public void searchPlugin() {
174176
pluginManageService.searchPlugin(selectPluginTextField.getText());
175177
}
178+
179+
public void addLocalPlugin() {
180+
File jarFile = FileChooserUtil.chooseFile(new ExtensionFilter("打包插件(*.jar)", "*.jar"));
181+
if (jarFile != null) {
182+
AddPluginResult result = PluginManager.getInstance().addPluginJar(jarFile);
183+
if (result.isNewPlugin()) {
184+
pluginManageService.addDataRow(result.getPluginJarInfo());
185+
}
186+
AppEvents.fire(new PluginEvent(PluginEvent.PLUGIN_DOWNLOADED, result.getPluginJarInfo()));
187+
}
188+
}
176189
}

src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.alibaba.fastjson.annotation.JSONField;
44
import java.io.File;
55
import lombok.Data;
6+
import lombok.NoArgsConstructor;
67

78
/**
89
* 插件信息
@@ -11,6 +12,7 @@
1112
*/
1213

1314
@Data
15+
@NoArgsConstructor
1416
public class PluginJarInfo {
1517

1618
///////////////////////////////////////// 下面的属性在远程插件列表和本地配置中都存在
@@ -37,6 +39,8 @@ public class PluginJarInfo {
3739

3840
private Integer localVersionNumber; // 插件本地版本
3941

42+
private String localPath; // 插件本地文件路径(如果是本地插件)
43+
4044
///////////////////////////////////////// 下面的属性来自插件描述文件 toolFxmlLoaderConfiguration.xml
4145

4246
private String fxmlPath; // FXML 资源路径
@@ -69,7 +73,7 @@ public boolean getIsFavorite() {
6973

7074
@JSONField(serialize = false)
7175
public File getFile() {
72-
return new File("libs/", getJarName() + "-" + getVersion() + ".jar");
76+
return localPath == null? new File("libs/", getJarName() + "-" + getVersion() + ".jar"): new File(localPath);
7377
}
7478

7579
@JSONField(serialize = false)

src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherController.java

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.xwintop.xJavaFxTool.newui;
22

3+
import static com.xwintop.xJavaFxTool.utils.BoolUtils.isNot;
4+
35
import com.xwintop.xJavaFxTool.Main;
46
import com.xwintop.xJavaFxTool.controller.IndexController;
57
import com.xwintop.xJavaFxTool.controller.index.PluginManageController;
@@ -120,28 +122,41 @@ private void loadPlugins() {
120122
* @param jarInfo 插件信息
121123
*/
122124
private void loadPlugin(PluginJarInfo jarInfo) {
123-
String menuParentTitle = jarInfo.getMenuParentTitle();
124-
if (menuParentTitle != null) {
125125

126-
String categoryName = jarInfo.getIsFavorite() ?
127-
FAVORITE_CATEGORY_NAME : Main.RESOURCE_BUNDLE.getString(menuParentTitle);
126+
if (!jarInfo.getFile().exists()) {
127+
log.info("跳过插件 {}: 文件不存在", jarInfo.getName());
128+
return;
129+
}
128130

129-
PluginCategoryController category = categoryControllers.computeIfAbsent(
130-
categoryName, __ -> {
131-
PluginCategoryController _category =
132-
PluginCategoryController.newInstance(categoryName);
133-
addCategory(_category);
134-
return _category;
135-
}
136-
);
131+
if (isNot(jarInfo.getIsEnable())) {
132+
log.info("跳过插件 {}: 插件未启用", jarInfo.getName());
133+
return;
134+
}
137135

138-
PluginItemController item = PluginItemController.newInstance(jarInfo);
139-
item.setContextMenu(itemContextMenu);
140-
category.addItem(item);
136+
String menuParentTitle = jarInfo.getMenuParentTitle();
137+
if (menuParentTitle == null) {
138+
log.info("跳过插件 {}: menuParentTitle 为空", jarInfo.getName());
139+
return;
140+
}
141141

142-
if (!pluginItemControllers.contains(item)) {
143-
pluginItemControllers.add(item);
142+
String categoryName = jarInfo.getIsFavorite() ?
143+
FAVORITE_CATEGORY_NAME : Main.RESOURCE_BUNDLE.getString(menuParentTitle);
144+
145+
PluginCategoryController category = categoryControllers.computeIfAbsent(
146+
categoryName, __ -> {
147+
PluginCategoryController _category =
148+
PluginCategoryController.newInstance(categoryName);
149+
addCategory(_category);
150+
return _category;
144151
}
152+
);
153+
154+
PluginItemController item = PluginItemController.newInstance(jarInfo);
155+
item.setContextMenu(itemContextMenu);
156+
category.addItem(item);
157+
158+
if (!pluginItemControllers.contains(item)) {
159+
pluginItemControllers.add(item);
145160
}
146161
}
147162

src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import java.util.Map.Entry;
88
import javafx.scene.control.Tab;
99
import javafx.scene.control.TabPane;
10+
import lombok.extern.slf4j.Slf4j;
1011

1112
/**
1213
* 新界面中负责与插件操作相关的逻辑
1314
*/
15+
@Slf4j
1416
public class NewLauncherService {
1517

1618
private static final NewLauncherService instance = new NewLauncherService();
@@ -42,6 +44,8 @@ public PluginItemController getCurrentPluginItem() {
4244
}
4345

4446
public void loadPlugin(PluginJarInfo pluginJarInfo) {
47+
log.info("加载插件 {}: {}", pluginJarInfo.getName(), pluginJarInfo.getFile().getAbsolutePath());
48+
4549
TabPane tabPane = this.newLauncherController.getTabPane();
4650

4751
for (Entry<Tab, PluginJarInfo> entry : jarInfoMap.entrySet()) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.xwintop.xJavaFxTool.plugin;
2+
3+
import com.xwintop.xJavaFxTool.model.PluginJarInfo;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
7+
@Data
8+
@AllArgsConstructor
9+
public class AddPluginResult {
10+
11+
private PluginJarInfo pluginJarInfo;
12+
13+
private boolean newPlugin;
14+
}

src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,34 @@ public void loadLocalPlugins() {
127127
});
128128
}
129129

130+
/**
131+
* 添加本地插件。如果与已有插件同名,则替换已有插件信息
132+
* @param jarFile 插件文件
133+
*/
134+
public AddPluginResult addPluginJar(File jarFile) {
135+
PluginClassLoader tmpClassLoader = new PluginClassLoader(jarFile);
136+
PluginJarInfo newJarInfo = new PluginJarInfo();
137+
newJarInfo.setLocalPath(jarFile.getAbsolutePath());
138+
newJarInfo.setIsEnable(true);
139+
newJarInfo.setIsDownload(true);
140+
PluginParser.parse(jarFile, newJarInfo, tmpClassLoader);
141+
142+
for (int i = 0; i < pluginList.size(); i++) {
143+
PluginJarInfo jarInfo = pluginList.get(i);
144+
if (Objects.equals(jarInfo.getFxmlPath(), newJarInfo.getFxmlPath())) {
145+
newJarInfo.setVersion(jarInfo.getVersion());
146+
newJarInfo.setSynopsis(jarInfo.getSynopsis());
147+
pluginList.set(i, newJarInfo);
148+
saveToFileQuietly();
149+
return new AddPluginResult(newJarInfo, false);
150+
}
151+
}
152+
153+
pluginList.add(newJarInfo);
154+
saveToFileQuietly();
155+
return new AddPluginResult(newJarInfo, true);
156+
}
157+
130158
public void loadServerPlugins() {
131159
try {
132160
String json = HttpUtil.get(SERVER_PLUGINS_URL);

src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import java.util.jar.JarEntry;
1616
import java.util.jar.JarFile;
1717
import java.util.stream.Collectors;
18+
import lombok.extern.slf4j.Slf4j;
19+
import org.apache.commons.lang3.StringUtils;
1820
import org.dom4j.Document;
1921
import org.dom4j.DocumentException;
2022
import org.dom4j.Element;
@@ -23,6 +25,7 @@
2325
/**
2426
* 用来解析插件文件中的 toolFxmlLoaderConfiguration.xml
2527
*/
28+
@Slf4j
2629
public class PluginParser {
2730

2831
public static final String ENTRY_NAME = "config/toolFxmlLoaderConfiguration.xml";
@@ -31,13 +34,19 @@ public class PluginParser {
3134
* 解析插件文件,补完 pluginJarInfo 属性
3235
*/
3336
public static void parse(File pluginFile, PluginJarInfo pluginJarInfo) {
34-
parse(pluginFile, pluginJarInfo, ClassLoader.getSystemClassLoader());
37+
parse(pluginFile, pluginJarInfo, null);
3538
}
3639

3740
/**
3841
* 解析插件文件,补完 pluginJarInfo 属性
3942
*/
4043
public static void parse(File pluginFile, PluginJarInfo pluginJarInfo, ClassLoader classLoader) {
44+
45+
if (!pluginFile.exists()) {
46+
log.error("插件 {} 文件不存在: {}", pluginJarInfo.getName(), pluginFile.getAbsolutePath());
47+
return;
48+
}
49+
4150
try (JarFile jarFile = new JarFile(pluginFile)) {
4251

4352
JarEntry entry = jarFile.getJarEntry(ENTRY_NAME);
@@ -55,8 +64,9 @@ public static void parse(File pluginFile, PluginJarInfo pluginJarInfo, ClassLoad
5564
}
5665

5766
String resourceBundleName = getChildNodeText(pluginElement, "resourceBundleName");
67+
ClassLoader tmpClassLoader = classLoader == null ? new PluginClassLoader(pluginFile) : classLoader;
5868
ResourceBundle pluginResourceBundle =
59-
ResourceBundle.getBundle(resourceBundleName, Config.defaultLocale, classLoader);
69+
ResourceBundle.getBundle(resourceBundleName, Config.defaultLocale, tmpClassLoader);
6070

6171
String menuId = getChildNodeText(pluginElement, "menuParentId");
6272
String url = getChildNodeText(pluginElement, "url");
@@ -71,6 +81,9 @@ public static void parse(File pluginFile, PluginJarInfo pluginJarInfo, ClassLoad
7181
pluginJarInfo.setFxmlPath(url);
7282
pluginJarInfo.setControllerType(controllerType);
7383
pluginJarInfo.setTitle(title);
84+
85+
pluginJarInfo.setName(StringUtils.defaultString(pluginJarInfo.getName(), title));
86+
7487
} catch (IOException | DocumentException e) {
7588
throw new AppException(e);
7689
}

src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package com.xwintop.xJavaFxTool.services.index;
22

3+
import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
4+
35
import com.xwintop.xJavaFxTool.AppException;
46
import com.xwintop.xJavaFxTool.controller.index.PluginManageController;
57
import com.xwintop.xJavaFxTool.model.PluginJarInfo;
68
import com.xwintop.xJavaFxTool.plugin.PluginManager;
79
import com.xwintop.xcore.javafx.dialog.FxProgressDialog;
810
import com.xwintop.xcore.javafx.dialog.ProgressTask;
9-
import lombok.Getter;
10-
import lombok.Setter;
11-
import lombok.extern.slf4j.Slf4j;
12-
import org.apache.commons.lang3.StringUtils;
13-
1411
import java.io.File;
1512
import java.util.HashMap;
1613
import java.util.Map;
1714
import java.util.function.Consumer;
18-
19-
import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
15+
import lombok.Getter;
16+
import lombok.Setter;
17+
import lombok.extern.slf4j.Slf4j;
18+
import org.apache.commons.lang3.StringUtils;
2019

2120
/**
2221
* 插件管理
@@ -47,7 +46,7 @@ public void getPluginList() {
4746
pluginManager.getPluginList().forEach(this::addDataRow);
4847
}
4948

50-
private void addDataRow(PluginJarInfo plugin) {
49+
public void addDataRow(PluginJarInfo plugin) {
5150

5251
Map<String, String> dataRow = new HashMap<>();
5352
dataRow.put("nameTableColumn", plugin.getName());
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.xwintop.xJavaFxTool.utils;
2+
3+
public class BoolUtils {
4+
5+
public static boolean is(Boolean b) {
6+
return b != null && b;
7+
}
8+
9+
public static boolean isNot(Boolean b) {
10+
return !is(b);
11+
}
12+
}

src/main/java/com/xwintop/xJavaFxTool/view/index/PluginManageView.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public abstract class PluginManageView implements Initializable {
2727
@FXML
2828
protected Button selectPluginButton;
2929

30+
@FXML
31+
protected Button addLocalPluginButton;
32+
3033
@FXML
3134
protected TableView<Map<String, String>> pluginDataTableView;
3235

0 commit comments

Comments
 (0)