🚩 完善 选择文件根路径的功能
This commit is contained in:
parent
778bb5bb62
commit
ad73d3a71c
@ -47,6 +47,6 @@ public class LunchApp extends Application {
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
APPLICATION_MANAGER.stopApp();
|
||||
APPLICATION_MANAGER.operationBeforeStopping();
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ import java.nio.file.Paths;
|
||||
*/
|
||||
public abstract class BaseConfigController<T> implements ConfigController<T> {
|
||||
|
||||
public static final String ROOT_CONFIG_DIR = "config";
|
||||
protected final String rootConfigDir = "config";
|
||||
|
||||
protected final String systemConfigDir = "system";
|
||||
|
||||
protected T config;
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.DEFAULT_PROPERTY;
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.PROGRAM_FILE_DIRECTORY;
|
||||
|
||||
/**
|
||||
* 应用程序配置文件
|
||||
@ -14,12 +21,51 @@ public class AppConfig {
|
||||
* 程序根路径
|
||||
*/
|
||||
private String rootPath;
|
||||
/**
|
||||
* 排除的文件夹
|
||||
*/
|
||||
@JsonIgnore
|
||||
private final Set<File> ignoreFolder;
|
||||
/**
|
||||
* 排除的文件
|
||||
*/
|
||||
@JsonIgnore
|
||||
private final Set<File> ignoreFile;
|
||||
/**
|
||||
* 上次的程序根路径
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String lastRootPath;
|
||||
|
||||
public AppConfig() {
|
||||
ignoreFolder = Set.of(
|
||||
new File(Paths.get(System.getProperty(DEFAULT_PROPERTY), PROGRAM_FILE_DIRECTORY, "system").toString()),
|
||||
new File(Paths.get(System.getProperty(DEFAULT_PROPERTY), PROGRAM_FILE_DIRECTORY, "logs").toString())
|
||||
);
|
||||
ignoreFile = Collections.emptySet();
|
||||
}
|
||||
|
||||
public String getRootPath() {
|
||||
return Optional.of(rootPath).orElse(System.getProperty(DEFAULT_PROPERTY));
|
||||
return Optional.ofNullable(rootPath).orElse(System.getProperty(DEFAULT_PROPERTY));
|
||||
}
|
||||
|
||||
public void setRootPath(String rootPath) {
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
public String getLastRootPath() {
|
||||
return lastRootPath;
|
||||
}
|
||||
|
||||
public void setLastRootPath(String lastRootPath) {
|
||||
this.lastRootPath = lastRootPath;
|
||||
}
|
||||
|
||||
public Set<File> getIgnoreFolder() {
|
||||
return ignoreFolder;
|
||||
}
|
||||
|
||||
public Set<File> getIgnoreFile() {
|
||||
return ignoreFile;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,24 +8,35 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.Window;
|
||||
import org.jcnc.jnotepad.LunchApp;
|
||||
import org.jcnc.jnotepad.app.config.AppConfig;
|
||||
import org.jcnc.jnotepad.app.i18n.UiResourceBundle;
|
||||
import org.jcnc.jnotepad.common.constants.AppConstants;
|
||||
import org.jcnc.jnotepad.common.constants.TextConstants;
|
||||
import org.jcnc.jnotepad.common.manager.ThreadPoolManager;
|
||||
import org.jcnc.jnotepad.controller.ResourceController;
|
||||
import org.jcnc.jnotepad.controller.cache.CacheController;
|
||||
import org.jcnc.jnotepad.controller.config.AppConfigController;
|
||||
import org.jcnc.jnotepad.controller.config.PluginConfigController;
|
||||
import org.jcnc.jnotepad.controller.exception.AppException;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
import org.jcnc.jnotepad.plugin.manager.PluginManager;
|
||||
import org.jcnc.jnotepad.util.FileUtil;
|
||||
import org.jcnc.jnotepad.util.LogUtil;
|
||||
import org.jcnc.jnotepad.util.UiUtil;
|
||||
import org.jcnc.jnotepad.views.manager.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.DEFAULT_PROPERTY;
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.PROGRAM_FILE_DIRECTORY;
|
||||
|
||||
|
||||
/**
|
||||
* 应用程序管理类<br/>
|
||||
@ -130,11 +141,42 @@ public class ApplicationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止程序
|
||||
* 迁移程序根文件夹
|
||||
*/
|
||||
public void migrateFileRootFolder() {
|
||||
AppConfig config = AppConfigController.getInstance().getConfig();
|
||||
String lastRootPath = config.getLastRootPath();
|
||||
if (lastRootPath == null) {
|
||||
return;
|
||||
}
|
||||
// 获取源文件夹
|
||||
File sourceFolder = new File(lastRootPath, PROGRAM_FILE_DIRECTORY);
|
||||
// 获取目标文件夹
|
||||
File targetFolder = new File(config.getRootPath(), PROGRAM_FILE_DIRECTORY);
|
||||
// 设置忽略文件夹
|
||||
Set<File> ignoredFolders = config.getIgnoreFolder();
|
||||
// 设置忽略文件
|
||||
Set<File> ignoredFiles = config.getIgnoreFile();
|
||||
// 移动文件夹
|
||||
FileUtil.migrateFolder(sourceFolder, targetFolder, ignoredFolders, ignoredFiles);
|
||||
// 删除.jnotepad
|
||||
if (!sourceFolder.equals(new File(Paths.get(System.getProperty(DEFAULT_PROPERTY), PROGRAM_FILE_DIRECTORY).toString()))) {
|
||||
try {
|
||||
Files.delete(sourceFolder.toPath());
|
||||
} catch (IOException e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
}
|
||||
// 保存新配置
|
||||
AppConfigController.getInstance().writeConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止前操作
|
||||
*
|
||||
* @apiNote 在停止程序之前会执行此操作
|
||||
*/
|
||||
public void stopApp() {
|
||||
public void operationBeforeStopping() {
|
||||
PluginConfigController pluginConfigController = PluginConfigController.getInstance();
|
||||
// 刷新插件配置文件
|
||||
pluginConfigController.getConfig().setPlugins(PluginManager.getInstance().getPluginDescriptors());
|
||||
@ -146,6 +188,8 @@ public class ApplicationManager {
|
||||
CenterTabPaneManager.getInstance().saveOpenFileTabs();
|
||||
// 将缓存写入本地
|
||||
CacheController.getInstance().writeCaches();
|
||||
// 迁移文件夹
|
||||
migrateFileRootFolder();
|
||||
// 关闭线程池
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
@ -205,12 +249,11 @@ public class ApplicationManager {
|
||||
// 构建新进程来重新启动应用程序
|
||||
ProcessBuilder builder = new ProcessBuilder(javaCommand, "-cp", System.getProperty("java.class.path"), mainClass);
|
||||
builder.start();
|
||||
|
||||
// 关闭当前应用程序
|
||||
System.exit(0);
|
||||
// fixme 使用这个System.exit(0);,在开发环境,点击重启程序,停止前操作不生效
|
||||
stop();
|
||||
} catch (IOException e) {
|
||||
LogUtil.getLogger("正在重启当前应用程序".getClass());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +282,7 @@ public class ApplicationManager {
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
public void stopApplication() {
|
||||
public void stop() {
|
||||
Platform.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,10 @@ public class AppConstants {
|
||||
* 默认属性
|
||||
*/
|
||||
public static final String DEFAULT_PROPERTY = "user.home";
|
||||
/**
|
||||
* 程序文件目录
|
||||
*/
|
||||
public static final String PROGRAM_FILE_DIRECTORY = ".jnotepad";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package org.jcnc.jnotepad.component.module.interfaces;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 控制器接口类
|
||||
*
|
||||
@ -9,14 +7,14 @@ import java.util.List;
|
||||
*
|
||||
* @author 许轲
|
||||
*/
|
||||
public interface ControllerAble {
|
||||
public interface ControllerAble<T> {
|
||||
|
||||
/**
|
||||
* 打开关联文件并创建 TextArea。
|
||||
*
|
||||
* @param rawParameters 原始参数列表
|
||||
*/
|
||||
void openAssociatedFileAndCreateTextArea(List<String> rawParameters);
|
||||
void openAssociatedFileAndCreateTextArea(T rawParameters);
|
||||
|
||||
/**
|
||||
* 打开关联文件。
|
||||
|
||||
@ -266,6 +266,9 @@ public class SetStage extends Stage {
|
||||
cache.setCacheData(file.getParent());
|
||||
cacheManager.addCache(cache);
|
||||
}
|
||||
// 设置上次的根路径
|
||||
config.setLastRootPath(config.getRootPath());
|
||||
// 设置当前根路径
|
||||
config.setRootPath(file.getAbsolutePath());
|
||||
PopUpUtil.questionAlert("更改", "设置程序文件根路径", "设置成功,请重启程序以应用路径更改!", appDialog -> {
|
||||
appDialog.close();
|
||||
|
||||
@ -1,25 +1,15 @@
|
||||
package org.jcnc.jnotepad.controller;
|
||||
|
||||
import org.jcnc.jnotepad.controller.config.PluginConfigController;
|
||||
import org.jcnc.jnotepad.controller.exception.AppException;
|
||||
import org.jcnc.jnotepad.controller.i18n.LocalizationController;
|
||||
import org.jcnc.jnotepad.plugin.PluginLoader;
|
||||
import org.jcnc.jnotepad.util.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 资源控制器:用于加载程序所需的资源
|
||||
* 资源控制器
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class ResourceController {
|
||||
private static final ResourceController INSTANCE = new ResourceController();
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
private ResourceController() {
|
||||
}
|
||||
@ -33,42 +23,6 @@ public class ResourceController {
|
||||
// 1. 加载语言
|
||||
LocalizationController.initLocal();
|
||||
// 2. 加载插件
|
||||
loadPlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* 装载插件
|
||||
*
|
||||
* @since 2023/9/15 21:39
|
||||
*/
|
||||
public void loadPlugins() {
|
||||
// 扫描并装载插件
|
||||
scanLoadPlugins(PluginConfigController.getInstance().getPlungsPath());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 扫描插件
|
||||
*
|
||||
* @param pluginsPath 插件路径
|
||||
* @apiNote 扫描所有插件,更新配置文件中的插件信息
|
||||
* @since 2023/9/16 0:21
|
||||
*/
|
||||
|
||||
private void scanLoadPlugins(Path pluginsPath) {
|
||||
if (!Files.isDirectory(pluginsPath)) {
|
||||
try {
|
||||
Files.createDirectory(pluginsPath);
|
||||
} catch (IOException e) {
|
||||
throw new AppException("这不是一个有效的路径!");
|
||||
}
|
||||
}
|
||||
// 获取插件加载器
|
||||
PluginLoader pluginLoader = PluginLoader.getInstance();
|
||||
try (Stream<Path> pathStream = Files.walk(pluginsPath)) {
|
||||
pathStream.filter(path -> path.toString().endsWith(".jar")).forEach(path -> pluginLoader.loadPluginByPath(path.toString()));
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
PluginLoader.getInstance().loadPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import org.jcnc.jnotepad.app.config.AppConfig;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.DEFAULT_PROPERTY;
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.PROGRAM_FILE_DIRECTORY;
|
||||
|
||||
/**
|
||||
* 应用程序配置文件控制器
|
||||
@ -23,12 +24,12 @@ public class AppConfigController extends BaseConfigController<AppConfig> {
|
||||
/**
|
||||
* 配置文件名
|
||||
*/
|
||||
public static final String CONFIG_NAME = "appConfig.json";
|
||||
public static final String CONFIG_NAME = "JNotepadConfig.json";
|
||||
|
||||
private final String configDir;
|
||||
|
||||
public AppConfigController() {
|
||||
configDir = Paths.get(System.getProperty(DEFAULT_PROPERTY), ".jnotepad", ROOT_CONFIG_DIR).toString();
|
||||
configDir = Paths.get(System.getProperty(DEFAULT_PROPERTY), PROGRAM_FILE_DIRECTORY, systemConfigDir).toString();
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,8 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.PROGRAM_FILE_DIRECTORY;
|
||||
|
||||
/**
|
||||
* 插件控制器
|
||||
*
|
||||
@ -24,8 +26,8 @@ public class PluginConfigController extends BaseConfigController<PluginConfig> {
|
||||
|
||||
private PluginConfigController() {
|
||||
String rootPath = AppConfigController.getInstance().getConfig().getRootPath();
|
||||
configDir = Paths.get(rootPath, ".jnotepad", ROOT_CONFIG_DIR).toString();
|
||||
setPluginsDir(Paths.get(rootPath, ".jnotepad", "plugins").toString());
|
||||
configDir = Paths.get(rootPath, PROGRAM_FILE_DIRECTORY, rootConfigDir).toString();
|
||||
setPluginsDir(Paths.get(rootPath, PROGRAM_FILE_DIRECTORY, "plugins").toString());
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jcnc.jnotepad.common.constants.AppConstants.PROGRAM_FILE_DIRECTORY;
|
||||
import static org.jcnc.jnotepad.common.constants.TextConstants.CHINESE;
|
||||
|
||||
/**
|
||||
@ -31,7 +32,7 @@ public class UserConfigController extends BaseConfigController<UserConfig> {
|
||||
private String configDir;
|
||||
|
||||
private UserConfigController() {
|
||||
configDir = Paths.get(AppConfigController.getInstance().getConfig().getRootPath(), ".jnotepad", ROOT_CONFIG_DIR).toString();
|
||||
configDir = Paths.get(AppConfigController.getInstance().getConfig().getRootPath(), PROGRAM_FILE_DIRECTORY, rootConfigDir).toString();
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import java.util.Optional;
|
||||
*
|
||||
* @author 许轲
|
||||
*/
|
||||
public class Controller implements ControllerAble {
|
||||
public class Controller implements ControllerAble<List<String>> {
|
||||
private static final ApplicationCacheManager CACHE_MANAGER = ApplicationCacheManager.getInstance();
|
||||
|
||||
private static final Controller INSTANCE = new Controller();
|
||||
|
||||
@ -14,10 +14,13 @@ import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
@ -244,4 +247,39 @@ public class PluginLoader {
|
||||
logger.info("已加载插件:{}", pluginDescriptor.getName());
|
||||
return pluginClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 装载插件
|
||||
*
|
||||
* @since 2023/9/15 21:39
|
||||
*/
|
||||
public void loadPlugins() {
|
||||
// 扫描并装载插件
|
||||
scanLoadPlugins(PluginConfigController.getInstance().getPlungsPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描插件
|
||||
*
|
||||
* @param pluginsPath 插件路径
|
||||
* @apiNote 扫描所有插件,更新配置文件中的插件信息
|
||||
* @since 2023/9/16 0:21
|
||||
*/
|
||||
|
||||
private void scanLoadPlugins(Path pluginsPath) {
|
||||
if (!Files.isDirectory(pluginsPath)) {
|
||||
try {
|
||||
Files.createDirectory(pluginsPath);
|
||||
} catch (IOException e) {
|
||||
throw new AppException("这不是一个有效的路径!");
|
||||
}
|
||||
}
|
||||
// 获取插件加载器
|
||||
PluginLoader pluginLoader = PluginLoader.getInstance();
|
||||
try (Stream<Path> pathStream = Files.walk(pluginsPath)) {
|
||||
pathStream.filter(path -> path.toString().endsWith(".jar")).forEach(path -> pluginLoader.loadPluginByPath(path.toString()));
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import java.nio.file.StandardCopyOption;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled.*;
|
||||
|
||||
@ -170,7 +171,7 @@ public class FileUtil {
|
||||
* @since 2023/10/5 12:18
|
||||
*/
|
||||
|
||||
private static void migrateFolder(File sourceFolder, File targetFolder) {
|
||||
public static void migrateFolder(File sourceFolder, File targetFolder) {
|
||||
// 创建目标文件夹
|
||||
targetFolder.mkdirs();
|
||||
|
||||
@ -197,4 +198,74 @@ public class FileUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移文件夹
|
||||
*
|
||||
* @param sourceFolder 源文件夹
|
||||
* @param targetFolder 目标文件夹
|
||||
* @param ignoredFolders 忽略的文件夹集合
|
||||
* @param ignoredFiles 忽略的文件集合
|
||||
* @since 2023/10/5 13:58
|
||||
*/
|
||||
public static void migrateFolder(File sourceFolder, File targetFolder, Set<File> ignoredFolders, Set<File> ignoredFiles) {
|
||||
// 创建目标文件夹
|
||||
targetFolder.mkdir();
|
||||
// 获取源文件夹中的所有文件和文件夹
|
||||
File[] files = sourceFolder.listFiles();
|
||||
if (files != null) {
|
||||
// 遍历源文件夹中的每个文件和文件夹
|
||||
for (File file : files) {
|
||||
// 如果是文件夹且不是忽略的文件夹,递归调用自身进行迁移
|
||||
if (file.isDirectory() && !ignoredFolders.contains(file)) {
|
||||
migrateFolder(targetFolder, ignoredFolders, ignoredFiles, file);
|
||||
continue;
|
||||
}
|
||||
// 如果是文件且不是忽略的文件,将文件复制到目标文件夹中
|
||||
if (!file.isDirectory() && !ignoredFiles.contains(file)) {
|
||||
migrateFile(targetFolder, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移文件
|
||||
*
|
||||
* @param targetFolder 目标文件夹
|
||||
* @param file 文件
|
||||
*/
|
||||
public static void migrateFile(File targetFolder, File file) {
|
||||
Path sourceFilePath = file.toPath();
|
||||
Path targetFilePath = new File(targetFolder, file.getName()).toPath();
|
||||
try {
|
||||
Files.copy(sourceFilePath, targetFilePath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
// 删除源文件
|
||||
try {
|
||||
Files.delete(file.toPath());
|
||||
} catch (IOException e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移文件夹
|
||||
*
|
||||
* @param targetFolder 目标文件夹
|
||||
* @param ignoredFolders 忽略的文件夹集合
|
||||
* @param ignoredFiles 忽略的文件集合
|
||||
* @param file 文件
|
||||
*/
|
||||
private static void migrateFolder(File targetFolder, Set<File> ignoredFolders, Set<File> ignoredFiles, File file) {
|
||||
migrateFolder(file, new File(targetFolder, file.getName()), ignoredFolders, ignoredFiles);
|
||||
// 调用完毕删除当前目录
|
||||
try {
|
||||
Files.deleteIfExists(file.toPath());
|
||||
} catch (IOException e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user