
net.sourceforge.squirrel_sql.client.update.UpdateUtilImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of squirrel-sql Show documentation
Show all versions of squirrel-sql Show documentation
This is the jar that contains the main application classes which are very specific to
SQuirreLSQL.
/*
* Copyright (C) 2007 Rob Manning
* [email protected]
*
* 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;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.sourceforge.squirrel_sql.client.ApplicationArguments;
import net.sourceforge.squirrel_sql.client.plugin.IPluginManager;
import net.sourceforge.squirrel_sql.client.plugin.PluginInfo;
import net.sourceforge.squirrel_sql.client.preferences.IUpdateSettings;
import net.sourceforge.squirrel_sql.client.update.gui.ArtifactStatus;
import net.sourceforge.squirrel_sql.client.update.util.PathUtils;
import net.sourceforge.squirrel_sql.client.update.util.PathUtilsImpl;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ArtifactXmlBean;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ChangeListXmlBean;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ChannelXmlBean;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ModuleXmlBean;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.ReleaseXmlBean;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.UpdateXmlSerializer;
import net.sourceforge.squirrel_sql.client.update.xmlbeans.UpdateXmlSerializerImpl;
import net.sourceforge.squirrel_sql.client.util.ApplicationFileWrappers;
import net.sourceforge.squirrel_sql.client.util.ApplicationFileWrappersImpl;
import net.sourceforge.squirrel_sql.fw.util.FileWrapper;
import net.sourceforge.squirrel_sql.fw.util.FileWrapperFactory;
import net.sourceforge.squirrel_sql.fw.util.FileWrapperFactoryImpl;
import net.sourceforge.squirrel_sql.fw.util.IOUtilities;
import net.sourceforge.squirrel_sql.fw.util.IOUtilitiesImpl;
import net.sourceforge.squirrel_sql.fw.util.IProxySettings;
import net.sourceforge.squirrel_sql.fw.util.StringUtilities;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
/**
* Low-level utility methods for the UpdateController. Among other things this class provides file locations
* for important directories that are needed for backup/restore, installation/removal of updates and existing
* software. The following is a pictorial anatomy of the update directory.
*
* SQUIRREL_SQL_HOME/
* |
* + update/ (root of the update hierarchy)
* |
* + backup/ (original files that are to be updated are copied here for recovery purposes)
* | |
* | + core/
* | |
* | + i18n/
* | |
* | + plugin/
* |
* + downloads/
* | |
* | + core/
* | |
* | + i18n/
* | |
* | + plugin/
* |
* + changeList.xml (describes what is in downloads to be installed - deleted after update)
* |
* + release.xml (describes the release that is currently installed)
*
* @author manningr
*/
public class UpdateUtilImpl implements UpdateUtil
{
// This class is used both inside and outside of SQuirreL (updater application). When this class is used
// by the updater application, the SQuirreL Main class is not used, and so ApplicationArguments must be
// initialized here or else the logger initialization will fail.
static {
ApplicationArguments.getInstance();
}
/** Logger for this class. */
private final static ILogger s_log = LoggerController.createLogger(UpdateUtilImpl.class);
/** the PluginManager that tells us what plugins are installed */
private IPluginManager _pluginManager = null;
/** The size of the buffer to use when extracting files from a ZIP archive */
public final static int ZIP_EXTRACTION_BUFFER_SIZE = 8192;
/**
* Since it can take a while to compute a checksum for large jars, here we cache them for later use. The
* key is the absolute path to the file. The value is it's checksum
*/
private HashMap fileChecksumMap = new HashMap();
/** TODO: Spring-inject when this class is a Spring bean */
private PathUtils _pathUtils = new PathUtilsImpl();
public void setPathUtils(PathUtils pathUtils)
{
this._pathUtils = pathUtils;
}
/** TODO: Spring-inject when this class is a Spring bean */
private FileWrapperFactory _fileWrapperFactory = new FileWrapperFactoryImpl();
public void setFileWrapperFactory(FileWrapperFactory factory)
{
_fileWrapperFactory = factory;
}
/** TODO: Spring-inject when this class is a Spring bean */
private ApplicationFileWrappers _appFileWrappers = new ApplicationFileWrappersImpl();
public void setApplicationFileWrappers(ApplicationFileWrappers appFileWrappers)
{
_appFileWrappers = appFileWrappers;
}
/** TODO: Spring-inject when this class is a Spring bean */
private IOUtilities _iou = new IOUtilitiesImpl();
public void setIOUtilities(IOUtilities iou)
{
_iou = iou;
}
/**
* the utility class that reads and writes release info from/to the release.xml file TODO: Spring-inject
* when this class is a Spring bean
*/
private UpdateXmlSerializer _serializer = new UpdateXmlSerializerImpl();
public void setUpdateXmlSerializer(UpdateXmlSerializer serializer)
{
_serializer = serializer;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getCheckSum(java.io.File)
*/
public long getCheckSum(FileWrapper f)
{
String absPath = f.getAbsolutePath();
Long result = -1L;
if (fileChecksumMap.containsKey(absPath))
{
result = fileChecksumMap.get(absPath);
}
else
{
try
{
result = _iou.getCheckSum(f);
}
catch (IOException e)
{
s_log.error("getCheckSum: failed to compute the checksum for file (" + f.getAbsolutePath()
+ "): " + e.getMessage(), e);
}
// -1 is stored if the checksum operation failed. This will ensure that comparison with any other
// file's checksum will be different - even if they happen to be the same file.
fileChecksumMap.put(absPath, result);
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#downloadCurrentRelease(java.lang.String, int,
* java.lang.String, java.lang.String)
*/
public ChannelXmlBean downloadCurrentRelease(final String host, final int port, final String path,
final String fileToGet, final IProxySettings proxySettings) throws Exception
{
ChannelXmlBean result = null;
if (s_log.isDebugEnabled())
{
s_log.debug("downloadCurrentRelease: host=" + host + " port=" + port + " path=" + path
+ " fileToGet=" + fileToGet);
}
result = downloadCurrentReleaseHttp(host, port, path, fileToGet, proxySettings);
return result;
}
/**
* Loads the channel xml bean from the file system.throw new IOException();
*
* @param path
* the directory to find release.xml in
* @return the ChannelXmlBean that represents the specified path.
*/
public ChannelXmlBean loadUpdateFromFileSystem(final String path)
{
ChannelXmlBean result = null;
try
{
FileWrapper f = _fileWrapperFactory.create(path);
if (!f.isDirectory())
{
s_log.error("FileSystem path (" + path + ") is not a directory.");
}
else
{
f = _fileWrapperFactory.create(f, RELEASE_XML_FILENAME);
result = _serializer.readChannelBean(f);
}
}
catch (IOException e)
{
s_log.error("Unexpected exception while attempting " + "load updates from filesystem path (" + path
+ "): " + e.getMessage(), e);
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#downloadLocalUpdateFile(java.lang.String,
* java.lang.String)
*/
public boolean downloadLocalUpdateFile(String fileToGet, String destDir) throws FileNotFoundException,
IOException
{
boolean result = false;
FileWrapper fromFile = _fileWrapperFactory.create(fileToGet);
if (fromFile.isFile() && fromFile.canRead())
{
String filename = fromFile.getName();
FileWrapper toFile = _fileWrapperFactory.create(destDir, filename);
copyFile(fromFile, toFile);
result = true;
}
else
{
s_log.error("File " + fileToGet + " doesn't appear to be readable");
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#copyFile(FileWrapper, FileWrapper)
*/
public void copyFile(final FileWrapper from, final FileWrapper to) throws FileNotFoundException,
IOException
{
if (!from.exists())
{
s_log.error("Cannot copy from file (" + from.getAbsolutePath() + ") which doesn't appear to exist.");
return;
}
FileWrapper toFile = to;
// Check to see if to is a directory and convert toFile to be the name of the file in that directory.
if (to.isDirectory())
{
toFile = getFile(to, from.getName());
}
if (s_log.isDebugEnabled())
{
s_log.debug("Copying from file (" + from.getAbsolutePath() + ") to file ("
+ toFile.getAbsolutePath() + ")");
}
if (toFile.exists())
{
long fromCheckSum = getCheckSum(from);
long toCheckSum = getCheckSum(toFile);
if (fromCheckSum == toCheckSum)
{
if (s_log.isInfoEnabled())
{
s_log.info("File to be copied(" + from.getAbsolutePath() + ") has the same checksum("
+ fromCheckSum + ") as the file to copy to (" + toFile.getAbsolutePath()
+ "). Skipping copy.");
}
return;
}
}
_iou.copyFile(from, toFile);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#copyDir(
* net.sourceforge.squirrel_sql.fw.util.FileWrapper,
* java.lang.String, boolean, net.sourceforge.squirrel_sql.fw.util.FileWrapper)
*/
@Override
public void moveFiles(FileWrapper fromDir, String filePattern, boolean matchPattern, FileWrapper toDir)
throws FileNotFoundException, IOException
{
if (StringUtilities.isEmpty(filePattern)) {
throw new IllegalArgumentException("filePattern arg cannot be empty or null");
}
if (!fromDir.isDirectory()) { throw new IllegalArgumentException("Expected fromDir("
+ fromDir.getAbsolutePath() + ") to be a directory."); }
if (!toDir.isDirectory()) { throw new IllegalArgumentException("Expected toDir("
+ toDir.getAbsolutePath() + ") to be a directory."); }
List filesToMove = getFilterFileList(fromDir, filePattern, matchPattern);
for (FileWrapper file : filesToMove) {
copyFile(file, toDir);
if (s_log.isDebugEnabled()) {
s_log.debug("moveFiles: Attempting to delete file "+file.getAbsolutePath());
}
if (file.delete()) {
s_log.error("moveFiles: Unable to delete file "+file.getAbsolutePath());
}
}
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#copyDir(FileWrapper, FileWrapper)
*/
public void copyDir(FileWrapper fromDir, FileWrapper toDir) throws FileNotFoundException, IOException
{
verifyDirectory(fromDir, toDir);
FileWrapper[] files = fromDir.listFiles();
copyFiles(Arrays.asList(files), toDir);
}
private void verifyDirectory(FileWrapper fromDir, FileWrapper toDir) {
if (!fromDir.isDirectory()) { throw new IllegalArgumentException("Expected fromDir("
+ fromDir.getAbsolutePath() + ") to be a directory."); }
if (!toDir.isDirectory()) { throw new IllegalArgumentException("Expected toDir("
+ toDir.getAbsolutePath() + ") to be a directory."); }
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#copyDir(
* net.sourceforge.squirrel_sql.fw.util.FileWrapper,
* java.lang.String, boolean, net.sourceforge.squirrel_sql.fw.util.FileWrapper)
*/
@Override
public void copyDir(FileWrapper fromDir, String filePattern, boolean matchPattern, FileWrapper toDir)
throws FileNotFoundException, IOException
{
if (StringUtilities.isEmpty(filePattern)) {
throw new IllegalArgumentException("filePattern arg cannot be empty or null");
}
verifyDirectory(fromDir, toDir);
List filesToCopy = getFilterFileList(fromDir, filePattern, matchPattern);
copyFiles(filesToCopy, toDir);
}
/**
* Builds a list of FileWrappers that represent each of the files in the specified fromDir whose name
* matches or doesn't match the specified filePattern. A true value for the matchPattern flag indicates
* that files which match the pattern should be included. False indicates that only files that do not
* match the pattern should be included.
*
* @param fromDir
* @param filePattern
* @param matchPattern
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private List getFilterFileList(FileWrapper fromDir, String filePattern, boolean matchPattern)
throws FileNotFoundException, IOException
{
FileWrapper[] files = fromDir.listFiles();
List filesToCopy = new ArrayList();
for (FileWrapper sourceFile : files) {
boolean fileNameMatchesPattern = sourceFile.getName().matches(filePattern);
if (matchPattern && fileNameMatchesPattern) {
filesToCopy.add(sourceFile);
}
if (!matchPattern && !fileNameMatchesPattern) {
filesToCopy.add(sourceFile);
}
}
return filesToCopy;
}
/**
* Expects the toDir to be a directory. This check should be made in the public method.
* @param files
* @param toDir
* @throws FileNotFoundException
* @throws IOException
*/
private void copyFiles(List files, FileWrapper toDir)
throws FileNotFoundException, IOException
{
for (FileWrapper sourceFile : files)
{
copyFile(sourceFile, toDir);
}
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getLocalReleaseInfo(java.lang.String)
*/
public ChannelXmlBean getLocalReleaseInfo(String localReleaseFile)
{
ChannelXmlBean result = null;
if (s_log.isDebugEnabled())
{
s_log.debug("Attempting to read local release file: " + localReleaseFile);
}
try
{
result = _serializer.readChannelBean(localReleaseFile);
}
catch (IOException e)
{
s_log.error("Unable to read local release file: " + e.getMessage(), e);
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getSquirrelHomeDir()
*/
public FileWrapper getSquirrelHomeDir()
{
FileWrapper squirrelHomeDir = _appFileWrappers.getSquirrelHomeDir();
if (!squirrelHomeDir.isDirectory())
{
s_log.error("SQuirreL Home Directory (" + squirrelHomeDir.getAbsolutePath()
+ " doesn't appear to be a directory");
}
return squirrelHomeDir;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getInstalledSquirrelMainJarLocation()
*/
public FileWrapper getInstalledSquirrelMainJarLocation()
{
return _fileWrapperFactory.create(getSquirrelHomeDir(), SQUIRREL_SQL_JAR_FILENAME);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getSquirrelPluginsDir()
*/
public FileWrapper getSquirrelPluginsDir()
{
FileWrapper squirrelHomeDir = _appFileWrappers.getPluginsDirectory();
if (!squirrelHomeDir.isDirectory())
{
s_log.error("SQuirreL Plugins Directory (" + squirrelHomeDir.getAbsolutePath()
+ " doesn't appear to be a directory");
}
return squirrelHomeDir;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getSquirrelLibraryDir()
*/
public FileWrapper getSquirrelLibraryDir()
{
FileWrapper squirrelLibDir = _appFileWrappers.getLibraryDirectory();
if (!squirrelLibDir.isDirectory())
{
s_log.error("SQuirreL Library Directory (" + squirrelLibDir.getAbsolutePath()
+ " doesn't appear to be a directory");
}
return squirrelLibDir;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getSquirrelUpdateDir()
*/
public FileWrapper getSquirrelUpdateDir()
{
return getDir(_appFileWrappers.getUpdateDirectory(), null, true);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getDownloadsDir()
*/
public FileWrapper getDownloadsDir()
{
return getDir(getSquirrelUpdateDir(), DOWNLOADS_DIR_NAME, true);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getCoreDownloadsDir()
*/
public FileWrapper getCoreDownloadsDir()
{
return getDir(getDownloadsDir(), CORE_ARTIFACT_ID, true);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getPluginDownloadsDir()
*/
public FileWrapper getPluginDownloadsDir()
{
return getDir(getDownloadsDir(), PLUGIN_ARTIFACT_ID, true);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getI18nDownloadsDir()
*/
public FileWrapper getI18nDownloadsDir()
{
return getDir(getDownloadsDir(), TRANSLATION_ARTIFACT_ID, true);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getBackupDir()
*/
public FileWrapper getBackupDir()
{
return getDir(getSquirrelUpdateDir(), BACKUP_ROOT_DIR_NAME, false);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getCoreBackupDir()
*/
public FileWrapper getCoreBackupDir()
{
return getDir(getBackupDir(), CORE_ARTIFACT_ID, false);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getI18nBackupDir()
*/
public FileWrapper getI18nBackupDir()
{
return getDir(getBackupDir(), TRANSLATION_ARTIFACT_ID, false);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getPluginBackupDir()
*/
public FileWrapper getPluginBackupDir()
{
return getDir(getBackupDir(), PLUGIN_ARTIFACT_ID, false);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getChangeListFile()
*/
public FileWrapper getChangeListFile()
{
FileWrapper updateDir = getSquirrelUpdateDir();
FileWrapper changeListFile = _fileWrapperFactory.create(updateDir, CHANGE_LIST_FILENAME);
return changeListFile;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#saveChangeList(java.util.List)
*/
public void saveChangeList(List changes) throws FileNotFoundException
{
ChangeListXmlBean changeBean = new ChangeListXmlBean();
changeBean.setChanges(changes);
_serializer.write(changeBean, getChangeListFile());
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getChangeList()
*/
public ChangeListXmlBean getChangeList() throws FileNotFoundException
{
return _serializer.readChangeListBean(getChangeListFile());
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getLocalReleaseFile()
*/
public FileWrapper getLocalReleaseFile() throws FileNotFoundException
{
FileWrapper result = null;
try
{
FileWrapper[] files = getSquirrelHomeDir().listFiles();
for (FileWrapper file : files)
{
if (LOCAL_UPDATE_DIR_NAME.equals(file.getName()))
{
FileWrapper[] updateFiles = file.listFiles();
for (FileWrapper updateFile : updateFiles)
{
if (RELEASE_XML_FILENAME.equals(updateFile.getName()))
{
result = updateFile;
}
}
}
}
}
catch (Exception e)
{
s_log.error("getLocalReleaseFile: Exception encountered while " + "attempting to find "
+ RELEASE_XML_FILENAME + " file");
}
if (result == null) { throw new FileNotFoundException("File " + RELEASE_XML_FILENAME
+ " could not be found"); }
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getArtifactStatus(net.sourceforge.squirrel_sql.client.update.xmlbeans.ChannelXmlBean)
*/
public List getArtifactStatus(ChannelXmlBean channelXmlBean)
{
ReleaseXmlBean releaseXmlBean = channelXmlBean.getCurrentRelease();
return getArtifactStatus(releaseXmlBean);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#
* getArtifactStatus(net.sourceforge.squirrel_sql.client.update.xmlbeans.ReleaseXmlBean)
*/
public List getArtifactStatus(ReleaseXmlBean releaseXmlBean)
{
Set installedPlugins = getInstalledPlugins();
Set installedTranslations = getInstalledTranslations();
ArrayList result = new ArrayList();
Set currentModuleBeans = releaseXmlBean.getModules();
for (ModuleXmlBean module : currentModuleBeans)
{
Set artifactBeans = module.getArtifacts();
String moduleName = module.getName();
for (ArtifactXmlBean artifact : artifactBeans)
{
ArtifactStatus status = new ArtifactStatus(artifact);
status.setType(moduleName);
if (status.isCoreArtifact())
{
status.setInstalled(true);
}
if (status.isPluginArtifact() && installedPlugins.contains(artifact.getName()))
{
status.setInstalled(true);
}
if (status.isTranslationArtifact() && installedTranslations.contains(artifact.getName()))
{
status.setInstalled(true);
}
result.add(status);
}
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getInstalledPlugins()
*/
public Set getInstalledPlugins()
{
HashSet result = new HashSet();
for (PluginInfo info : _pluginManager.getPluginInformation())
{
result.add(info.getInternalName() + ".zip");
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getInstalledTranslations()
*/
public Set getInstalledTranslations()
{
HashSet result = new HashSet();
FileWrapper libDir = getSquirrelLibraryDir();
for (String filename : libDir.list())
{
if (filename.startsWith("squirrel-sql_"))
{
result.add(filename);
}
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getPluginManager()
*/
public IPluginManager getPluginManager()
{
return _pluginManager;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#setPluginManager(net.sourceforge.squirrel_sql.client.plugin.PluginManager)
*/
public void setPluginManager(IPluginManager manager)
{
_pluginManager = manager;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#checkDir(FileWrapper, java.lang.String)
*/
public FileWrapper checkDir(FileWrapper parent, String child)
{
FileWrapper dir = _fileWrapperFactory.create(parent, child);
if (!dir.exists() && !dir.mkdir())
{
s_log.error("checkDir: Failed to mkdir - " + dir.getAbsolutePath());
}
return dir;
}
/**
* TODO: move to IOUtilities
*
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#createZipFile(FileWrapper, FileWrapper[])
*/
public void createZipFile(FileWrapper zipFile, FileWrapper... sourceFiles) throws FileNotFoundException,
IOException
{
ZipOutputStream os = new ZipOutputStream(new FileOutputStream(zipFile.getAbsolutePath()));
zipFileOs(os, sourceFiles);
os.close();
}
/**
* This function will recursively delete directories and files.
*
* @param path
* File or Directory to be deleted
* @return true indicates successfully deleted the file or directory.
*/
public boolean deleteFile(FileWrapper path)
{
boolean result = true;
if (path.exists())
{
if (path.isFile())
{
result = path.delete();
if (s_log.isInfoEnabled())
{
if (result)
{
s_log.info("deleteFile: successfully deleted file = " + path.getAbsolutePath());
}
else
{
s_log.info("deleteFile: failed to delete file = " + path.getAbsolutePath());
}
}
}
else
{
FileWrapper[] files = path.listFiles();
for (int i = 0; i < files.length; i++)
{
result = result && deleteFile(files[i]);
}
result = result && path.delete();
}
}
return result;
}
/**
* TODO: Move this to IOUtilities Extracts the specified zip file to the specified output directory.
*
* @param zipFile
* @param outputDirectory
* @throws IOException
*/
public void extractZipFile(FileWrapper zipFile, FileWrapper outputDirectory) throws IOException
{
if (!outputDirectory.isDirectory())
{
s_log.error("Output directory specified (" + outputDirectory.getAbsolutePath()
+ ") doesn't appear to be a directory");
return;
}
FileInputStream fis = null;
ZipInputStream zis = null;
FileOutputStream fos = null;
try
{
fis = new FileInputStream(zipFile.getAbsolutePath());
zis = new ZipInputStream(fis);
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null)
{
String name = zipEntry.getName();
if (zipEntry.isDirectory())
{
checkDir(outputDirectory, name);
}
else
{
FileWrapper newFile = _fileWrapperFactory.create(outputDirectory, name);
if (newFile.exists())
{
if (s_log.isInfoEnabled())
{
s_log.info("Deleting extraction file that already exists:" + newFile.getAbsolutePath());
}
newFile.delete();
}
fos = new FileOutputStream(newFile.getAbsolutePath());
byte[] buffer = new byte[ZIP_EXTRACTION_BUFFER_SIZE];
int n = 0;
while ((n = zis.read(buffer, 0, ZIP_EXTRACTION_BUFFER_SIZE)) > -1)
{
fos.write(buffer, 0, n);
}
fos.close();
}
zipEntry = zis.getNextEntry();
}
}
finally
{
_iou.closeOutputStream(fos);
_iou.closeInputStream(fis);
_iou.closeInputStream(zis);
}
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getChangeList(FileWrapper)
*/
public ChangeListXmlBean getChangeList(FileWrapper changeListFile) throws FileNotFoundException
{
return _serializer.readChangeListBean(changeListFile);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#getFile(FileWrapper, java.lang.String)
*/
public FileWrapper getFile(FileWrapper installDir, String artifactName)
{
return _fileWrapperFactory.create(installDir, artifactName);
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#downloadHttpUpdateFile(java.lang.String, int,
* java.lang.String, java.lang.String, long, long)
*/
public String downloadHttpUpdateFile(final String host, final int port, final String fileToGet,
final String destDir, final long fileSize, final long checksum, final IProxySettings proxySettings)
throws Exception
{
URL url = _iou.constructHttpUrl(host, port, fileToGet);
String result = null;
FileWrapper resultFile = _fileWrapperFactory.create(destDir, _pathUtils.getFileFromPath(fileToGet));
result = resultFile.getAbsolutePath();
if (s_log.isDebugEnabled())
{
s_log.debug("downloadHttpFile: writing http response body to file: " + resultFile);
}
int totalLength = _iou.downloadHttpFile(url, resultFile, proxySettings);
verifySize(url, fileSize, totalLength);
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#
* getDownloadFileLocation(net.sourceforge.squirrel_sql.client.update.gui.ArtifactStatus)
*/
public FileWrapper getDownloadFileLocation(ArtifactStatus status)
{
FileWrapper result = null;
if (CORE_ARTIFACT_ID.equals(status.getType()))
{
result = getFile(getCoreDownloadsDir(), status.getName());
}
if (PLUGIN_ARTIFACT_ID.equals(status.getType()))
{
result = getFile(getPluginDownloadsDir(), status.getName());
}
if (TRANSLATION_ARTIFACT_ID.equals(status.getType()))
{
result = getFile(getI18nDownloadsDir(), status.getName());
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#
* isPresentInDownloadsDirectory(net.sourceforge.squirrel_sql.client.update.gui.ArtifactStatus)
*/
public boolean isPresentInDownloadsDirectory(ArtifactStatus status)
{
boolean result = false;
FileWrapper downloadFile = getDownloadFileLocation(status);
if (downloadFile.exists())
{
long checkSum = getCheckSum(downloadFile);
if (status.getChecksum() == checkSum)
{
if (downloadFile.length() == status.getSize())
{
result = true;
}
}
}
return result;
}
/* Helper Methods */
/**
* Verifies that the byte size of what was downloaded matches the expected size of the artifact. If
* expected is -1, this check will be skipped; this is expected in the case where the release.xml file is
* being downloaded and there is no information about big it is. When -1 is expected, then a log message is
* created and this check is skipped.
*
* @param url
* the URL that was downloaded from
* @param expected
* the number of bytes expected to be downloaded
* @param actual
* the actual number of bytes downloaded
* @throws Exception
* if the two counts do not match.
*/
private void verifySize(URL url, long expected, long actual) throws Exception
{
if (expected == -1)
{
if (s_log.isInfoEnabled())
{
s_log.info("verifySize: expected size was -1. Skipping check for url: " + url.toString());
}
return;
}
if (expected != actual) { throw new Exception("Attempt to get file contents from url ("
+ url.toString() + ") resulted in " + actual + " bytes downloaded, but " + expected
+ " bytes were expected."); }
}
/**
* Writes the specified sourceFile(s) contents to the specified Zip output stream.
*
* @param os
* the Zip OutputStream to write to
* @param sourceFiles
* the files to read from
* @throws FileNotFoundException
* if one of the files could not be found
* @throws IOException
* if and IO error occurs
*/
private void zipFileOs(ZipOutputStream os, FileWrapper[] sourceFiles) throws FileNotFoundException,
IOException
{
for (FileWrapper file : sourceFiles)
{
if (file.isDirectory())
{
zipFileOs(os, file.listFiles());
}
else
{
FileInputStream fis = null;
try
{
fis = new FileInputStream(file.getAbsolutePath());
os.putNextEntry(new ZipEntry(file.getPath()));
_iou.copyBytes(fis, os);
}
finally
{
_iou.closeInputStream(fis);
}
}
}
}
/**
* @param parent
* @param dirName
* @param create
* @return
*/
private FileWrapper getDir(FileWrapper parent, String dirName, boolean create)
{
FileWrapper result = null;
if (dirName != null)
{
result = _fileWrapperFactory.create(parent, dirName);
}
else
{
result = parent;
}
if (!result.isDirectory())
{
if (result.exists())
{
// If the update dir, is actually a file, log an error.
s_log.error(dirName + " directory (" + result.getAbsolutePath()
+ ") doesn't appear to be a directory");
}
else
{
// If the downloads dir doesn't already exist, just create it.
if (create)
{
result.mkdir();
}
}
}
return result;
}
/**
* @param host
* @param port
* @param path
* @param fileToGet
* @return
* @throws Exception
* if the current release file could not be downloaded
*/
private ChannelXmlBean downloadCurrentReleaseHttp(final String host, final int port, final String path,
final String file, final IProxySettings proxySettings) throws Exception
{
ChannelXmlBean result = null;
InputStream is = null;
try
{
String fileToGet = _pathUtils.buildPath(true, path, file);
// We set expected and checksum to -1 here, since we don't have that information for release.xml file
// TODO: Can HttpClient be used to get the byte-size of release.xml so we can perform this check?
String filename =
downloadHttpUpdateFile(host, port, fileToGet, getDownloadsDir().getAbsolutePath(), -1, -1,
proxySettings);
FileWrapper releaseXmlFile = _fileWrapperFactory.create(filename);
if (releaseXmlFile.exists())
{
result = _serializer.readChannelBean(releaseXmlFile);
}
else
{
throw new FileNotFoundException("Current release file couldn't be downloaded");
}
}
finally
{
_iou.closeInputStream(is);
}
return result;
}
/**
* @see net.sourceforge.squirrel_sql.client.update.UpdateUtil#
* getUpdateCheckFrequency(net.sourceforge.squirrel_sql.client.preferences.IUpdateSettings)
*/
public UpdateCheckFrequency getUpdateCheckFrequency(IUpdateSettings settings)
{
UpdateCheckFrequency result = UpdateCheckFrequency.STARTUP;
String updateCheckFrequencyStr = settings.getUpdateCheckFrequency();
if ("weekly".equalsIgnoreCase(updateCheckFrequencyStr))
{
result = UpdateCheckFrequency.WEEKLY;
}
if ("daily".equalsIgnoreCase(updateCheckFrequencyStr))
{
result = UpdateCheckFrequency.DAILY;
}
if ("startup".equalsIgnoreCase(updateCheckFrequencyStr))
{
result = UpdateCheckFrequency.STARTUP;
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy