Skip to content

Commit b30f10a

Browse files
ctruedenclaude
andcommitted
Fix LinuxSchemeInstaller desktop file handling
The scijava.app.desktop-file property should not need to be set. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a3db9e5 commit b30f10a

File tree

3 files changed

+33
-68
lines changed

3 files changed

+33
-68
lines changed

src/main/java/org/scijava/desktop/platform/linux/LinuxPlatform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public void setFileExtensionsEnabled(final boolean enable) throws IOException {
284284

285285
@Override
286286
public SchemeInstaller getSchemeInstaller() {
287-
return new LinuxSchemeInstaller(log);
287+
return new LinuxSchemeInstaller(getDesktopFilePath(), log);
288288
}
289289

290290
// -- Helper methods --

src/main/java/org/scijava/desktop/platform/linux/LinuxSchemeInstaller.java

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@
3838
import java.nio.charset.StandardCharsets;
3939
import java.nio.file.Files;
4040
import java.nio.file.Path;
41-
import java.nio.file.Paths;
4241
import java.util.concurrent.TimeUnit;
4342

4443
/**
4544
* Linux implementation of {@link SchemeInstaller} using .desktop files.
4645
* <p>
47-
* This implementation modifies the .desktop file specified by the
48-
* {@code scijava.app.desktop-file} system property to add URI scheme
49-
* handlers via the MimeType field, then registers them using xdg-mime.
46+
* This implementation modifies the application's .desktop file to add URI
47+
* scheme handlers via the MimeType field, then registers them using xdg-mime.
5048
* </p>
5149
*
5250
* @author Curtis Rueden
@@ -55,9 +53,11 @@ public class LinuxSchemeInstaller implements SchemeInstaller {
5553

5654
private static final long COMMAND_TIMEOUT_SECONDS = 10;
5755

56+
private final Path desktopFilePath;
5857
private final LogService log;
5958

60-
public LinuxSchemeInstaller(final LogService log) {
59+
public LinuxSchemeInstaller(final Path desktopFilePath, final LogService log) {
60+
this.desktopFilePath = desktopFilePath;
6161
this.log = log;
6262
}
6363

@@ -78,65 +78,53 @@ public void install(final String scheme, final String executablePath) throws IOE
7878
throw new IllegalArgumentException("Scheme cannot be null or empty");
7979
}
8080

81-
// Get desktop file path from system property
82-
final String desktopFileProp = System.getProperty("scijava.app.desktop-file");
83-
if (desktopFileProp == null || desktopFileProp.isEmpty()) {
84-
throw new IOException("scijava.app.desktop-file property not set");
85-
}
86-
87-
final Path desktopFile = Paths.get(desktopFileProp);
88-
if (!Files.exists(desktopFile)) {
89-
throw new IOException("Desktop file does not exist: " + desktopFile);
81+
if (!Files.exists(desktopFilePath)) {
82+
throw new IOException("Desktop file does not exist: " + desktopFilePath);
9083
}
9184

9285
// Parse desktop file
93-
final DesktopFile df = DesktopFile.parse(desktopFile);
86+
final DesktopFile df = DesktopFile.parse(desktopFilePath);
9487

9588
// Check if scheme already registered
9689
final String mimeType = "x-scheme-handler/" + scheme;
9790
if (df.hasMimeType(mimeType)) {
98-
if (log != null) log.debug("Scheme '" + scheme + "' already registered in: " + desktopFile);
91+
if (log != null) log.debug("Scheme '" + scheme + "' already registered in: " + desktopFilePath);
9992
return;
10093
}
10194

10295
// Add MIME type
10396
df.addMimeType(mimeType);
10497

10598
// Write back to file
106-
df.writeTo(desktopFile);
99+
df.writeTo(desktopFilePath);
107100

108101
// Register with xdg-mime
109-
final String desktopFileName = desktopFile.getFileName().toString();
102+
final String desktopFileName = desktopFilePath.getFileName().toString();
110103
if (!executeCommand(new String[]{"xdg-mime", "default", desktopFileName, mimeType})) {
111104
throw new IOException("Failed to register scheme with xdg-mime: " + scheme);
112105
}
113106

114107
// Update desktop database
115-
final Path applicationsDir = desktopFile.getParent();
108+
final Path applicationsDir = desktopFilePath.getParent();
116109
if (applicationsDir != null) {
117110
executeCommand(new String[]{"update-desktop-database", applicationsDir.toString()});
118111
// Note: update-desktop-database may fail if not installed, but this is non-critical
119112
}
120113

121-
if (log != null) log.info("Registered URI scheme '" + scheme + "' in: " + desktopFile);
114+
if (log != null) log.info("Registered URI scheme '" + scheme + "' in: " + desktopFilePath);
122115
}
123116

124117
@Override
125118
public boolean isInstalled(final String scheme) {
126119
if (!isSupported()) return false;
127-
128-
final String desktopFileProp = System.getProperty("scijava.app.desktop-file");
129-
if (desktopFileProp == null) return false;
130-
131-
final Path desktopFile = Paths.get(desktopFileProp);
132-
if (!Files.exists(desktopFile)) return false;
120+
if (!Files.exists(desktopFilePath)) return false;
133121

134122
try {
135-
final DesktopFile df = DesktopFile.parse(desktopFile);
123+
final DesktopFile df = DesktopFile.parse(desktopFilePath);
136124
return df.hasMimeType("x-scheme-handler/" + scheme);
137125
}
138126
catch (final IOException e) {
139-
if (log != null) log.debug("Failed to parse desktop file: " + desktopFile, e);
127+
if (log != null) log.debug("Failed to parse desktop file: " + desktopFilePath, e);
140128
return false;
141129
}
142130
}
@@ -145,13 +133,8 @@ public boolean isInstalled(final String scheme) {
145133
public String getInstalledPath(final String scheme) {
146134
if (!isInstalled(scheme)) return null;
147135

148-
final String desktopFileProp = System.getProperty("scijava.app.desktop-file");
149-
if (desktopFileProp == null) return null;
150-
151-
final Path desktopFile = Paths.get(desktopFileProp);
152-
153136
try {
154-
final DesktopFile df = DesktopFile.parse(desktopFile);
137+
final DesktopFile df = DesktopFile.parse(desktopFilePath);
155138
final String exec = df.get("Exec");
156139
if (exec == null) return null;
157140

@@ -162,7 +145,7 @@ public String getInstalledPath(final String scheme) {
162145
}
163146
}
164147
catch (final IOException e) {
165-
if (log != null) log.debug("Failed to parse desktop file: " + desktopFile, e);
148+
if (log != null) log.debug("Failed to parse desktop file: " + desktopFilePath, e);
166149
}
167150

168151
return null;
@@ -179,16 +162,13 @@ public void uninstall(final String scheme) throws IOException {
179162
return;
180163
}
181164

182-
final String desktopFileProp = System.getProperty("scijava.app.desktop-file");
183-
final Path desktopFile = Paths.get(desktopFileProp);
184-
185165
// Parse and remove MIME type
186-
final DesktopFile df = DesktopFile.parse(desktopFile);
166+
final DesktopFile df = DesktopFile.parse(desktopFilePath);
187167
df.removeMimeType("x-scheme-handler/" + scheme);
188-
df.writeTo(desktopFile);
168+
df.writeTo(desktopFilePath);
189169

190170
// Update desktop database
191-
final Path applicationsDir = desktopFile.getParent();
171+
final Path applicationsDir = desktopFilePath.getParent();
192172
if (applicationsDir != null) {
193173
executeCommand(new String[]{"update-desktop-database", applicationsDir.toString()});
194174
}

src/test/java/org/scijava/desktop/platform/linux/LinuxSchemeInstallerTest.java

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.io.IOException;
3838
import java.nio.file.Files;
3939
import java.nio.file.Path;
40+
import java.nio.file.Paths;
4041

4142
import static org.junit.Assert.*;
4243

@@ -50,13 +51,12 @@ public class LinuxSchemeInstallerTest {
5051
private static final String TEST_SCHEME = "scijava-test";
5152
private LinuxSchemeInstaller installer;
5253
private Path tempDesktopFile;
53-
private String originalProperty;
5454

5555
@Before
5656
public void setUp() throws IOException {
57-
installer = new LinuxSchemeInstaller(null);
5857
// Only run tests on Linux
59-
Assume.assumeTrue("Tests only run on Linux", installer.isSupported());
58+
Assume.assumeTrue("Tests only run on Linux",
59+
System.getProperty("os.name", "").toLowerCase().contains("linux"));
6060

6161
// Create temporary desktop file
6262
tempDesktopFile = Files.createTempFile("test-app", ".desktop");
@@ -68,22 +68,11 @@ public void setUp() throws IOException {
6868
df.set("Exec", "/usr/bin/test-app %U");
6969
df.save();
7070

71-
// Set system property
72-
originalProperty = System.getProperty("scijava.app.desktop-file");
73-
System.setProperty("scijava.app.desktop-file", tempDesktopFile.toString());
71+
installer = new LinuxSchemeInstaller(tempDesktopFile, null);
7472
}
7573

7674
@After
7775
public void tearDown() throws IOException {
78-
// Restore original property
79-
if (originalProperty != null) {
80-
System.setProperty("scijava.app.desktop-file", originalProperty);
81-
}
82-
else {
83-
System.clearProperty("scijava.app.desktop-file");
84-
}
85-
86-
// Clean up temp file
8776
if (tempDesktopFile != null && Files.exists(tempDesktopFile)) {
8877
Files.delete(tempDesktopFile);
8978
}
@@ -159,12 +148,10 @@ public void testInstallTwice() throws IOException {
159148

160149
@Test
161150
public void testIsInstalledReturnsFalseWhenFileDoesNotExist() {
162-
// Arrange
163-
System.setProperty("scijava.app.desktop-file", "/nonexistent/path/app.desktop");
164-
165-
// Act & Assert
151+
final LinuxSchemeInstaller nonExistent =
152+
new LinuxSchemeInstaller(Paths.get("/nonexistent/path/app.desktop"), null);
166153
assertFalse("Should return false when desktop file doesn't exist",
167-
installer.isInstalled(TEST_SCHEME));
154+
nonExistent.isInstalled(TEST_SCHEME));
168155
}
169156

170157
@Test
@@ -197,12 +184,10 @@ public void testInstallWithEmptyScheme() throws IOException {
197184
}
198185

199186
@Test(expected = IOException.class)
200-
public void testInstallWithoutDesktopFileProperty() throws IOException {
201-
// Arrange
202-
System.clearProperty("scijava.app.desktop-file");
203-
204-
// Act
205-
installer.install(TEST_SCHEME, "/usr/bin/test-app");
187+
public void testInstallWhenDesktopFileDoesNotExist() throws IOException {
188+
final LinuxSchemeInstaller nonExistent =
189+
new LinuxSchemeInstaller(Paths.get("/nonexistent/path/app.desktop"), null);
190+
nonExistent.install(TEST_SCHEME, "/usr/bin/test-app");
206191
}
207192

208193
@Test

0 commit comments

Comments
 (0)