commit 6cb6bb705f14fd21ca401fe9bc59da71a9402798 Author: zm <1334717033@qq.com> Date: Fri Mar 8 18:20:49 2024 +0800 2024年3月8日18:20:13 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4dc7b69 --- /dev/null +++ b/pom.xml @@ -0,0 +1,164 @@ + + + 4.0.0 + + com.zhangmeng + javafx-tools-minio + 1.0-SNAPSHOT + + + 17 + 17 + 19 + + + + + io.minio + minio + 8.5.7 + + + + com.squareup.okhttp3 + okhttp + 4.8.1 + + + + org.projectlombok + lombok + 1.18.30 + + + + org.apache.commons + commons-lang3 + 3.11 + + + + org.openjfx + javafx-controls + ${javafx.version} + + + + org.openjfx + javafx-base + ${javafx.version} + + + + org.openjfx + javafx-graphics + ${javafx.version} + + + + org.openjfx + javafx-fxml + ${javafx.version} + + + + org.openjfx + javafx-web + ${javafx.version} + + + + org.openjfx + javafx-media + ${javafx.version} + + + + + org.openjfx + javafx-swing + ${javafx.version} + + + + com.github.leewyatt + rxcontrols + + 11.0.2 + + + + com.fasterxml.jackson.core + jackson-core + 2.16.1 + + + + com.google.guava + guava + 30.1-jre + + + log4j + log4j + 1.2.17 + + + org.apache.tika + tika-core + 1.27 + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + true + lib/ + com.zhangmeng.minio.MiniToolsApplication + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + + + jitpack.io + https://jitpack.io + + + zm + http://123.57.75.116:49000/repository/zm/ + + + \ No newline at end of file diff --git a/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java b/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java new file mode 100644 index 0000000..0a9da57 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java @@ -0,0 +1,64 @@ +package com.zhangmeng.minio; + +import com.google.common.eventbus.Subscribe; +import com.zhangmeng.minio.controller.MinioController; +import com.zhangmeng.minio.message.Message; +import com.zhangmeng.minio.utils.ConfigUtils; +import com.zhangmeng.minio.utils.EventBusUtils; +import com.zhangmeng.minio.utils.MinioUtils; +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import lombok.extern.log4j.Log4j; +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggerFactory; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 14:24 + */ +public class MiniToolsApplication extends Application { + + @Override + public void start(Stage primaryStage) throws Exception { + + MinioUtils.objectMap.put(MinioUtils.primaryStage,primaryStage); + + Parent root = FXMLLoader.load(this.getClass().getResource("/fxml/main.fxml")); + primaryStage.setScene(new Scene(root)); + primaryStage.setTitle("javafx minio 工具"); + primaryStage.show(); + } + + @Override + public void init() throws Exception { + EventBusUtils.getDefault().register(this); + } + + @Override + public void stop() throws Exception { + EventBusUtils.getDefault().unregister(this); + MinioController minioController = (MinioController) MinioUtils.objectMap.get(MinioUtils.minioController); + if (minioController != null){ + EventBusUtils.getDefault().unregister(minioController); + System.out.println("EventBusUtils.getDefault().unregister(minioController)"); + } + System.out.println("EventBusUtils.getDefault().unregister(MiniToolsApplication) "); + } + + public static void main(String[] args) { + launch(args); + } + + @Subscribe + public void handlerMessage(Message message){ + System.out.println(message.getMsg()); + MinioController minioController = (MinioController) MinioUtils.objectMap.get(MinioUtils.minioController); + minioController.reload(); + + ConfigUtils.getDefaultConfig(); + } +} diff --git a/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java b/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java new file mode 100644 index 0000000..6fc4a0c --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java @@ -0,0 +1,59 @@ +package com.zhangmeng.minio.controller; + +import com.zhangmeng.minio.message.Message; +import com.zhangmeng.minio.utils.AlertUtils; +import com.zhangmeng.minio.utils.EventBusUtils; +import com.zhangmeng.minio.utils.MinioUtils; +import io.minio.MinioClient; +import io.minio.messages.Bucket; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.ComboBox; +import javafx.stage.Stage; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 15:40 + */ +public class BucketChooseController { + + @FXML + public ComboBox comboBox; + + private final ObservableList list = FXCollections.observableArrayList(); + + @FXML + public void initialize() { + //获取所有储存桶 + List buckets = MinioUtils.getAllBuckets(); + if (buckets.size()>0){ + for (Bucket bucket : buckets) { + list.add(bucket.name()); + } + } + comboBox.setItems(list); + } + + @FXML + public void save_choose(ActionEvent actionEvent) { + + String selectedItem = comboBox.getSelectionModel().getSelectedItem(); + if (selectedItem == null ){ + AlertUtils.alert_warning("请选择储存桶再试!"); + return; + } + MinioUtils.objectMap.put(MinioUtils.current_bucket,selectedItem); + Stage stage = (Stage) MinioUtils.objectMap.get(MinioUtils.bucket_choose_action_stage); + stage.close(); + + EventBusUtils.getDefault().post(new Message("save_choose .............")); + } +} diff --git a/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java b/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java new file mode 100644 index 0000000..0335fac --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java @@ -0,0 +1,93 @@ +package com.zhangmeng.minio.controller; + +import com.zhangmeng.minio.model.BucketFile; +import com.zhangmeng.minio.utils.AlertUtils; +import com.zhangmeng.minio.utils.MinioUtils; +import javafx.collections.ObservableMap; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Region; +import javafx.scene.text.Text; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.stage.Window; + +import java.io.IOException; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 16:30 + */ +public class BucketFileCell extends ListCell { + + private final Label label; + private final BorderPane pane; + + public BucketFileCell() { + pane = new BorderPane(); + label = new Label(); + BorderPane.setAlignment(label, Pos.CENTER_LEFT); + Button button = new Button(); + button.getStyleClass().add("remove-btn"); + button.setGraphic(new Region()); + button.setOnAction(event -> { + + try { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/alert.fxml")); + Parent root = fxmlLoader.load(); + ObservableMap namespace = fxmlLoader.getNamespace(); + Button yes = (Button) namespace.get("yes"); + Button cancel = (Button) namespace.get("cancel"); + + Stage stage = AlertUtils.alert("文件删除",root,396,200, (Stage) MinioUtils.objectMap.get(MinioUtils.primaryStage)); + + yes.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + if (getItem() == getListView().getSelectionModel().getSelectedItem()) { + getListView().getSelectionModel().clearSelection(); + } + getListView().getItems().remove(getItem()); + stage.close(); + } + }); + + cancel.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + stage.close(); + } + }); + + + + } catch (IOException e) { + e.printStackTrace(); + } + }); + pane.setCenter(label); + pane.setRight(button); + } + + @Override + protected void updateItem(BucketFile item, boolean empty) { + super.updateItem(item, empty); + if (item == null || empty) { + setGraphic(null); + setText(""); + } else { + String name = item.getFileName(); + label.setText(name.substring(0, name.length() - 4) ); + setGraphic(pane); + } + + } +} diff --git a/src/main/java/com/zhangmeng/minio/controller/MinioController.java b/src/main/java/com/zhangmeng/minio/controller/MinioController.java new file mode 100644 index 0000000..a93ce8c --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/controller/MinioController.java @@ -0,0 +1,333 @@ +package com.zhangmeng.minio.controller; + +import com.google.common.reflect.ClassPath; +import com.zhangmeng.minio.model.BucketFile; +import com.zhangmeng.minio.utils.AlertUtils; +import com.zhangmeng.minio.utils.EventBusUtils; +import com.zhangmeng.minio.utils.MinioUtils; +import io.minio.messages.Bucket; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.ObservableMap; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.*; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; +import javafx.scene.layout.AnchorPane; +import javafx.stage.FileChooser; +import javafx.stage.Stage; +import org.apache.commons.lang3.ClassPathUtils; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Properties; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 15:29 + */ +public class MinioController { + + @FXML + public ListView listView; + + @FXML + public AnchorPane center; + + private final ObservableList list = FXCollections.observableArrayList(); + + @FXML + public MenuItem config_file; + + @FXML + public MenuItem bucket_choose; + + @FXML + public MenuItem reload_config; + + @FXML + public Button upload; + + @FXML + public Button choose_upload_file; + + @FXML + public TextField upload_path; + + @FXML + public TextField bucket_name; + + @FXML + public Button bucket_btn; + + @FXML + public TextField endpoint; + + @FXML + public TextField accessKey; + + @FXML + public TextField secretKey; + + @FXML + public Button save_config; + + @FXML + public ComboBox backet_list; + + private final ObservableList backet_item_list = FXCollections.observableArrayList(); + + private File upload_file; + + public MinioController() { + EventBusUtils.getDefault().register(this); + } + + @FXML + public void initialize() { + listView.setItems(list); + listView.setCellFactory(fileListView -> new BucketFileCell()); + + //绑定快捷键 + KeyCombination kc1 = KeyCombination.valueOf("ctrl+q"); + config_file.setAccelerator(kc1); + config_file.setOnAction(event -> { + FileInputStream fileInputStream = null; + try { + FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/fxml/config.fxml")); + AnchorPane root = fxmlLoader.load(); + ObservableMap namespace = fxmlLoader.getNamespace(); + TextArea text_area = (TextArea) namespace.get("text_area"); + Button save_p = (Button) namespace.get("save_p"); + URL resource = this.getClass().getResource("/minio.properties"); + fileInputStream = new FileInputStream(new File(resource.getFile())); + byte[] bytes = fileInputStream.readAllBytes(); + text_area.setText(new String(bytes, StandardCharsets.UTF_8)); + Stage stage = AlertUtils.alert("minio 配置文件",root,600,410,(Stage) MinioUtils.objectMap.get(MinioUtils.primaryStage)); + save_p.setOnAction(event1 -> { + stage.close(); + try { + FileWriter fileWriter = new FileWriter(resource.getFile()); + fileWriter.write(text_area.getText()); + fileWriter.flush(); + fileWriter.close(); + load_property(); + } catch (IOException e) { + e.printStackTrace(); + } + AlertUtils.alert_msg("保存成功!"); + }); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fileInputStream != null){ + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + }); + + KeyCombination kc2 = KeyCombination.valueOf("ctrl+r"); + reload_config.setAccelerator(kc2); + + KeyCombination kc3 = KeyCombination.valueOf("ctrl+b"); + bucket_choose.setAccelerator(kc3); + MinioUtils.objectMap.put(MinioUtils.minioController,this); + + choose_upload_file.setOnAction(event -> { + //打开文件 + Stage stage = new Stage(); + FileChooser dc = new FileChooser(); + dc.setTitle("文件选择"); + dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文件类型", "*.*")); + File file = dc.showOpenDialog(stage); + if (file != null){ + //展示路径 + upload_file = file; + upload_path.setText(file.getAbsolutePath()); + } + }); + + upload.setOnAction(event -> { + + if (upload_file == null){ + AlertUtils.alert_warning("请选择上传的文件后再试!"); + return; + } + + MinioUtils.upload_file(upload_file); + }); + + bucket_btn.setOnAction(event -> { + + if (endpoint.getText().length() == 0 ){ + AlertUtils.alert_warning("endpoint 不能为空!"); + return; + } + + if (accessKey.getText().length() == 0 ){ + AlertUtils.alert_warning("accessKey 不能为空!"); + return; + } + if (secretKey.getText().length() == 0 ){ + AlertUtils.alert_warning("secretKey 不能为空!"); + return; + } + + if (bucket_name.getText().length() == 0 ){ + AlertUtils.alert_warning("bucket_name 不能为空!"); + return; + } + MinioUtils.createBucket(bucket_name.getText()); + }); + + load_property(); + + save_config.setOnAction(event -> save_properties()); + + backet_list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + if (newValue != null){ + MinioUtils.objectMap.put(MinioUtils.current_bucket,newValue); + reload(); + } + } + }); + } + + public void save_properties(){ + + if (endpoint.getText().length() == 0 ){ + AlertUtils.alert_warning("endpoint 不能为空!"); + return; + } + + if (accessKey.getText().length() == 0 ){ + AlertUtils.alert_warning("accessKey 不能为空!"); + return; + } + if (secretKey.getText().length() == 0 ){ + AlertUtils.alert_warning("secretKey 不能为空!"); + return; + } + + // 创建一个Properties对象 + Properties properties = new Properties(); + URL resource = this.getClass().getResource("/minio.properties"); + if (resource != null){ + InputStream input = null; + OutputStream output = null; + try { + String file = resource.getFile(); + input = new FileInputStream(new File(file)); + output = new FileOutputStream(new File(file)); + // load a properties file + properties.load(input); + properties.put("endpoint",this.endpoint.getText()); + properties.put("accessKey",this.accessKey.getText()); + properties.put("secretKey",this.secretKey.getText()); + properties.store(output,"save"); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (output != null){ + try { + output.close(); + }catch (IOException e){ + e.printStackTrace(); + } + } + } + load_property(); + AlertUtils.alert_warning("配置文件保存成功!"); + } + } + + public void load_property(){ + Properties prop = new Properties(); + URL resource = this.getClass().getResource("/minio.properties"); + if (resource != null){ + String file = resource.getFile(); + InputStream input = null; + try { + input = new FileInputStream(new File(file)); + // load a properties file + prop.load(input); + // get the property value and print it out + String endpoint = prop.getProperty("endpoint"); + this.endpoint.setText(endpoint); + String accessKey = prop.getProperty("accessKey"); + this.accessKey.setText(accessKey); + String secretKey = prop.getProperty("secretKey"); + this.secretKey.setText(secretKey); + + MinioUtils.objectMap.put("endpoint",endpoint); + MinioUtils.objectMap.put("accessKey",accessKey); + MinioUtils.objectMap.put("secretKey",secretKey); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + //获取所有储存桶 + List buckets = MinioUtils.getAllBuckets(); + if (buckets.size()>0){ + for (Bucket bucket : buckets) { + backet_item_list.add(bucket.name()); + } + } + this.backet_list.setItems(backet_item_list); + } + + @FXML + private void bucket_choose_action(){ + Stage primaryStage = (Stage) this.listView.getScene().getWindow(); + FXMLLoader fxmlLoader =new FXMLLoader( getClass().getResource("/fxml/bucket_choose.fxml")); + AnchorPane bucket_choose = null; + try { + bucket_choose = fxmlLoader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + Stage stage = AlertUtils.alert("设置", bucket_choose, primaryStage); + MinioUtils.objectMap.put(MinioUtils.bucket_choose_action_stage,stage); + } + + @FXML + public void reload(){ + String bucketName = MinioUtils.objectMap.get(MinioUtils.current_bucket).toString(); + List bucketFiles = MinioUtils.getFileList(bucketName); + if (bucketFiles.size()>0){ + list.clear(); + list.addAll(bucketFiles); + } + } +} diff --git a/src/main/java/com/zhangmeng/minio/message/Message.java b/src/main/java/com/zhangmeng/minio/message/Message.java new file mode 100644 index 0000000..ef890c1 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/message/Message.java @@ -0,0 +1,23 @@ +package com.zhangmeng.minio.message; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-08 10:19 + */ +public class Message { + + private String msg ; + + public Message(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/src/main/java/com/zhangmeng/minio/model/BucketFile.java b/src/main/java/com/zhangmeng/minio/model/BucketFile.java new file mode 100644 index 0000000..ee5ce33 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/model/BucketFile.java @@ -0,0 +1,19 @@ +package com.zhangmeng.minio.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 16:31 + */ +@Data +public class BucketFile { + + private String bucketName; + private String fileName; + private boolean isDir; + private Long size; + private String url; +} diff --git a/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java b/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java new file mode 100644 index 0000000..d3d01e1 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java @@ -0,0 +1,83 @@ +/* + * MIT License + * + * Copyright (c) 2023 芊芊墨客 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.zhangmeng.minio.utils; + +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.stage.Window; + +import java.io.IOException; + +/** + * @author : 芊芊墨客 + * @version : 1.0 + * @date : 2023-02-17 09:59 + */ +public class AlertUtils { + + /** + * 警告弹窗 + */ + public static void alert_warning(String msg) { + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.initModality(Modality.APPLICATION_MODAL); + alert.setContentText(msg); + alert.setHeaderText(null); + alert.show(); + } + + public static void alert_msg(String msg) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.initModality(Modality.APPLICATION_MODAL); + alert.setContentText(msg); + alert.setHeaderText(null); + alert.show(); + } + + public static Stage alert(String title, Parent node, Stage primaryStage){ + return alert(title,node,600,400,primaryStage); + } + public static Stage alert(String title, Parent node, int width, int height, Stage primaryStage) { + Scene scene = new Scene(node); + Stage stage = new Stage(); + stage.setScene(scene); + stage.setTitle(title); + stage.setWidth(width); + stage.setHeight(height); + stage.initStyle(StageStyle.UTILITY); + stage.initOwner(primaryStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setResizable(false); + stage.show(); + return stage; + } +} diff --git a/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java b/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java new file mode 100644 index 0000000..194fca4 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java @@ -0,0 +1,64 @@ +package com.zhangmeng.minio.utils; + + +import org.apache.commons.configuration2.Configuration; +import org.apache.commons.configuration2.ex.ConfigurationException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-08 14:17 + */ +public class ConfigUtils { + + public static void getDefaultConfig(){ + + + } + + public static class MinioConfig { + + private String endpoint; + private String accessKey; + private String secretKey; + + public MinioConfig() { + } + + public MinioConfig(String endpoint, String accessKey, String secretKey) { + this.endpoint = endpoint; + this.accessKey = accessKey; + this.secretKey = secretKey; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public String getAccessKey() { + return accessKey; + } + + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + } +} diff --git a/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java b/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java new file mode 100644 index 0000000..a328cb0 --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java @@ -0,0 +1,21 @@ +package com.zhangmeng.minio.utils; + +import com.google.common.eventbus.EventBus; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-08 10:00 + */ +public class EventBusUtils { + + private EventBusUtils (){ + + } + + private final static EventBus EVENT_BUS = new EventBus(); + + public static EventBus getDefault(){ + return EVENT_BUS; + } +} diff --git a/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java b/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java new file mode 100644 index 0000000..38f694d --- /dev/null +++ b/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java @@ -0,0 +1,202 @@ +package com.zhangmeng.minio.utils; + +import com.google.common.io.Files; +import com.zhangmeng.minio.model.BucketFile; +import io.minio.*; +import io.minio.http.Method; +import io.minio.messages.Bucket; +import io.minio.messages.Item; +import javafx.application.Platform; +import javafx.scene.control.TextField; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.apache.tika.Tika; +import org.apache.tika.exception.TikaException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author zhangmeng + * @version 1.0 + * @date 2024-03-07 15:45 + */ +public class MinioUtils { + + private static MinioClient minioClient = null; + + private static String endpoint = "http://192.168.1.254:9000"; + private static String accessKey = "minioadmin"; + private static String secretKey = "minioadmin"; + + public static Map objectMap = new HashMap<>(); + public static String current_bucket = "current_bucket"; + public static String primaryStage = "primaryStage"; + public static String bucket_choose_action_stage = "bucket_choose_action_stage"; + public static String minioController = "minioController"; + + public static MinioClient getDefault() { + if (minioClient == null) { + minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build(); + } + return minioClient; + } + + /** + * 获得所有Bucket列表 + * + * @return + */ + @SneakyThrows(Exception.class) + public static List getAllBuckets() { + return getDefault().listBuckets(); + } + + /** + * 启动SpringBoot容器的时候初始化Bucket + * 如果没有Bucket则创建 + * + * @param bucketName + */ + @SneakyThrows(Exception.class) + public static void createBucket(String bucketName) { + if (!bucketExists(bucketName)) { + getDefault().makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + }else { + Platform.runLater(()->{ + AlertUtils.alert_warning("bucket_name : "+ bucketName + "已存在"); + }); + } + } + + /** + * 判断Bucket是否存在,true:存在,false:不存在 + * + * @param bucketName + * @return + */ + @SneakyThrows(Exception.class) + public static boolean bucketExists(String bucketName) { + return getDefault().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + } + + public String DateFormatString(ZonedDateTime zonedDateTime){ + // 创建一个 DateTimeFormatter 对象,用于定义日期和时间的格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // 使用 formatter 来格式化 ZonedDateTime 对象 + return zonedDateTime.format(formatter); + } + + /** + * 根据文件前置查询文件 + * + * @param bucketName 存储桶 + * @param prefix 前缀 + * @param recursive 是否使用递归查询 + * @return MinioItem 列表 + */ + @SneakyThrows(Exception.class) + public static List getAllObjectsByPrefix(String bucketName, + String prefix, + boolean recursive) { + List list = new ArrayList<>(); + Iterable> objectsIterator = getDefault().listObjects( + ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build()); + if (objectsIterator != null) { + for (Result o : objectsIterator) { + Item item = o.get(); + list.add(item); + } + } + return list; + } + + /** + * 获得文件外链 + * + * @param bucketName + * @param objectName + * @return url + */ + @SneakyThrows(Exception.class) + public static String getPresignedObjectUrl(String bucketName, String objectName) { + GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder() + .bucket(bucketName) + .object(objectName) + .method(Method.GET).build(); + return getDefault() .getPresignedObjectUrl(args); + } + + @SneakyThrows(Exception.class) + public static List getFileList(String bucketName){ + List itemList = getAllObjectsByPrefix(bucketName, null, true); + List list = new ArrayList<>(); + if (itemList.size() > 0 ){ + list = itemList.stream().map(i -> { + BucketFile bucketFile = new BucketFile(); + bucketFile.setDir(i.isDir()); + bucketFile.setFileName(i.objectName()); + bucketFile.setSize(i.size()); + //获取url + String presignedObjectUrl = getPresignedObjectUrl(bucketName, i.objectName()); + bucketFile.setUrl(presignedObjectUrl); + return bucketFile; + }).collect(Collectors.toList()); + } + return list; + } + + public static void upload_file(File file){ + //文件名 + String fileName = file.getName(); + String newFileName = System.currentTimeMillis() + "." + StringUtils.substringAfterLast(fileName, "."); + String contentType = getContentType(file); + String bucketName = objectMap.get(current_bucket).toString(); + if (bucketName == null){ + AlertUtils.alert_warning("上传的bucket不能为空!"); + return; + } + uploadFile(bucketName, file, newFileName, contentType); + } + + /** + * 使用MultipartFile进行文件上传 + * + * @param bucketName 存储桶 + * @param file 文件名 + * @param objectName 对象名 + * @param contentType 类型 + * @return + */ + @SneakyThrows(Exception.class) + public static ObjectWriteResponse uploadFile(String bucketName, File file, String objectName, String contentType) { + FileInputStream inputStream = new FileInputStream(file); + return minioClient.putObject( + PutObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .contentType(contentType) + .stream(inputStream,inputStream.available(), -1) + .build()); + } + + + public static String getContentType(File file){ + Tika tika = new Tika(); + try { + return tika.detect(file); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..f8424a1 --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,20 @@ +/** + * @author zhangmeng + * @date 2024-03-07 14:29 + * @version 1.0 + */ + +open module javafx.tools.minio { + requires com.google.common; + requires javafx.controls; + requires javafx.media; + requires javafx.fxml; + requires rxcontrols; + requires minio; + requires lombok; + requires com.fasterxml.jackson.core; + requires log4j; + requires org.apache.commons.lang3; + requires tika.core; + requires org.apache.commons.configuration2; +} \ No newline at end of file diff --git a/src/main/resources/css/main.css b/src/main/resources/css/main.css new file mode 100644 index 0000000..c677768 --- /dev/null +++ b/src/main/resources/css/main.css @@ -0,0 +1,56 @@ +.root{ + /*-fx-background-image: url(../img/sunset.jpg);*/ + /*-fx-background-size: 1200;*/ + + -base-hover-color: #1ECE9A; +} + +.split-pane{ + /*-fx-background-image: url(../img/sunset.jpg);*/ + -fx-background-size: 1200; + -fx-background-color: white; +} + +.list-view{ + -fx-font-size: 14; + -fx-focus-color: #0000; + -fx-faint-focus-color: #0000; + -fx-background-color: white; +} + +.list-cell { + -fx-pref-height: 40; + -fx-background-color: null; +} + +.list-cell:hover, +.list-cell:selected { + -fx-background-color: #F8F8F8; +} + +.list-cell:hover .label, +.list-cell:selected .label { + -fx-text-fill: -base-hover-color; +} + +.menu-bar{ + -fx-background-color: #beebb6; + -fx-text-fill: black; +} + +.list-cell .remove-btn { + -fx-background-color: null; + -fx-pref-height: 20; + -fx-pref-width: 38; + visibility: hidden; +} + +.list-cell .remove-btn Region { + -fx-background-color: -base-hover-color; + -fx-shape: "M798.938839 1017.751676h-497.58838a120.584726 120.584726 0 0 1-123.951493-118.62903V274.661607a29.706769 29.706769 0 0 1 31.910021-29.186901 30.89504 30.89504 0 0 1 31.885265 29.186901v624.461039a60.131451 60.131451 0 0 0 62.01288 58.349045h497.58838a61.319722 61.319722 0 0 0 62.01288-58.349045V274.661607a29.706769 29.706769 0 0 1 31.885266-29.186901 30.919795 30.919795 0 0 1 31.910021 29.186901v624.461039a125.189275 125.189275 0 0 1-127.615329 118.62903z m-92.041472-178.933771a30.89504 30.89504 0 0 1-31.885266-29.186901V393.315393a29.855303 29.855303 0 0 1 31.885266-29.261168 30.919795 30.919795 0 0 1 31.910021 29.261168v416.241344a32.182333 32.182333 0 0 1-31.910021 29.36019z m-155.960537 0a30.89504 30.89504 0 0 1-31.885266-29.186901V393.315393a29.706769 29.706769 0 0 1 31.885266-29.261168 30.969307 30.969307 0 0 1 31.910021 29.261168v416.241344a30.919795 30.919795 0 0 1-31.786243 29.36019z m-155.960537 0a30.870284 30.870284 0 0 1-31.910021-29.186901V393.315393a29.706769 29.706769 0 0 1 31.910021-29.261168 30.969307 30.969307 0 0 1 31.910021 29.261168v416.241344a30.919795 30.919795 0 0 1-31.662465 29.36019zM1063.551883 214.431133H38.098975A30.89504 30.89504 0 0 1 6.188954 185.268988a29.706769 29.706769 0 0 1 31.910021-29.261168H332.963412V95.802102A91.37307 91.37307 0 0 1 426.886314 6.31046h247.878231a92.561341 92.561341 0 0 1 93.898145 89.491642v60.205718h294.889193a29.335434 29.335434 0 1 1 0 58.423313zM394.976293 154.225414h311.673517V93.920673a29.706769 29.706769 0 0 0-31.885265-29.162145H426.886314a30.89504 30.89504 0 0 0-31.910021 29.162145zM799.013106 1023.940586h-497.58838a126.253768 126.253768 0 0 1-130.115648-124.842696V274.661607a35.994702 35.994702 0 0 1 38.098931-35.375811 36.861149 36.861149 0 0 1 38.074176 35.375811v624.436283a54.165342 54.165342 0 0 0 55.82397 52.184891h497.58838a55.526902 55.526902 0 0 0 55.82397-52.184891V274.661607a35.994702 35.994702 0 0 1 38.098931-35.375811 36.836393 36.836393 0 0 1 38.074175 35.375811v624.436283a130.586005 130.586005 0 0 1-133.878505 124.842696z m-589.728875-772.375992a23.666393 23.666393 0 0 0-25.721111 22.99799V898.998867a113.875948 113.875948 0 0 0 117.737828 112.464877h497.58838a119.693523 119.693523 0 0 0 121.30264-112.61341V274.661607a24.755641 24.755641 0 0 0-25.696355-22.997991 23.666393 23.666393 0 0 0-25.721111 22.997991v624.436283a67.360099 67.360099 0 0 1-68.201791 64.562711h-497.58838a66.518407 66.518407 0 0 1-68.20179-64.562711V274.661607a24.755641 24.755641 0 0 0-25.49831-22.997991z m497.58838 593.343198a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.885905 36.885905 0 0 1 38.074175 35.450078v416.241344a38.371243 38.371243 0 0 1-38.049419 35.375811z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a24.755641 24.755641 0 0 0 25.696355 22.99799 25.8944 25.8944 0 0 0 25.745867-23.56737v-415.647209a24.755641 24.755641 0 0 0-25.696355-22.99799z m-155.960537 474.689412a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.885905 36.885905 0 0 1 38.074175 35.450078v416.241344a36.836393 36.836393 0 0 1-37.925641 35.450078z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a25.869645 25.869645 0 0 0 51.417466 0V393.315393a24.755641 24.755641 0 0 0-25.547821-22.99799z m-155.960537 474.689412a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.91066 36.91066 0 0 1 38.098931 35.450078v416.241344a36.861149 36.861149 0 0 1-37.826619 35.450078z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a25.8944 25.8944 0 0 0 51.442222 0V393.315393a24.755641 24.755641 0 0 0-25.448799-22.99799zM1063.502372 220.52102H38.049464A36.836393 36.836393 0 0 1-0.024712 185.169965a36.019457 36.019457 0 0 1 38.074176-35.450077H326.774502V95.678324a98.032338 98.032338 0 0 1 100.087056-95.655796h247.853476a99.27012 99.27012 0 0 1 100.111811 95.655796v54.041564H1063.502372a36.885905 36.885905 0 0 1 38.098931 35.450077 37.306751 37.306751 0 0 1-37.826619 35.450078zM38.049464 162.097708a23.666393 23.666393 0 0 0-25.696355 23.072257 24.755641 24.755641 0 0 0 25.696355 22.973235H1063.502372a23.17128 23.17128 0 1 0 0-46.045492H762.449025V95.678324A86.644743 86.644743 0 0 0 674.715034 12.400348H426.861558A85.679273 85.679273 0 0 0 339.152323 95.678324v66.419384z m674.764501-1.782406h-324.051338V93.821651a36.861149 36.861149 0 0 1 38.098931-35.375811h247.853476a36.019457 36.019457 0 0 1 38.098931 35.375811z m-311.673518-12.377821h299.295697V93.821651a23.666393 23.666393 0 0 0-25.72111-22.997991H426.861558a24.755641 24.755641 0 0 0-25.721111 22.997991z"; +} + +.list-cell:hover .remove-btn, +.list-cell:selected .remove-btn { + visibility: visible; +} \ No newline at end of file diff --git a/src/main/resources/fxml/alert.fxml b/src/main/resources/fxml/alert.fxml new file mode 100644 index 0000000..40ce9b8 --- /dev/null +++ b/src/main/resources/fxml/alert.fxml @@ -0,0 +1,17 @@ + + + + + + + + + + +