This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 6b22959e91 Add the “Save As” capability to text files #6238 (#6260)
6b22959e91 is described below
commit 6b22959e91d00fb7f10c76dd9ad4d630db075cd2
Author: Nicolas Adment <[email protected]>
AuthorDate: Mon Dec 29 11:48:06 2025 +0100
Add the “Save As” capability to text files #6238 (#6260)
---
.../transforms/types/JsonExplorerFileType.java | 1 +
.../types/JsonExplorerFileTypeTest.java} | 42 +++++++++++++---------
.../transforms/types/CsvExplorerFileType.java | 5 ++-
.../transforms/types/MarkDownExplorerFileType.java | 1 +
.../transforms/types/TextExplorerFileType.java | 1 +
.../transforms/types/CsvExplorerFileTypeTest.java | 20 ++++++++---
.../types/MarkDownExplorerFileTypeTest.java | 12 ++++++-
.../transforms/types/TextExplorerFileTypeTest.java | 5 +++
.../transforms/xml/types/XmlExplorerFileType.java | 1 +
.../types/base/BaseExplorerFileTypeHandler.java | 7 ++--
.../file/types/log/LogExplorerFileType.java | 1 +
.../text/BaseTextExplorerFileTypeHandler.java | 39 ++++++++++++++++++--
12 files changed, 108 insertions(+), 27 deletions(-)
diff --git
a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileType.java
b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileType.java
index c7afb68bb7..fc19743704 100644
---
a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileType.java
+++
b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileType.java
@@ -44,6 +44,7 @@ public class JsonExplorerFileType extends
BaseTextExplorerFileType<JsonExplorerF
new String[] {"JSON files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
IHopFileType.CAPABILITY_FILE_HISTORY,
IHopFileType.CAPABILITY_COPY,
diff --git
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
b/plugins/transforms/json/src/test/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileTypeTest.java
similarity index 76%
copy from
plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
copy to
plugins/transforms/json/src/test/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileTypeTest.java
index bb972423e3..30a08b2fe8 100644
---
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
+++
b/plugins/transforms/json/src/test/java/org/apache/hop/pipeline/transforms/types/JsonExplorerFileTypeTest.java
@@ -26,13 +26,13 @@ import org.apache.hop.ui.hopgui.file.IHopFileType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-class CsvExplorerFileTypeTest {
+class JsonExplorerFileTypeTest {
- private CsvExplorerFileType fileType;
+ private JsonExplorerFileType fileType;
@BeforeEach
void setUp() {
- fileType = new CsvExplorerFileType();
+ fileType = new JsonExplorerFileType();
}
@Test
@@ -42,12 +42,12 @@ class CsvExplorerFileTypeTest {
@Test
void testGetName() {
- assertEquals("CSV File", fileType.getName());
+ assertEquals("JSON File", fileType.getName());
}
@Test
void testGetDefaultFileExtension() {
- assertEquals(".csv", fileType.getDefaultFileExtension());
+ assertEquals(".json", fileType.getDefaultFileExtension());
}
@Test
@@ -55,7 +55,7 @@ class CsvExplorerFileTypeTest {
String[] extensions = fileType.getFilterExtensions();
assertNotNull(extensions);
assertEquals(1, extensions.length);
- assertEquals("*.csv", extensions[0]);
+ assertEquals("*.json", extensions[0]);
}
@Test
@@ -63,7 +63,7 @@ class CsvExplorerFileTypeTest {
String[] names = fileType.getFilterNames();
assertNotNull(names);
assertEquals(1, names.length);
- assertEquals("CSV files", names[0]);
+ assertEquals("JSON files", names[0]);
}
@Test
@@ -71,6 +71,11 @@ class CsvExplorerFileTypeTest {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE));
}
+ @Test
+ void testHasCapabilitySaveAs() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE_AS));
+ }
+
@Test
void testHasCapabilityClose() {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_CLOSE));
@@ -82,13 +87,18 @@ class CsvExplorerFileTypeTest {
}
@Test
- void testDoesNotHaveCapabilityCopy() {
- assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_COPY));
+ void testHasCapabilityCopy() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_COPY));
+ }
+
+ @Test
+ void testHasCapabilitySelect() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SELECT));
}
@Test
- void testDoesNotHaveCapabilitySelect() {
- assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_SELECT));
+ void testDoesNotHaveCapabilityStart() {
+ assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_START));
}
@Test
@@ -117,13 +127,13 @@ class CsvExplorerFileTypeTest {
@Test
void testGetCapabilities() {
assertNotNull(fileType.getCapabilities());
- assertTrue(fileType.getCapabilities().size() > 0);
+ assertFalse(fileType.getCapabilities().isEmpty());
}
@Test
- void testFileTypeIsForCsvFiles() {
- assertTrue(fileType.getDefaultFileExtension().endsWith(".csv"));
- assertTrue(fileType.getFilterExtensions()[0].contains("csv"));
- assertTrue(fileType.getFilterNames()[0].toLowerCase().contains("csv"));
+ void testFileTypeIsForJsonFiles() {
+ assertTrue(fileType.getDefaultFileExtension().endsWith(".json"));
+ assertTrue(fileType.getFilterExtensions()[0].contains("json"));
+ assertTrue(fileType.getFilterNames()[0].toLowerCase().contains("json"));
}
}
diff --git
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileType.java
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileType.java
index 844c207dfa..0e6170ca53 100644
---
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileType.java
+++
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileType.java
@@ -44,8 +44,11 @@ public class CsvExplorerFileType extends
BaseTextExplorerFileType<TextExplorerFi
new String[] {"CSV files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
- IHopFileType.CAPABILITY_FILE_HISTORY));
+ IHopFileType.CAPABILITY_FILE_HISTORY,
+ IHopFileType.CAPABILITY_COPY,
+ IHopFileType.CAPABILITY_SELECT));
}
@Override
diff --git
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileType.java
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileType.java
index 4166c3c4b4..4f26c0bd75 100644
---
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileType.java
+++
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileType.java
@@ -45,6 +45,7 @@ public class MarkDownExplorerFileType
new String[] {"MarkDown files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
IHopFileType.CAPABILITY_FILE_HISTORY,
IHopFileType.CAPABILITY_COPY,
diff --git
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileType.java
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileType.java
index 568e70ab6a..094a47ebc2 100644
---
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileType.java
+++
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileType.java
@@ -44,6 +44,7 @@ public class TextExplorerFileType extends
BaseTextExplorerFileType<TextExplorerF
new String[] {"TXT files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
IHopFileType.CAPABILITY_FILE_HISTORY,
IHopFileType.CAPABILITY_COPY,
diff --git
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
index bb972423e3..1e0d648b5a 100644
---
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
+++
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/CsvExplorerFileTypeTest.java
@@ -71,6 +71,11 @@ class CsvExplorerFileTypeTest {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE));
}
+ @Test
+ void testHasCapabilitySaveAs() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE_AS));
+ }
+
@Test
void testHasCapabilityClose() {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_CLOSE));
@@ -82,13 +87,18 @@ class CsvExplorerFileTypeTest {
}
@Test
- void testDoesNotHaveCapabilityCopy() {
- assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_COPY));
+ void testHasCapabilityCopy() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_COPY));
+ }
+
+ @Test
+ void testHasCapabilitySelect() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SELECT));
}
@Test
- void testDoesNotHaveCapabilitySelect() {
- assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_SELECT));
+ void testDoesNotHaveCapabilityStart() {
+ assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_START));
}
@Test
@@ -117,7 +127,7 @@ class CsvExplorerFileTypeTest {
@Test
void testGetCapabilities() {
assertNotNull(fileType.getCapabilities());
- assertTrue(fileType.getCapabilities().size() > 0);
+ assertFalse(fileType.getCapabilities().isEmpty());
}
@Test
diff --git
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileTypeTest.java
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileTypeTest.java
index 67c2ebb09f..a7777899b2 100644
---
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileTypeTest.java
+++
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/MarkDownExplorerFileTypeTest.java
@@ -71,6 +71,11 @@ class MarkDownExplorerFileTypeTest {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE));
}
+ @Test
+ void testHasCapabilitySaveAs() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE_AS));
+ }
+
@Test
void testHasCapabilityClose() {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_CLOSE));
@@ -91,6 +96,11 @@ class MarkDownExplorerFileTypeTest {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SELECT));
}
+ @Test
+ void testDoesNotHaveCapabilityStart() {
+ assertFalse(fileType.hasCapability(IHopFileType.CAPABILITY_START));
+ }
+
@Test
void testMultipleFilterExtensions() {
String[] extensions = fileType.getFilterExtensions();
@@ -117,7 +127,7 @@ class MarkDownExplorerFileTypeTest {
@Test
void testGetCapabilities() {
assertNotNull(fileType.getCapabilities());
- assertTrue(fileType.getCapabilities().size() > 0);
+ assertFalse(fileType.getCapabilities().isEmpty());
}
@Test
diff --git
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileTypeTest.java
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileTypeTest.java
index dac01b6eda..68defea278 100644
---
a/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileTypeTest.java
+++
b/plugins/transforms/textfile/src/test/java/org/apache/hop/pipeline/transforms/types/TextExplorerFileTypeTest.java
@@ -71,6 +71,11 @@ class TextExplorerFileTypeTest {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE));
}
+ @Test
+ void testHasCapabilitySaveAs() {
+ assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_SAVE_AS));
+ }
+
@Test
void testHasCapabilityClose() {
assertTrue(fileType.hasCapability(IHopFileType.CAPABILITY_CLOSE));
diff --git
a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/types/XmlExplorerFileType.java
b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/types/XmlExplorerFileType.java
index d8cdc0e24f..95a47259e2 100644
---
a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/types/XmlExplorerFileType.java
+++
b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/types/XmlExplorerFileType.java
@@ -44,6 +44,7 @@ public class XmlExplorerFileType extends
BaseTextExplorerFileType<XmlExplorerFil
new String[] {"XML files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
IHopFileType.CAPABILITY_FILE_HISTORY,
IHopFileType.CAPABILITY_COPY,
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/base/BaseExplorerFileTypeHandler.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/base/BaseExplorerFileTypeHandler.java
index 35a7d7c82a..db49b6665e 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/base/BaseExplorerFileTypeHandler.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/base/BaseExplorerFileTypeHandler.java
@@ -168,8 +168,11 @@ public abstract class BaseExplorerFileTypeHandler
implements IExplorerFileTypeHa
hopGui
.getDisplay()
.asyncExec(
- () ->
- hopGui.handleFileCapabilities(this.getFileType(),
this.hasChanged(), false, false));
+ () -> {
+ hopGui.handleFileCapabilities(this.getFileType(),
this.hasChanged(), false, false);
+ perspective.updateTabItem(this);
+ perspective.updateTreeItem(this);
+ });
}
@Override
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/log/LogExplorerFileType.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/log/LogExplorerFileType.java
index 340f46b716..4a9e8d19d3 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/log/LogExplorerFileType.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/log/LogExplorerFileType.java
@@ -44,6 +44,7 @@ public class LogExplorerFileType extends
BaseTextExplorerFileType<LogExplorerFil
new String[] {"Log files"},
FileTypeCapabilities.getCapabilities(
IHopFileType.CAPABILITY_SAVE,
+ IHopFileType.CAPABILITY_SAVE_AS,
IHopFileType.CAPABILITY_CLOSE,
IHopFileType.CAPABILITY_FILE_HISTORY,
IHopFileType.CAPABILITY_COPY,
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/text/BaseTextExplorerFileTypeHandler.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/text/BaseTextExplorerFileTypeHandler.java
index f9811cc930..b3497659b0 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/text/BaseTextExplorerFileTypeHandler.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/file/types/text/BaseTextExplorerFileTypeHandler.java
@@ -19,12 +19,14 @@ package
org.apache.hop.ui.hopgui.perspective.explorer.file.types.text;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import org.apache.commons.vfs2.FileObject;
import org.apache.hop.core.Const;
import org.apache.hop.core.Props;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.logging.LogChannel;
import org.apache.hop.core.vfs.HopVfs;
import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.dialog.MessageBox;
import org.apache.hop.ui.hopgui.HopGui;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerFile;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
@@ -97,8 +99,8 @@ public class BaseTextExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
this.clearChanged();
- // Update menu options
- perspective.updateGui();
+ // Update menu options, tab and tree item
+ updateGui();
// If we create a new file, refresh the explorer perspective tree
if (!fileExist) {
@@ -109,6 +111,39 @@ public class BaseTextExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
}
}
+ @Override
+ public void saveAs(String filename) throws HopException {
+ try {
+
+ // Enforce file extension
+ if
(!filename.toLowerCase().endsWith(this.getFileType().getDefaultFileExtension()))
{
+ filename = filename + this.getFileType().getDefaultFileExtension();
+ }
+
+ // Normalize file name
+ filename = HopVfs.normalize(filename);
+
+ FileObject fileObject = HopVfs.getFileObject(filename);
+ if (fileObject.exists()) {
+ MessageBox box =
+ new MessageBox(hopGui.getActiveShell(), SWT.YES | SWT.NO |
SWT.ICON_QUESTION);
+ box.setText("Overwrite?");
+ box.setMessage("Are you sure you want to overwrite file '" + filename
+ "'?");
+ int answer = box.open();
+ if ((answer & SWT.YES) == 0) {
+ return;
+ }
+ }
+
+ setFilename(filename);
+
+ save();
+ hopGui.fileRefreshDelegate.register(filename, this);
+ } catch (Exception e) {
+ throw new HopException("Error validating file existence for '" +
filename + "'", e);
+ }
+ }
+
@Override
public void reload() {
try {