Skip to content

Commit 5ba6179

Browse files
authored
Merge pull request #1167 from amottier/fix-delete-extension-folder-on-removal-nio
Attempt of using `java.nio.file` for extension removal
2 parents 11f2322 + 2c98a7a commit 5ba6179

File tree

1 file changed

+56
-4
lines changed
  • xwiki-commons-core/xwiki-commons-extension/xwiki-commons-extension-api/src/main/java/org/xwiki/extension/repository/internal/local

1 file changed

+56
-4
lines changed

xwiki-commons-core/xwiki-commons-extension/xwiki-commons-extension-api/src/main/java/org/xwiki/extension/repository/internal/local/LocalExtensionStorage.java

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@
2424
import java.io.FileNotFoundException;
2525
import java.io.FileOutputStream;
2626
import java.io.IOException;
27+
import java.nio.file.DirectoryNotEmptyException;
28+
import java.nio.file.Files;
29+
import java.nio.file.Path;
2730

2831
import javax.xml.parsers.ParserConfigurationException;
2932
import javax.xml.transform.TransformerException;
3033

3134
import org.apache.commons.lang3.StringUtils;
35+
import org.apache.commons.lang3.exception.ExceptionUtils;
3236
import org.slf4j.Logger;
3337
import org.slf4j.LoggerFactory;
3438
import org.xwiki.component.manager.ComponentLookupException;
@@ -101,7 +105,7 @@ public File getRootFolder()
101105

102106
/**
103107
* Load extension from repository storage.
104-
*
108+
*
105109
* @throws IOException when failing to load extensions
106110
*/
107111
protected void loadExtensions() throws IOException
@@ -296,15 +300,63 @@ public void removeExtension(DefaultLocalExtension extension) throws IOException
296300
File descriptorFile = extension.getDescriptorFile();
297301

298302
if (descriptorFile == null) {
299-
throw new IOException("Exception does not exist");
303+
throw new IOException(
304+
String.format("Extension [%s] does not exist: descriptor file is null", extension.getId().getId()));
300305
}
301306

302-
descriptorFile.delete();
307+
// Get extension file descriptor path
308+
Path extensionDescriptorFilePath = descriptorFile.toPath();
309+
310+
// Delete the extension descriptor file
311+
try {
312+
Files.delete(extensionDescriptorFilePath);
313+
} catch (FileNotFoundException e) {
314+
LOGGER.warn(
315+
"Couldn't delete the extension descriptor file [{}] when removing extension [{}], "
316+
+ "because it doesn't exist. Root error: [{}]",
317+
descriptorFile.getAbsolutePath(), extension.getId().getId(), ExceptionUtils.getRootCauseMessage(e));
318+
}
303319

304320
DefaultLocalExtensionFile extensionFile = extension.getFile();
305321

306322
if (extensionFile != null) {
307-
extensionFile.getFile().delete();
323+
// Delete the extension file
324+
try {
325+
Files.delete(extensionFile.getFile().toPath());
326+
} catch (FileNotFoundException e) {
327+
LOGGER.warn("Extension file [{}] was not found while removing [{}] extension",
328+
extensionFile.getAbsolutePath(), extension.getId().getId());
329+
}
330+
}
331+
332+
// Get the path to the folder that store the version of the extension being removed
333+
Path extensionVersionFolderPath = extensionDescriptorFilePath.getParent();
334+
try {
335+
// Delete the extension version folder
336+
Files.delete(extensionDescriptorFilePath);
337+
338+
// Try to delete the extension folder
339+
deleteExtensionFolderIfEmpty(extensionVersionFolderPath.getParent());
340+
} catch (DirectoryNotEmptyException e) {
341+
LOGGER.warn("Extension version folder [{}] was not empty after removing the extension [{}]. Keeping it.",
342+
extensionDescriptorFilePath, extension.getId().getId());
343+
}
344+
}
345+
346+
/**
347+
* Try to delete the extension folder if empty (i.e. all versions have been removed)
348+
*
349+
* @param extensionFolderPath the path to the folder to delete
350+
* @throws IOException error (other than empty) when deleting the extension folder
351+
*/
352+
private static void deleteExtensionFolderIfEmpty(Path extensionFolderPath) throws IOException
353+
{
354+
try {
355+
Files.delete(extensionFolderPath);
356+
} catch (DirectoryNotEmptyException e) {
357+
// Folder not being empty is a valid scenario if some version of the extension are still installed
358+
LOGGER.debug("Extension folder [{}] was not empty after removing the extension. Keeping it.",
359+
extensionFolderPath);
308360
}
309361

310362
// Delete extension version folder if empty

0 commit comments

Comments
 (0)