Package net.sourceforge.squirrel_sql.client.update.downloader

Source Code of net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloaderImpl

/*
* 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.downloader;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import net.sourceforge.squirrel_sql.client.update.UpdateUtil;
import net.sourceforge.squirrel_sql.client.update.downloader.event.DownloadEventType;
import net.sourceforge.squirrel_sql.client.update.downloader.event.DownloadStatusEvent;
import net.sourceforge.squirrel_sql.client.update.downloader.event.DownloadStatusListener;
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.fw.util.FileWrapper;
import net.sourceforge.squirrel_sql.fw.util.IProxySettings;
import net.sourceforge.squirrel_sql.fw.util.Utilities;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;

/**
* Loops through a list of artifacts and downloads each one into the appropriate directory. Notifies listeners
* of important events.
*
* @author manningr
*/
public class ArtifactDownloaderImpl implements Runnable, ArtifactDownloader
{
  /** Logger for this class. */
  private final static ILogger s_log = LoggerController.createLogger(ArtifactDownloaderImpl.class);

  /** This is the pattern that all translation jars (i18n) begin with */
  public static final String TRANSLATION_JAR_PREFIX_PATTERN = "squirrel-sql_.*";

  private List<ArtifactStatus> _artifactStatus = null;

  private volatile boolean _stopped = false;

  private boolean _isRemoteUpdateSite = true;

  private String _host = null;

  private String _path = null;

  private String _fileSystemUpdatePath = null;

  private List<DownloadStatusListener> listeners = new ArrayList<DownloadStatusListener>();

  Thread downloadThread = null;

  String _updatesDir = null;

  private int _port = 80;

  /** The name of the channel from which we are downloading artifacts */
  private String _channelName;

  private UpdateUtil _util = null;

  private PathUtils _pathUtils = new PathUtilsImpl();

  private IProxySettings _proxySettings = null;

  private boolean releaseVersionWillChange = false;

  private RetryStrategy _retryStrategy = new DefaultRetryStrategyImpl();
 
  public ArtifactDownloaderImpl(List<ArtifactStatus> artifactStatus)
  {
    _artifactStatus = artifactStatus;
    downloadThread = new Thread(this, "ArtifactDownloadThread");
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#start()
   */
  public void start()
  {
    downloadThread.start();
  }

  /**
   * Runnable interface method implementation
   */
  public void run()
  {
    long totalBytesDownloaded = 0;
    try
    {

      prepareDownloadsDirectory();

      sendDownloadStarted(_artifactStatus.size());
      for (ArtifactStatus status : _artifactStatus)
      {
        if (_stopped)
        {
          sendDownloadStopped();
          return;
        }
        else
        {
          sendDownloadFileStarted(status.getName());
        }
        String fileToGet =
          _pathUtils.buildPath(true, _path, _channelName, status.getType(), status.getName());

        String destDir = getArtifactDownloadDestDir(status);

        if (_util.isPresentInDownloadsDirectory(status))
        {
          if (s_log.isInfoEnabled())
          {
            s_log.info("run: Skipping download of file (" + fileToGet + ") which is already present "
              + "in the downloads directory.");
          }
          sendDownloadFileCompleted(status.getName());
          continue;
        }

        boolean result = true;
        if (_isRemoteUpdateSite)
        {
          int count = 0;
          boolean success = false;
          while (_retryStrategy.shouldTryAgain(count++) && !success)
          {
            success = attemptFileDownload(fileToGet, destDir, status);
            if (!success)
            {
              Utilities.sleep(_retryStrategy.getTimeToWaitBeforeRetrying(count));
            }
          }
          if (!success)
          {
            sendDownloadFailed();
            return;
          }
        }
        else
        {
          fileToGet =
            _pathUtils.buildPath(false, this._fileSystemUpdatePath, status.getType(), status.getName());
          result = _util.downloadLocalUpdateFile(fileToGet, destDir);
        }
        if (result == false)
        {
          sendDownloadFailed();
          return;
        }
        else
        {
          sendDownloadFileCompleted(status.getName());
          totalBytesDownloaded += status.getSize();
        }
      }
    }
    catch (FileNotFoundException e)
    {
      s_log.error("run: Unexpected exception: " + e.getMessage(), e);
      sendDownloadFailed();
      return;
    }
    catch (IOException e)
    {
      s_log.error("run: Unexpected exception: " + e.getMessage(), e);
      sendDownloadFailed();
      return;
    }
    if (s_log.isInfoEnabled())
    {
      s_log.info("run: Downloaded " + totalBytesDownloaded + " bytes total for all update files.");
    }
    sendDownloadComplete();
  }

  private void prepareDownloadsDirectory() throws FileNotFoundException, IOException
  {
    // if the release version doesn't change, we won't be pulling down core artifacts. So, we just
    // need to make sure that all core files have been copied from their installed locations into the
    // corresponding directory in download, which is in the CLASSPATH of the updater. This covers the
    // case where the update is being run for the first time after install, and no new version is
    // available, but the user wants to install/remove plugins and/or translations.
    if (!releaseVersionWillChange)
    {
      // Copy core files minus any i18n jars to core downloads directory
      _util.copyDir(_util.getSquirrelLibraryDir(), TRANSLATION_JAR_PREFIX_PATTERN, false,
        _util.getCoreDownloadsDir());

      // Copy i18n files to i18n downloads directory
      _util.copyDir(_util.getSquirrelLibraryDir(), TRANSLATION_JAR_PREFIX_PATTERN, true,
        _util.getI18nDownloadsDir());

      // Copy the app module jar to core downloads directory
      _util.copyFile(_util.getInstalledSquirrelMainJarLocation(), _util.getCoreDownloadsDir());
    }
    // Move any i18n files that are located in the core downloads dir to the i18n downloads dir. The spring
    // application context will not load properly (for some unknown reason) when there are i18n jars in the
    // classpath. So as a work-around, we simply ensure that they are where they should be anyway.
    // Previously we were not as careful about this, so it is possible that i18n jars were copied into the
    // core downloads directory.
    _util.moveFiles(_util.getCoreDownloadsDir(), TRANSLATION_JAR_PREFIX_PATTERN, true,
      _util.getI18nDownloadsDir());
  }

  private boolean attemptFileDownload(String fileToGet, String destDir, ArtifactStatus status)
  {
    boolean success = true;

    try
    {
      _util.downloadHttpUpdateFile(_host, _port, fileToGet, destDir, status.getSize(),
        status.getChecksum(), _proxySettings);
    }
    catch (Exception e)
    {
      s_log.error("run: encountered exception while attempting to download file (" + fileToGet + "): "
        + e.getMessage(), e);
      success = false;
    }
    return success;
  }

  private String getArtifactDownloadDestDir(ArtifactStatus status)
  {

    FileWrapper destDir = _util.getCoreDownloadsDir();
    if (UpdateUtil.PLUGIN_ARTIFACT_ID.equals(status.getType()))
    {
      destDir = _util.getPluginDownloadsDir();
    }
    if (UpdateUtil.TRANSLATION_ARTIFACT_ID.equals(status.getType()))
    {
      destDir = _util.getI18nDownloadsDir();
    }
    return destDir.getAbsolutePath();
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#stopDownload()
   */
  public void stopDownload()
  {
    _stopped = true;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#getArtifactStatus()
   */
  public List<ArtifactStatus> getArtifactStatus()
  {
    return _artifactStatus;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setArtifactStatus(java.util.List)
   */
  public void setArtifactStatus(List<ArtifactStatus> status)
  {
    _artifactStatus = status;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#isRemoteUpdateSite()
   */
  public boolean isRemoteUpdateSite()
  {
    return _isRemoteUpdateSite;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setIsRemoteUpdateSite(boolean)
   */
  public void setIsRemoteUpdateSite(boolean remoteUpdateSite)
  {
    _isRemoteUpdateSite = remoteUpdateSite;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#getHost()
   */
  public String getHost()
  {
    return _host;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setHost(java.lang.String)
   */
  public void setHost(String host)
  {
    this._host = host;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#getPath()
   */
  public String getPath()
  {
    return _path;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setPath(java.lang.String)
   */
  public void setPath(String path)
  {
    this._path = path;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#getUtil()
   */
  public UpdateUtil getUtil()
  {
    return _util;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#addDownloadStatusListener(net.sourceforge.squirrel_sql.client.update.downloader.event.DownloadStatusListener)
   */
  public void addDownloadStatusListener(DownloadStatusListener listener)
  {
    listeners.add(listener);
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#removeDownloadListener(net.sourceforge.squirrel_sql.client.update.downloader.event.DownloadStatusListener)
   */
  public void removeDownloadListener(DownloadStatusListener listener)
  {
    listeners.remove(listener);
  }

  private void sendEvent(DownloadStatusEvent evt)
  {
    for (DownloadStatusListener listener : listeners)
    {
      listener.handleDownloadStatusEvent(evt);
    }
  }

  private void sendDownloadStarted(int totalFileCount)
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_STARTED);
    evt.setFileCountTotal(totalFileCount);
    sendEvent(evt);
  }

  private void sendDownloadStopped()
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_STOPPED);
    sendEvent(evt);
  }

  private void sendDownloadComplete()
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_COMPLETED);
    sendEvent(evt);
  }

  private void sendDownloadFailed()
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_FAILED);
    sendEvent(evt);
  }

  private void sendDownloadFileStarted(String filename)
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_FILE_STARTED);
    evt.setFilename(filename);
    sendEvent(evt);
  }

  private void sendDownloadFileCompleted(String filename)
  {
    DownloadStatusEvent evt = new DownloadStatusEvent(DownloadEventType.DOWNLOAD_FILE_COMPLETED);
    evt.setFilename(filename);
    sendEvent(evt);
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#getFileSystemUpdatePath()
   */
  public String getFileSystemUpdatePath()
  {
    return _fileSystemUpdatePath;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setFileSystemUpdatePath(java.lang.String)
   */
  public void setFileSystemUpdatePath(String systemUpdatePath)
  {
    _fileSystemUpdatePath = systemUpdatePath;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setPort(int)
   */
  public void setPort(int updateServerPort)
  {
    _port = updateServerPort;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setChannelName(java.lang.String)
   */
  public void setChannelName(String name)
  {
    _channelName = name;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setUtil(net.sourceforge.squirrel_sql.client.update.UpdateUtil)
   */
  public void setUtil(UpdateUtil util)
  {
    this._util = util;
  }

  /**
   * @see net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloader#setProxySettings(net.sourceforge.squirrel_sql.fw.util.IProxySettings)
   */
  public void setProxySettings(IProxySettings settings)
  {
    _proxySettings = settings;
  }

  /**
   * @return the releaseVersionWillChange
   */
  public boolean isReleaseVersionWillChange()
  {
    return releaseVersionWillChange;
  }

  /**
   * @param releaseVersionWillChange
   *           the releaseVersionWillChange to set
   */
  public void setReleaseVersionWillChange(boolean releaseVersionWillChange)
  {
    this.releaseVersionWillChange = releaseVersionWillChange;
  }

  /**
   * @param strategy the _retryStrategy to set
   */
  public void setRetryStrategy(RetryStrategy strategy)
  {
    _retryStrategy = strategy;
  }
 
}
TOP

Related Classes of net.sourceforge.squirrel_sql.client.update.downloader.ArtifactDownloaderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.