/*
* Copyright (C) 2007 Rob Manning
* manningr@users.sourceforge.net
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.sourceforge.squirrel_sql.client.update.gui.installer;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import net.sourceforge.squirrel_sql.client.update.UpdateUtil;
import net.sourceforge.squirrel_sql.client.update.gui.ArtifactAction;
import net.sourceforge.squirrel_sql.client.update.gui.ArtifactStatus;
import net.sourceforge.squirrel_sql.client.update.gui.installer.event.InstallEventType;
import net.sourceforge.squirrel_sql.client.update.gui.installer.event.InstallStatusEvent;
import net.sourceforge.squirrel_sql.client.update.gui.installer.event.InstallStatusEventFactory;
import net.sourceforge.squirrel_sql.client.update.gui.installer.event.InstallStatusListener;
import net.sourceforge.squirrel_sql.client.update.gui.installer.util.InstallFileOperationInfo;
import net.sourceforge.squirrel_sql.client.update.gui.installer.util.InstallFileOperationInfoFactory;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ChangeListXmlBean;
import net.sourceforge.squirrel_sql.fw.util.FileWrapper;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
/**
* This class is used by the PreLaunchUpdateApplication to install artifact files that belong to a particular
* change list.
*
* @author manningr
*/
public class ArtifactInstallerImpl implements ArtifactInstaller
{
/** Logger for this class. */
private static ILogger s_log = LoggerController.createLogger(ArtifactInstallerImpl.class);
/**
* this list is derived from the changelist xmlbean. It will only contain the artifacts that need to be
* change (installed, removed).
*/
private List<ArtifactStatus> _changeList = null;
/** listeners to notify of important install events */
private List<InstallStatusListener> _listeners = new ArrayList<InstallStatusListener>();
/**
* the top-level directory beneath which reside all files needed for updating the application (e.g.
* /opt/squirrel/update)
*/
private FileWrapper updateDir = null;
// Download directories
/** the downlaods root directory (e.g. /opt/squirrel/update/downloads) */
private FileWrapper downloadsRootDir = null;
/** the core sub-directory of the backup directory (e.g. /opt/squirrel/update/downloads/core) */
private FileWrapper coreDownloadsDir = null;
/** the plugin sub-directory of the backup directory (e.g. /opt/squirrel/update/downloads/plugin) */
private FileWrapper pluginDownloadsDir = null;
/** the i18n sub-directory of the backup directory (e.g. /opt/squirrel/update/downloads/i18n) */
private FileWrapper i18nDownloadsDir = null;
// Backup directories
/** the backup directory (e.g. /opt/squirrel/update/backup) */
private FileWrapper backupRootDir = null;
/** the core sub-directory of the backup directory (e.g. /opt/squirrel/update/backup/core) */
private FileWrapper coreBackupDir = null;
/** the plugin sub-directory of the backup directory (e.g. /opt/squirrel/update/backup/plugin) */
private FileWrapper pluginBackupDir = null;
/** the i18n sub-directory of the backup directory (e.g. /opt/squirrel/update/backup/i18n) */
private FileWrapper translationBackupDir = null;
// Install directories
/** the top-level SQuirreL installation direction where launch scripts are (e.g. /opt/squirrel) */
private FileWrapper installRootDir = null;
/** the lib directory where most core jars are (e.g. /opt/squirrel/lib) */
private FileWrapper coreInstallDir = null;
/** the plugins directory where all of the plugin files are (e.g. /opt/squirrel/plugins) */
private FileWrapper pluginInstallDir = null;
/** the lib directory where translation jars are (e.g. /opt/squirrel/lib) */
private FileWrapper i18nInstallDir = null;
/**
* the file that was used to build a ChangeListXmlBean that we are using to determine which files need to
* be installed/removed
*/
private FileWrapper changeListFile = null;
/* Spring-injected dependencies */
/** Spring-injected factory for creating install events */
private InstallStatusEventFactory installStatusEventFactory = null;
public void setInstallStatusEventFactory(InstallStatusEventFactory installStatusEventFactory)
{
this.installStatusEventFactory = installStatusEventFactory;
}
/** Spring-injected factory for creating file operation infos */
private InstallFileOperationInfoFactory installFileOperationInfoFactory = null;
public void setInstallFileOperationInfoFactory(
InstallFileOperationInfoFactory installFileOperationInfoFactory)
{
this.installFileOperationInfoFactory = installFileOperationInfoFactory;
}
/** Utility which provides path information and abstraction to file operations */
private UpdateUtil _util = null;
public void setUpdateUtil(UpdateUtil util)
{
this._util = util;
updateDir = _util.getSquirrelUpdateDir();
backupRootDir = _util.checkDir(updateDir, UpdateUtil.BACKUP_ROOT_DIR_NAME);
downloadsRootDir = _util.checkDir(updateDir, UpdateUtil.DOWNLOADS_DIR_NAME);
coreBackupDir = _util.checkDir(backupRootDir, UpdateUtil.CORE_ARTIFACT_ID);
pluginBackupDir = _util.checkDir(backupRootDir, UpdateUtil.PLUGIN_ARTIFACT_ID);
translationBackupDir = _util.checkDir(backupRootDir, UpdateUtil.TRANSLATION_ARTIFACT_ID);
installRootDir = _util.getSquirrelHomeDir();
coreInstallDir = _util.getSquirrelLibraryDir();
pluginInstallDir = _util.getSquirrelPluginsDir();
i18nInstallDir = _util.getSquirrelLibraryDir();
coreDownloadsDir = _util.getCoreDownloadsDir();
pluginDownloadsDir = _util.getPluginDownloadsDir();
i18nDownloadsDir = _util.getI18nDownloadsDir();
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#setChangeList(net.sourceforge.squirrel_sql.client.update.xmlbeans.ChangeListXmlBean)
*/
public void setChangeList(ChangeListXmlBean changeList) throws FileNotFoundException
{
_changeList = initializeChangeList(changeList);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#getChangeListFile()
*/
public FileWrapper getChangeListFile()
{
return changeListFile;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#
* setChangeListFile(java.io.File)
*/
public void setChangeListFile(FileWrapper changeListFile)
{
this.changeListFile = changeListFile;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#
* addListener(net.sourceforge.squirrel_sql.client.update.gui.installer.event.InstallStatusListener)
*/
public void addListener(InstallStatusListener listener)
{
_listeners.add(listener);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#backupFiles()
*/
public boolean backupFiles() throws FileNotFoundException, IOException
{
boolean result = true;
sendBackupStarted(_changeList.size());
FileWrapper localReleaseFile = _util.getLocalReleaseFile();
_util.copyFile(localReleaseFile, _util.getBackupDir());
for (ArtifactStatus status : _changeList)
{
String artifactName = status.getName();
sendFileBackupStarted(artifactName);
// Skip files that are not installed - new files
if (!status.isInstalled())
{
if (s_log.isInfoEnabled())
{
s_log.info("Skipping backup of artifact (" + status + ") which isn't installed.");
}
sendFileBackupComplete(artifactName);
continue;
}
if (status.isCoreArtifact())
{
FileWrapper installDir = getCoreArtifactLocation(artifactName, installRootDir, coreInstallDir);
FileWrapper coreFile = _util.getFile(installDir, artifactName);
FileWrapper backupFile = _util.getFile(coreBackupDir, artifactName);
_util.copyFile(coreFile, backupFile);
}
if (status.isPluginArtifact())
{
// artifact name for plugins is <plugin internal name>.zip
FileWrapper pluginBackupFile = _util.getFile(pluginBackupDir, artifactName);
String pluginDirectory = artifactName.replace(".zip", "");
String pluginJarFilename = artifactName.replace(".zip", ".jar");
ArrayList<FileWrapper> filesToZip = new ArrayList<FileWrapper>();
FileWrapper pluginDirectoryFile = _util.getFile(pluginInstallDir, pluginDirectory);
if (pluginDirectoryFile.exists())
{
filesToZip.add(pluginDirectoryFile);
}
FileWrapper pluginJarFile = _util.getFile(pluginInstallDir, pluginJarFilename);
if (pluginJarFile.exists())
{
filesToZip.add(pluginJarFile);
}
if (filesToZip.size() > 0)
{
_util.createZipFile(pluginBackupFile, filesToZip.toArray(new FileWrapper[filesToZip.size()]));
}
else
{
s_log.error("Plugin (" + status.getName() + ") was listed as already installed, but it's "
+ "files didn't exist and couldn't be backed up: pluginDirectoryFile="
+ pluginDirectoryFile.getAbsolutePath() + " pluginJarFile="
+ pluginJarFile.getAbsolutePath());
}
}
if (status.isTranslationArtifact())
{
FileWrapper translationFile = _util.getFile(i18nInstallDir, artifactName);
FileWrapper backupFile = _util.getFile(translationBackupDir, artifactName);
if (translationFile.exists())
{
_util.copyFile(translationFile, backupFile);
}
}
breathing();
sendFileBackupComplete(artifactName);
}
sendBackupComplete();
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#installFiles()
*/
public void installFiles() throws IOException
{
List<FileWrapper> filesToRemove = new ArrayList<FileWrapper>();
List<InstallFileOperationInfo> filesToInstall = new ArrayList<InstallFileOperationInfo>();
for (ArtifactStatus status : _changeList)
{
ArtifactAction action = status.getArtifactAction();
FileWrapper installDir = null;
FileWrapper fileToCopy = null;
FileWrapper fileToRemove = null;
String artifactName = status.getName();
boolean isPlugin = false;
if (status.isCoreArtifact())
{
if (action == ArtifactAction.REMOVE)
{
s_log.error("Skipping core artifact (" + status.getName() + ") that was marked for removal");
continue;
}
installDir = getCoreArtifactLocation(status.getName(), installRootDir, coreInstallDir);
fileToCopy = _util.getFile(coreDownloadsDir, artifactName);
if (UpdateUtil.DOCS_ARCHIVE_FILENAME.equals(status.getName()))
{
fileToRemove = _util.getFile(installDir, artifactName.replace(".zip", ""));
}
else
{
fileToRemove = _util.getFile(installDir, artifactName);
}
filesToRemove.add(fileToRemove);
}
if (status.isPluginArtifact())
{
isPlugin = true;
installDir = pluginInstallDir;
if (action != ArtifactAction.REMOVE)
{
fileToCopy = _util.getFile(pluginDownloadsDir, artifactName);
}
// Need to remove the existing jar in the plugins directory and all of the files beneath the
// plugin-named directory.
String jarFileToRemove = artifactName.replace(".zip", ".jar");
String pluginDirectoryToRemove = artifactName.replace(".zip", "");
filesToRemove.add(_util.getFile(installDir, jarFileToRemove));
filesToRemove.add(_util.getFile(installDir, pluginDirectoryToRemove));
}
if (status.isTranslationArtifact())
{
installDir = i18nInstallDir;
if (action != ArtifactAction.REMOVE)
{
fileToCopy = _util.getFile(i18nDownloadsDir, artifactName);
}
fileToRemove = _util.getFile(installDir, artifactName);
filesToRemove.add(fileToRemove);
}
if (fileToCopy != null)
{
InstallFileOperationInfo info = installFileOperationInfoFactory.create(fileToCopy, installDir);
info.setPlugin(isPlugin);
info.setArtifactName(artifactName);
filesToInstall.add(info);
}
}
boolean success = removeOldFiles(filesToRemove);
success = success && installFiles(filesToInstall);
success = success && backupAndDeleteChangeListFile();
success = success && installNewReleaseXmlFile();
if (!success)
{
restoreFilesFromBackup(filesToInstall);
}
sendInstallComplete();
}
/**
* @see net.sourceforge.squirrel_sql.client.update.gui.installer.ArtifactInstaller#restoreBackupFiles(net.sourceforge.squirrel_sql.client.update.xmlbeans.ChangeListXmlBean)
*/
public boolean restoreBackupFiles() throws FileNotFoundException, IOException
{
for (ArtifactStatus status : _changeList)
{
String name = status.getName();
FileWrapper backupDir = null;
FileWrapper installDir = null;
if (status.isCoreArtifact())
{
backupDir = coreBackupDir;
installDir = getCoreArtifactLocation(name, installRootDir, coreInstallDir);
}
if (status.isPluginArtifact())
{
backupDir = pluginBackupDir;
installDir = pluginInstallDir;
}
if (status.isTranslationArtifact())
{
backupDir = translationBackupDir;
installDir = coreInstallDir; // translations are most likely to be found in core lib dir.
}
FileWrapper backupJarPath = _util.getFile(backupDir, name);
FileWrapper installJarPath = _util.getFile(installDir, name);
if (!_util.deleteFile(installJarPath))
{
return false;
}
else
{
_util.copyFile(backupJarPath, installJarPath);
}
}
if (!_util.deleteFile(_util.getLocalReleaseFile()))
{
return false;
}
else
{
FileWrapper backupReleaseFile = _util.getFile(_util.getBackupDir(), UpdateUtil.RELEASE_XML_FILENAME);
_util.copyFile(backupReleaseFile, updateDir);
}
return true;
}
// Helper methods
private void breathing()
{
// In case this is called by the AWT thread, log a message - this is most likey a bug
if (SwingUtilities.isEventDispatchThread())
{
if (s_log.isDebugEnabled())
{
s_log.debug("breathing: ignoring request to sleep the event dispatch thread");
}
return;
}
synchronized (this)
{
try
{
wait(50);
}
catch (InterruptedException e)
{
if (s_log.isInfoEnabled())
{
s_log.info("breathing: Interrupted", e);
}
}
}
}
/**
* Since it possible that some artifacts haven't changed between releases, and it is time-consuming to read
* the contents of the installed file to compute it's checksum, we do that here just once and boil the
* change list down to just those files that have physically changed, by comparing byte-size and checksum.
*/
private List<ArtifactStatus> initializeChangeList(ChangeListXmlBean changeListBean)
{
sendInitChangelistStarted(changeListBean.getChanges().size());
ArrayList<ArtifactStatus> result = new ArrayList<ArtifactStatus>();
for (ArtifactStatus status : changeListBean.getChanges())
{
String artifactName = status.getName();
sendFileInitChangelistStarted(artifactName);
// Always add plugins - there is not a good way to compare plugin zips and their extracted contents
// at the moment.
// TODO: Determine the best way to derive the filesize and checksum of the plugin zip that was last
// extracted. Should we keep it around? How about using the current release.xml file ? Come to
// think of it, perhaps we shouldn't be computing the checksum of *any* existing files, why don't
// we just get it from the current release.xml file?
if (status.isPluginArtifact())
{
result.add(status);
sendFileInitChangelistComplete(artifactName);
continue;
}
if (status.getArtifactAction() == ArtifactAction.INSTALL)
{
FileWrapper installedFileLocation = null;
// Skip the artifact if it is identical to the one that is already installed
if (status.isCoreArtifact())
{
installedFileLocation =
_util.getFile(getCoreArtifactLocation(status.getName(), installRootDir, coreInstallDir),
status.getName());
}
if (status.isTranslationArtifact())
{
installedFileLocation = _util.getFile(coreInstallDir, status.getName());
}
long installedSize = installedFileLocation.length();
if (installedSize == status.getSize())
{
long installedCheckSum = _util.getCheckSum(installedFileLocation);
if (installedCheckSum == status.getChecksum())
{
if (s_log.isDebugEnabled())
{
s_log.debug("initializeChangeList: found a core/translation artifact that is not "
+ "installed: installedSize= " + installedSize + " installedCheckSum="
+ installedCheckSum + " statusSize=" + status.getSize() + " statusChecksum="
+ status.getChecksum());
}
sendFileInitChangelistComplete(artifactName);
continue;
}
}
}
// We have a core or translation file that is not already installed - add it
result.add(status);
sendFileInitChangelistComplete(artifactName);
}
sendInitChangelistComplete();
return result;
}
/* Handle squirrel-sql.jar and documentation archive carefully - they live at the top */
private FileWrapper getCoreArtifactLocation(String artifactName, FileWrapper rootDir, FileWrapper coreDir)
{
if (UpdateUtil.SQUIRREL_SQL_JAR_FILENAME.equals(artifactName)
|| UpdateUtil.DOCS_ARCHIVE_FILENAME.equals(artifactName))
{
return rootDir;
}
else
{
return coreDir;
}
}
private void restoreFilesFromBackup(List<InstallFileOperationInfo> filesToInstall)
{
// TODO Auto-generated method stub
}
private boolean backupAndDeleteChangeListFile()
{
boolean result = true;
if (changeListFile != null)
{
try
{
_util.copyFile(changeListFile, backupRootDir);
result = _util.deleteFile(changeListFile);
}
catch (IOException e)
{
result = false;
s_log.error("Unexpected exception: " + e.getMessage(), e);
}
}
else
{
if (s_log.isInfoEnabled())
{
s_log.info("moveChangeListFile: Changelist file was null. Skipping move");
}
}
return result;
}
/**
* Install the downloaded release.xml file into the updates root directory so that the update knows the
* current release has changed.
*
* @return true if install was successful; false otherwise.
*/
private boolean installNewReleaseXmlFile()
{
boolean result = true;
try
{
_util.deleteFile(_util.getLocalReleaseFile());
}
catch (FileNotFoundException e)
{
// strange that release xml file wasn't found; but not a problem at this point - just log it.
if (s_log.isInfoEnabled())
{
s_log.info("installNewReleaseXmlFile: release file to be replaced was missing.");
}
}
FileWrapper downloadReleaseFile = _util.getFile(downloadsRootDir, UpdateUtil.RELEASE_XML_FILENAME);
try
{
_util.copyFile(downloadReleaseFile, updateDir);
}
catch (FileNotFoundException e)
{
result = false;
s_log.error("installNewReleaseXmlFile: unexpected exception - " + e.getMessage(), e);
}
catch (IOException e)
{
result = false;
s_log.error("installNewReleaseXmlFile: unexpected exception - " + e.getMessage(), e);
}
return result;
}
/**
* Removes the specified list of File objects (can represent either a file or directory)
*
* @param filesToRemove
* the files to be removed.
* @return true if the remove operation was successful and false otherwise.
*/
private boolean removeOldFiles(List<FileWrapper> filesToRemove)
{
boolean result = true;
sendRemoveStarted(filesToRemove.size());
for (FileWrapper fileToRemove : filesToRemove)
{
sendFileRemoveStarted(fileToRemove.getName());
result = removeOldFile(fileToRemove);
if (!result)
{
break;
}
breathing();
sendFileRemoveComplete(fileToRemove.getName());
}
sendRemoveComplete();
return result;
}
/**
* Removes the old file that will be replaced by the new.
*
* @param fileToRemove
* the File that represents the file to be removed
* @return true if the remove operation was successful and false otherwise.
*/
private boolean removeOldFile(FileWrapper fileToRemove)
{
boolean result = true;
String absolutePath = fileToRemove.getAbsolutePath();
if (s_log.isDebugEnabled())
{
s_log.debug("Examining file to remove: " + absolutePath);
}
if (fileToRemove.exists())
{
try
{
if (s_log.isDebugEnabled())
{
s_log.debug("Attempting to delete file: " + absolutePath);
}
result = _util.deleteFile(fileToRemove);
if (!result)
{
s_log.error("Delete operation failed for file/directory: " + absolutePath);
}
}
catch (SecurityException e)
{
result = false;
s_log.error("Unexpected security exception: " + e.getMessage());
}
}
else
{
if (s_log.isInfoEnabled())
{
s_log.info("Skipping delete of file doesn't appear to exist: " + absolutePath);
}
}
return result;
}
private boolean installFiles(List<InstallFileOperationInfo> filesToInstall) throws IOException
{
sendInstallStarted(_changeList.size());
breathing();
boolean result = true;
for (InstallFileOperationInfo info : filesToInstall)
{
try
{
sendFileInstallStarted(info.getArtifactName());
installFile(info);
sendFileInstallComplete(info.getArtifactName());
}
catch (Exception e)
{
s_log.error("installFiles: unexpected exception: " + e.getMessage(), e);
result = false;
break;
}
breathing();
}
return result;
}
private void installFile(InstallFileOperationInfo info) throws IOException
{
FileWrapper installDir = info.getInstallDir();
FileWrapper fileToCopy = info.getFileToInstall();
if (fileToCopy.getAbsolutePath().endsWith(".zip"))
{
// This file is a zip; it needs to be extracted into the install directory. All zips are packaged
// in such a way that the extraction beneath install directory is all that is required.
_util.extractZipFile(fileToCopy, installDir);
}
else
{
_util.copyFile(fileToCopy, installDir);
}
}
private void sendInitChangelistStarted(int numFilesToBackup)
{
logInfo("Changelist initialization started");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.INIT_CHANGELIST_STARTED);
evt.setNumFilesToUpdate(numFilesToBackup);
sendEvent(evt);
}
private void sendFileInitChangelistStarted(String artifactName)
{
logInfo("Changelist init started for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_INIT_CHANGELIST_STARTED);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendFileInitChangelistComplete(String artifactName)
{
logInfo("Changelist init complete for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_INIT_CHANGELIST_COMPLETE);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendInitChangelistComplete()
{
logInfo("Changelist initialization complete");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.INIT_CHANGELIST_COMPLETE);
sendEvent(evt);
}
private void sendBackupStarted(int numFilesToBackup)
{
logInfo("Backup started");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.BACKUP_STARTED);
evt.setNumFilesToUpdate(numFilesToBackup);
sendEvent(evt);
}
private void sendFileBackupStarted(String artifactName)
{
logInfo("Backup started for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_BACKUP_STARTED);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendFileBackupComplete(String artifactName)
{
logInfo("Backup complete for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_BACKUP_COMPLETE);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendBackupComplete()
{
logInfo("Backup complete");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.BACKUP_COMPLETE);
sendEvent(evt);
}
private void sendRemoveStarted(int numFilesToRemove)
{
logInfo("Remove started");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.REMOVE_STARTED);
evt.setNumFilesToUpdate(numFilesToRemove);
sendEvent(evt);
}
private void sendFileRemoveStarted(String artifactName)
{
logInfo("Remove started for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_REMOVE_STARTED);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendFileRemoveComplete(String artifactName)
{
logInfo("Remove complete for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_REMOVE_COMPLETE);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendRemoveComplete()
{
logInfo("Remove complete");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.REMOVE_COMPLETE);
sendEvent(evt);
}
private void sendInstallStarted(int numFilesToUpdate)
{
logInfo("Install started");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.INSTALL_STARTED);
evt.setNumFilesToUpdate(numFilesToUpdate);
sendEvent(evt);
}
private void sendFileInstallStarted(String artifactName)
{
logInfo("Install started for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_INSTALL_STARTED);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendFileInstallComplete(String artifactName)
{
logInfo("Install complete for file: " + artifactName);
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.FILE_INSTALL_COMPLETE);
evt.setArtifactName(artifactName);
sendEvent(evt);
}
private void sendInstallComplete()
{
logInfo("Install completed");
InstallStatusEvent evt = installStatusEventFactory.create(InstallEventType.INSTALL_COMPLETE);
sendEvent(evt);
}
private void sendEvent(InstallStatusEvent evt)
{
for (InstallStatusListener listener : _listeners)
{
listener.handleInstallStatusEvent(evt);
}
}
private void logInfo(String message)
{
if (s_log.isInfoEnabled())
{
s_log.info(message);
}
}
}