AddonUninstallService.groovy
/*
* Copyright (C) 2003-2014 eXo Platform SAS.
*
* This file is part of eXo Platform - Add-ons Manager.
*
* eXo Platform - Add-ons Manager is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* eXo Platform - Add-ons Manager software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with eXo Platform - Add-ons Manager; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see <http://www.gnu.org/licenses/>.
*/
package org.exoplatform.platform.am
import groovy.util.slurpersupport.GPathResult
import org.exoplatform.platform.am.cli.CommandLineParameters
import org.exoplatform.platform.am.ex.AddonNotInstalledException
import org.exoplatform.platform.am.settings.EnvironmentSettings
import org.exoplatform.platform.am.utils.FileUtils
import org.exoplatform.platform.am.utils.Logger
import static org.exoplatform.platform.am.utils.FileUtils.copyFile
/**
* All services to install add-ons
*
* @author Arnaud Héritier <aheritier@exoplatform.com>
*/
public class AddonUninstallService {
/**
* Logger
*/
private static final Logger LOG = Logger.getInstance()
/**
* Add-on Services
*/
private static final AddonService ADDON_SERVICE = AddonService.getInstance()
/**
* Singleton
*/
private static final AddonUninstallService singleton = new AddonUninstallService()
/**
* Factory
*
* @return The {@link AddonUninstallService} singleton instance
*/
static AddonUninstallService getInstance() {
return singleton
}
/**
* You should use the singleton
*/
private AddonUninstallService() {
}
/**
* Uninstall an add-on given the current environment {@code env} and command line {@code parameters}.
* @param env The execution environment
* @param parameters Command line parameters for an uninstall action
*/
void uninstallAddon(
EnvironmentSettings env,
CommandLineParameters.UninstallCommandParameters parameters) {
File statusFile = ADDON_SERVICE.getAddonStatusFile(env.statusesDirectory, parameters.addonId)
if (statusFile.exists()) {
Addon addon
LOG.withStatus("Loading add-on installation details") {
addon = ADDON_SERVICE.createAddonFromJsonText(statusFile.text);
}
uninstallAddon(env, addon)
} else {
throw new AddonNotInstalledException("The add-on ${parameters.addonId} was not installed")
}
}
/**
* Uninstall the @{code addon} from the current @{code env}.
* @param env The environment where the add-on must be uninstalled
* @param addon The add-on to remove
*/
protected void uninstallAddon(
EnvironmentSettings env,
Addon addon) {
LOG.info("Uninstalling @|yellow ${addon.id}:${addon.version}|@")
addon.installedLibraries.each {
library ->
File fileToDelete = new File(env.platform.librariesDirectory, FileUtils.extractFilename(library))
if (!fileToDelete.exists()) {
LOG.warn("No library ${fileToDelete} to delete")
} else {
LOG.withStatus("Deleting library ${fileToDelete}") {
fileToDelete.delete()
assert !fileToDelete.exists()
}
}
}
// Update application.xml if it exists
File applicationDescriptorFile = new File(env.platform.webappsDirectory, "META-INF/application.xml")
addon.installedWebapps.each {
webapp ->
String contextRoot = webapp.substring(webapp.lastIndexOf('/')+1, webapp.length() - 4)
String webUri = webapp.substring(webapp.lastIndexOf('/')+1, webapp.length())
File fileToDelete = new File(env.platform.webappsDirectory, FileUtils.extractFilename(webapp))
if (!fileToDelete.exists()) {
LOG.warn("No web application ${fileToDelete} to delete")
} else {
LOG.withStatus("Deleting web application ${fileToDelete}") {
fileToDelete.delete()
assert !fileToDelete.exists()
}
}
// AM-119: delete unzipped war folder
File folderToDelete = new File(fileToDelete.getPath().substring(0, fileToDelete.getPath().length() - 4))
if (folderToDelete.isDirectory()) {
LOG.withStatus("Deleting web application folder ${folderToDelete}") {
folderToDelete.deleteDir()
assert !folderToDelete.exists()
}
}
if (applicationDescriptorFile.exists()) {
LOG.withStatus("Removing context declaration /${contextRoot} for ${webUri} in application.xml") {
ADDON_SERVICE.processFileInplace(applicationDescriptorFile) { text ->
GPathResult applicationXmlContent = new XmlSlurper(false, false).parseText(text)
applicationXmlContent.depthFirst().findAll {
(it.name() == 'module') && (it.'web'.'web-uri'.text() == webUri)
}.each { node ->
// remove existing node
node.replaceNode {}
}
ADDON_SERVICE.serializeXml(applicationXmlContent)
}
}
}
}
addon.installedProperties.each {
propFile ->
File fileToDelete = new File(env.platform.propertiesDirectory, propFile)
if (!fileToDelete.exists()) {
LOG.warn("No ${fileToDelete} to delete")
} else {
LOG.withStatus("Deleting properties file ${fileToDelete}") {
fileToDelete.delete()
assert !fileToDelete.exists()
}
File parentDirectory = fileToDelete.parentFile
while (parentDirectory.isDirectory() && !parentDirectory.list()) {
LOG.withStatus(
"Deleting empty directory ${parentDirectory.toURI().getPath()}") {
parentDirectory.delete()
}
parentDirectory = parentDirectory.parentFile
}
}
}
addon.installedOthersFiles.each {
otherFile ->
File fileToDelete = new File(env.platform.homeDirectory, otherFile)
if (!fileToDelete.exists()) {
LOG.warn("No file ${otherFile} to delete")
} else {
LOG.withStatus("Deleting file ${otherFile}") {
fileToDelete.delete()
assert !fileToDelete.exists()
}
File parentDirectory = fileToDelete.parentFile
while (parentDirectory.isDirectory() && !parentDirectory.list()) {
LOG.withStatus(
"Deleting empty directory ${parentDirectory.toURI().getPath()}") {
parentDirectory.delete()
}
parentDirectory = parentDirectory.parentFile
}
}
}
// Restore overwritten files
addon.overwrittenFiles.each {
fileToRecover ->
File backupFile = new File(env.overwrittenFilesDirectory, "${addon.id}/${fileToRecover}")
File originalFile
if (fileToRecover ==~ /^.*jar$/) {
// jar files
originalFile = new File(env.platform.librariesDirectory, FileUtils.extractFilename(fileToRecover))
} else if (fileToRecover ==~ /^.*war$/) {
// war files
originalFile = new File(env.platform.webappsDirectory, FileUtils.extractFilename(fileToRecover))
} else if (fileToRecover ==~ /^.*properties$/) {
// properties files
originalFile = new File(env.platform.propertiesDirectory, fileToRecover)
} else {
// other files
originalFile = new File(env.platform.homeDirectory, fileToRecover)
}
copyFile("Reinstalling original file ${fileToRecover}", backupFile, originalFile)
LOG.withStatus("Deleting backup file of ${fileToRecover}") {
backupFile.delete()
}
LOG.warn("File ${fileToRecover} has been restored")
}
LOG.withStatus("Deleting installation details ${ADDON_SERVICE.getAddonStatusFile(env.statusesDirectory, addon).name}") {
ADDON_SERVICE.getAddonStatusFile(env.statusesDirectory, addon).delete()
assert !ADDON_SERVICE.getAddonStatusFile(env.statusesDirectory, addon).exists()
}
LOG.withStatusOK("Add-on ${addon.id}:${addon.version} uninstalled")
}
}