[jsword-svn] jsword/java/jsword/org/crosswire/jsword/book/install/sword s

jswordcvs at crosswire.org jswordcvs at crosswire.org
Fri Oct 15 16:28:10 MST 2004


Update of /cvs/jsword/jsword/java/jsword/org/crosswire/jsword/book/install/sword
In directory www.crosswire.org:/tmp/cvs-serv30320/java/jsword/org/crosswire/jsword/book/install/sword

Modified Files:
	HttpSwordInstaller.java FtpSwordInstaller.java 
Added Files:
	AbstractSwordInstaller.java 
Log Message:
progress on downloading index

--- NEW FILE: AbstractSwordInstaller.java ---
package org.crosswire.jsword.book.install.sword;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.crosswire.common.progress.Job;
import org.crosswire.common.progress.JobManager;
import org.crosswire.common.util.IOUtil;
import org.crosswire.common.util.Logger;
import org.crosswire.common.util.NetUtil;
import org.crosswire.common.util.Reporter;
import org.crosswire.jsword.book.BookMetaData;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.basic.AbstractBookList;
import org.crosswire.jsword.book.install.InstallException;
import org.crosswire.jsword.book.install.Installer;
import org.crosswire.jsword.book.sword.ModuleType;
import org.crosswire.jsword.book.sword.SwordBookDriver;
import org.crosswire.jsword.book.sword.SwordBookMetaData;
import org.crosswire.jsword.book.sword.SwordConstants;
import org.crosswire.jsword.util.Project;

import com.ice.tar.TarEntry;
import com.ice.tar.TarInputStream;

/**
 * .
 * 
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 *
 * Distribution Licence:<br />
 * JSword is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public License,
 * version 2 as published by the Free Software Foundation.<br />
 * This program 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
 * General Public License for more details.<br />
 * The License is available on the internet
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA<br />
 * The copyright to this program is held by it's authors.
 * </font></td></tr></table>
 * @see gnu.gpl.Licence
 * @author Joe Walker [joe at eireneh dot com]
 * @version $Id: AbstractSwordInstaller.java,v 1.1 2004/10/15 23:28:08 joe Exp $
 */
public abstract class AbstractSwordInstaller extends AbstractBookList implements Installer
{
    /**
     * Utility to download a file from a remote site
     * @param job The way of noting progress
     * @param dir The directory from which to download the file
     * @param file The file to download
     * @throws InstallException
     */
    protected abstract void download(Job job, String dir, String file, URL dest) throws InstallException;

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.install.Installer#toLocalURL(org.crosswire.jsword.book.BookMetaData)
     */
    public URL toLocalURL(BookMetaData bmd)
    {
        File fulldir = toLocalDirectory(bmd);

        try
        {
            return new URL(NetUtil.PROTOCOL_FILE, null, fulldir.getAbsolutePath());
        }
        catch (MalformedURLException ex)
        {
            log.error("Failed to create URL for file: "+fulldir, ex); //$NON-NLS-1$
            assert false;
            return null;
        }
    }

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.install.Installer#isNewer(org.crosswire.jsword.book.BookMetaData)
     */
    public boolean isNewer(BookMetaData bmd)
    {
        URL local = toLocalURL(bmd);

        SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
        URL conf = NetUtil.lengthenURL(local, sbmd.getDiskName() + SwordConstants.EXTENSION_CONF);

        URL remote = toRemoteURL(bmd);
        return NetUtil.isNewer(remote, conf);
    }

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.BookList#getBookMetaDatas()
     */
    public List getBookMetaDatas()
    {
        try
        {
            if (!loaded)
            {
                loadCachedIndex();
            }

            List mutable = new ArrayList();
            mutable.addAll(entries.values());
            return Collections.unmodifiableList(mutable);
        }
        catch (InstallException ex)
        {
            log.error("Failed to reload cached index file", ex); //$NON-NLS-1$
            return new ArrayList();
        }
    }

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.install.Installer#install(org.crosswire.jsword.book.BookMetaData)
     */
    public void install(BookMetaData bmd)
    {
        if (!(bmd instanceof SwordBookMetaData))
        {
            assert false;
            return;
        }

        // Is the book already installed? Then nothing to do.
        if (Books.installed().getBookMetaData(bmd.getName()) != null)
        {
            return;
        }

        final SwordBookMetaData sbmd = (SwordBookMetaData) bmd;

        // So now we know what we want to install - all we need to do
        // is installer.install(name) however we are doing it in the
        // background so we create a job for it.
        final Thread worker = new Thread("DisplayPreLoader") //$NON-NLS-1$
        {
            public void run()
            {
                URL predicturl = Project.instance().getWritablePropertiesURL("sword-install"); //$NON-NLS-1$
                Job job = JobManager.createJob(Msg.INSTALLING.toString(sbmd.getName()), predicturl, this, true);

                yield();

                try
                {
                    job.setProgress(Msg.JOB_INIT.toString());

                    URL desturl = toLocalURL(sbmd);
                    NetUtil.makeDirectory(desturl);

                    URL temp = NetUtil.getTemporaryURL("swd", "zip"); //$NON-NLS-1$ //$NON-NLS-2$

                    download(job, directory + '/' + PACKAGE_DIR, sbmd.getInitials() + ZIP_SUFFIX, temp);

                    IOUtil.unpackZip(NetUtil.getAsFile(temp), desturl);

                    File dldir = SwordBookDriver.getDownloadDir();
                    job.setProgress(Msg.JOB_CONFIG.toString());
                    File confdir = new File(dldir, SwordConstants.DIR_CONF);
                    confdir.mkdirs();
                    File conf = new File(confdir, sbmd.getDiskName() + SwordConstants.EXTENSION_CONF);
                    URL configurl = new URL(NetUtil.PROTOCOL_FILE, null, conf.getAbsolutePath());
                    sbmd.save(configurl);

                    SwordBookDriver.registerNewBook(sbmd, dldir);
                }
                catch (Exception ex)
                {
                    Reporter.informUser(this, ex);
                    job.ignoreTimings();
                }
                finally
                {
                    job.done();
                }
            }
        };

        // this actually starts the thread off
        worker.setPriority(Thread.MIN_PRIORITY);
        worker.start();
    }

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.install.Installer#reloadIndex()
     */
    public void reloadBookList() throws InstallException
    {
        Job job = JobManager.createJob(Msg.JOB_DOWNLOADING.toString(), Thread.currentThread(), false);

        try
        {
            URL scratchfile = getCachedIndexFile();
            download(job, LIST_DIR + '/' + directory, FILE_LIST_GZ, scratchfile);
            loaded = false;
        }
        catch (InstallException ex)
        {
            job.ignoreTimings();
            throw ex;
        }
        finally
        {
            job.done();
        }
    }

    /* (non-Javadoc)
     * @see org.crosswire.jsword.book.install.Installer#downloadSearchIndex(org.crosswire.jsword.book.BookMetaData, java.net.URL)
     */
    public void downloadSearchIndex(BookMetaData bmd, URL localDest) throws InstallException
    {
        Job job = JobManager.createJob(Msg.JOB_DOWNLOADING.toString(), Thread.currentThread(), false);

        try
        {
            download(job, directory + '/' + SEARCH_DIR, bmd.getInitials() + ZIP_SUFFIX, localDest);
        }
        catch (Exception ex)
        {
            job.ignoreTimings();
            throw new InstallException(Msg.UNKNOWN_ERROR, ex);
        }
        finally
        {
            job.done();
        }                
    }

    /**
     * Load the cached index file into memory
     */
    private void loadCachedIndex() throws InstallException
    {
        entries.clear();

        URL cache = getCachedIndexFile();
        if (!NetUtil.isFile(cache))
        {
            reloadBookList();
        }

        try
        {
            InputStream in = cache.openStream();
            GZIPInputStream gin = new GZIPInputStream(in);
            TarInputStream tin = new TarInputStream(gin);

            while (true)
            {
                TarEntry entry = tin.getNextEntry();
                if (entry == null)
                {
                    break;
                }

                String internal = entry.getName();
                if (!entry.isDirectory())
                {
                    try
                    {
                        int size = (int) entry.getSize();
                        byte[] buffer = new byte[size];
                        tin.read(buffer);

                        if (internal.endsWith(SwordConstants.EXTENSION_CONF))
                        {
                            internal = internal.substring(0, internal.length() - 5);
                        }

                        if (internal.startsWith(SwordConstants.DIR_CONF + '/'))
                        {
                            internal = internal.substring(7);
                        }

                        Reader rin = new InputStreamReader(new ByteArrayInputStream(buffer));
                        SwordBookMetaData sbmd = new SwordBookMetaData(rin, internal);

                        if (sbmd.isSupported())
                        {
                            entries.put(sbmd.getName(), sbmd);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.warn("Failed to load config for entry: " + internal, ex); //$NON-NLS-1$
                    }
                }
            }

            IOUtil.close(tin);
            IOUtil.close(gin);
            IOUtil.close(in);

            loaded = true;
        }
        catch (IOException ex)
        {
            throw new InstallException(Msg.CACHE_ERROR, ex);
        }
    }

    /**
     * @return Returns the directory.
     */
    public String getDirectory()
    {
        return directory;
    }

    /**
     * @param directory The directory to set.
     */
    public void setDirectory(String directory)
    {
        this.directory = directory;
        loaded = false;
    }

    /**
     * @return Returns the host.
     */
    public String getHost()
    {
        return host;
    }

    /**
     * @param host The host to set.
     */
    public void setHost(String host)
    {
        this.host = host;
        loaded = false;
    }

    /**
     * The URL for the cached index file for this installer
     */
    protected URL getCachedIndexFile() throws InstallException
    {
        try
        {
            URL scratchdir = Project.instance().getTempScratchSpace(getTempFileExtension(host, directory), false);
            return NetUtil.lengthenURL(scratchdir, FILE_LIST_GZ);
        }
        catch (IOException ex)
        {
            throw new InstallException(Msg.URL_FAILED, ex);
        }
    }

    /**
     * What are we using as a temp filename?
     */
    private static String getTempFileExtension(String host, String directory)
    {
        return DOWNLOAD_PREFIX + host + directory.replace('/', '_'); //$NON-NLS-1$
    }

    /**
     * Get a local directory to which a book is installed
     */
    protected File toLocalDirectory(BookMetaData bmd)
    {
        if (!(bmd instanceof SwordBookMetaData))
        {
            assert false;
            return null;
        }

        SwordBookMetaData sbmd = (SwordBookMetaData) bmd;

        ModuleType type = sbmd.getModuleType();
        String modpath = type.getInstallDirectory();
        String destname = modpath + '/' + sbmd.getDiskName();

        File dldir = SwordBookDriver.getDownloadDir();
        File moddir = new File(dldir, SwordConstants.DIR_DATA);
        return new File(moddir, destname);
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object object)
    {
        if (!(object instanceof AbstractSwordInstaller))
        {
            return false;
        }
        AbstractSwordInstaller that = (AbstractSwordInstaller) object;

        if (!equals(this.host, that.host))
        {
            return false;
        }

        if (!equals(this.directory, that.directory))
        {
            return false;
        }

        return true;
    }

    /* (non-Javadoc)
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(Object arg0)
    {
        HttpSwordInstaller myClass = (HttpSwordInstaller) arg0;

        int ret = host.compareTo(myClass.host);
        if (ret != 0)
        {
            ret = directory.compareTo(myClass.directory);
        }
        return ret;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    public int hashCode()
    {
        return host.hashCode() + directory.hashCode();
    }

    /**
     * Quick utility to check to see if 2 (potentially null) strings are equal
     */
    protected boolean equals(String string1, String string2)
    {
        if (string1 == null)
        {
            return string2 == null;
        }
        return string1.equals(string2);
    }

    /**
     * The relative path of the dir holding the zip files
     */
    protected static final String PACKAGE_DIR = "packages/rawzip"; //$NON-NLS-1$

    /**
     * The relative path of the dir holding the index file
     */
    private static final String LIST_DIR = "raw"; //$NON-NLS-1$

    /**
     * A map of the entries in this download area
     */
    protected Map entries = new HashMap();

    /**
     * The remote hostname.
     */
    protected String host;

    /**
     * The directory containing modules on the <code>host</code>.
     */
    protected String directory = "/"; //$NON-NLS-1$

    /**
     * Do we need to reload the index file
     */
    protected boolean loaded;

    /**
     * The sword index file
     */
    protected static final String FILE_LIST_GZ = "mods.d.tar.gz"; //$NON-NLS-1$

    /**
     * The suffix of zip modules on this server
     */
    protected static final String ZIP_SUFFIX = ".zip"; //$NON-NLS-1$

    /**
     * The log stream
     */
    private static final Logger log = Logger.getLogger(AbstractSwordInstaller.class);

    /**
     * The relative path of the dir holding the search index files
     */
    protected static final String SEARCH_DIR = "seach/jsword/L1"; //$NON-NLS-1$

    /**
     * When we cache a download index
     */
    protected static final String DOWNLOAD_PREFIX = "download-"; //$NON-NLS-1$
}

Index: HttpSwordInstaller.java
===================================================================
RCS file: /cvs/jsword/jsword/java/jsword/org/crosswire/jsword/book/install/sword/HttpSwordInstaller.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** HttpSwordInstaller.java	10 Oct 2004 22:12:02 -0000	1.11
--- HttpSwordInstaller.java	15 Oct 2004 23:28:08 -0000	1.12
***************
*** 1,42 ****
  package org.crosswire.jsword.book.install.sword;
  
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
- import java.io.InputStreamReader;
  import java.io.OutputStream;
- import java.io.Reader;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLConnection;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.zip.GZIPInputStream;
  
  import org.crosswire.common.progress.Job;
- import org.crosswire.common.progress.JobManager;
  import org.crosswire.common.util.IOUtil;
- import org.crosswire.common.util.Logger;
  import org.crosswire.common.util.NetUtil;
- import org.crosswire.common.util.Reporter;
  import org.crosswire.jsword.book.BookMetaData;
- import org.crosswire.jsword.book.Books;
- import org.crosswire.jsword.book.BooksListener;
- import org.crosswire.jsword.book.basic.AbstractBookList;
  import org.crosswire.jsword.book.install.InstallException;
- import org.crosswire.jsword.book.install.Installer;
- import org.crosswire.jsword.book.sword.ModuleType;
- import org.crosswire.jsword.book.sword.SwordBookDriver;
  import org.crosswire.jsword.book.sword.SwordBookMetaData;
- import org.crosswire.jsword.book.sword.SwordConstants;
- import org.crosswire.jsword.util.Project;
- 
- import com.ice.tar.TarEntry;
- import com.ice.tar.TarInputStream;
  
  /**
--- 1,17 ----
***************
*** 65,69 ****
   * @version $Id$
   */
! public class HttpSwordInstaller extends AbstractBookList implements Installer, Comparable
  {
      /* (non-Javadoc)
--- 40,44 ----
   * @version $Id$
   */
! public class HttpSwordInstaller extends AbstractSwordInstaller implements Comparable
  {
      /* (non-Javadoc)
***************
*** 72,182 ****
      public String getURL()
      {
!         return PROTOCOL_WEB + ":" + host + directory; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.BookList#getBookMetaDatas()
       */
!     public List getBookMetaDatas()
      {
!         try
!         {
!             if (!loaded)
!             {
!                 loadCachedIndex();
!             }
! 
!             List mutable = new ArrayList();
!             mutable.addAll(entries.values());
!             return Collections.unmodifiableList(mutable);
!         }
!         catch (InstallException ex)
          {
!             log.error("Failed to reload cached index file", ex); //$NON-NLS-1$
!             return new ArrayList();
          }
-     }
  
!     /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#reloadIndex()
!      */
!     public void reloadBookList() throws InstallException
!     {
!         URL scratchfile = getCachedIndexFile();
!         download(host, directory, FILE_LIST_GZ, scratchfile);
!         loaded = false;
!     }
  
-     /**
-      * Utility to download a file by HTTP from a remote site
-      * @param site The place to download from
-      * @param dir The directory from which to download the file
-      * @param file The file to download
-      * @throws InstallException
-      */
-     private static void download(String site, String dir, String file, URL dest) throws InstallException
-     {
-         InputStream in = null;
-         OutputStream out = null;
          try
          {
!             URL url = new URL("http://" + site + dir + '/' + LIST_DIR + '/' + file); //$NON-NLS-1$
!             byte[] buf = new byte[4096];
! 
!             // Check the download directory exists
!             URL parent = NetUtil.shortenURL(dest, FILE_LIST_GZ);
!             NetUtil.makeDirectory(parent);
! 
!             // Download the index file
!             out = NetUtil.getOutputStream(dest);
!             in = url.openStream();
!             for (int read = 0; -1 != (read = in.read(buf)); )
!             {
!                 out.write(buf, 0, read);
!             }
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.UNKNOWN_ERROR, ex);
          }
!         finally
          {
!             IOUtil.close(in);
!             IOUtil.close(out);
          }
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#downloadSearchIndex(org.crosswire.jsword.book.BookMetaData, java.net.URL)
       */
!     public void downloadSearchIndex(BookMetaData bmd, URL localDest) throws InstallException
      {
-         Job job = JobManager.createJob(Msg.JOB_DOWNLOADING.toString(), Thread.currentThread(), false);
- 
          try
          {
!             String dir = directory + '/' + SEARCH_DIR  + '/' + bmd.getInitials() + ZIP_SUFFIX;
!             downloadZip(job, host, dir, localDest);
          }
!         catch (Exception ex)
          {
-             job.ignoreTimings();
              throw new InstallException(Msg.UNKNOWN_ERROR, ex);
          }
-         finally
-         {
-             job.done();
-         }                
      }
  
      /**
-      * Utility to download a file by HTTP from a remote site
       * @param job
!      * @param site
!      * @param dir
!      * @param destdir
!      * @throws InstallException
       */
!     protected static void downloadZip(Job job, String site, String dir, URL destdir) throws InstallException
      {
          InputStream in = null;
--- 47,99 ----
      public String getURL()
      {
!         return PROTOCOL_WEB + ":" + host + directory; //$NON-NLS-1$
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#toURL(org.crosswire.jsword.book.BookMetaData)
       */
!     public URL toRemoteURL(BookMetaData bmd)
      {
!         if (!(bmd instanceof SwordBookMetaData))
          {
!             assert false;
!             return null;
          }
  
!         SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
  
          try
          {
!             return new URL(NetUtil.PROTOCOL_HTTP, host, directory + '/' + PACKAGE_DIR + '/' + sbmd.getInitials() + ZIP_SUFFIX); //$NON-NLS-1$
          }
!         catch (MalformedURLException ex)
          {
!             return null;
          }
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.sword.AbstractSwordInstaller#download(java.lang.String, java.lang.String, java.net.URL)
       */
!     protected void download(Job job, String dir, String file, URL dest) throws InstallException
      {
          try
          {
!             URL url = new URL("http://" + host + dir + '/' + file); //$NON-NLS-1$
!             copy(job, dest, url);
          }
!         catch (IOException ex)
          {
              throw new InstallException(Msg.UNKNOWN_ERROR, ex);
          }
      }
  
      /**
       * @param job
!      * @param url
!      * @param dest
!      * @throws IOException
       */
!     private void copy(Job job, URL url, URL dest) throws IOException
      {
          InputStream in = null;
***************
*** 185,195 ****
          try
          {
!             job.setProgress(Msg.JOB_DOWNLOADING.toString());
  
!             URL zipurl = new URL("http://" + site + dir); //$NON-NLS-1$
!             File f = File.createTempFile("swd", "zip"); //$NON-NLS-1$ //$NON-NLS-2$
!             out = new FileOutputStream(f);
  
!             URLConnection urlConnection = zipurl.openConnection();
              in = urlConnection.getInputStream();
  
--- 102,114 ----
          try
          {
!             if (job != null)
!             {
!                 job.setProgress(Msg.JOB_DOWNLOADING.toString());
!             }
  
!             // Download the index file
!             out = NetUtil.getOutputStream(dest);
  
!             URLConnection urlConnection = url.openConnection();
              in = urlConnection.getInputStream();
  
***************
*** 199,208 ****
                  out.write(buf, 0, count);
              }
- 
-             IOUtil.unpackZip(f, destdir);
-         }
-         catch (IOException ex)
-         {
-             throw new InstallException(Msg.UNKNOWN_ERROR, ex);
          }
          finally
--- 118,121 ----
***************
*** 214,418 ****
  
      /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#install(org.crosswire.jsword.book.BookMetaData)
-      */
-     public void install(BookMetaData bmd) throws InstallException
-     {
-         if (!(bmd instanceof SwordBookMetaData))
-         {
-             assert false;
-             return;
-         }
- 
-         // Is the book already installed? Then nothing to do.
-         if (Books.installed().getBookMetaData(bmd.getName()) != null)
-         {
-             return;
-         }
- 
-         final SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
- 
-         // So now we know what we want to install - all we need to do
-         // is installer.install(name) however we are doing it in the
-         // background so we create a job for it.
-         final Thread worker = new Thread("DisplayPreLoader") //$NON-NLS-1$
-         {
-             public void run()
-             {
-                 URL predicturl = Project.instance().getWritablePropertiesURL("sword-install"); //$NON-NLS-1$
-                 Job job = JobManager.createJob(Msg.INSTALLING.toString(sbmd.getName()), predicturl, this, true);
- 
-                 try
-                 {
-                     job.setProgress(Msg.JOB_INIT.toString());
- 
-                     URL desturl = toLocalURL(sbmd);
-                     NetUtil.makeDirectory(desturl);
-                     downloadZip(job, host, directory + '/' + PACKAGE_DIR + '/' + sbmd.getInitials() + ZIP_SUFFIX, desturl);
- 
-                     File dldir = SwordBookDriver.getDownloadDir();
-                     job.setProgress(Msg.JOB_CONFIG.toString());
-                     File confdir = new File(dldir, SwordConstants.DIR_CONF);
-                     confdir.mkdirs();
-                     File conf = new File(confdir, sbmd.getDiskName() + SwordConstants.EXTENSION_CONF);
-                     URL configurl = new URL(NetUtil.PROTOCOL_FILE, null, conf.getAbsolutePath());
-                     sbmd.save(configurl);
- 
-                     SwordBookDriver.registerNewBook(sbmd, dldir);
-                 }
-                 catch (Exception ex)
-                 {
-                     Reporter.informUser(this, ex);
-                     job.ignoreTimings();
-                 }
-                 finally
-                 {
-                     job.done();
-                 }
-             }
-         };
- 
-         // this actually starts the thread off
-         worker.setPriority(Thread.MIN_PRIORITY);
-         worker.start();
-     }
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#toURL(org.crosswire.jsword.book.BookMetaData)
-      */
-     public URL toRemoteURL(BookMetaData bmd)
-     {
-         if (!(bmd instanceof SwordBookMetaData))
-         {
-             assert false;
-             return null;
-         }
- 
-         SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
- 
- 	    try
-         {
-             return new URL(NetUtil.PROTOCOL_HTTP, host, directory + '/' + PACKAGE_DIR + '/' + sbmd.getInitials() + ZIP_SUFFIX); //$NON-NLS-1$
-         }
-         catch (MalformedURLException ex)
-         {
-             return null;
-         }
- 	}
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#toLocalURL(org.crosswire.jsword.book.BookMetaData)
-      */
-     public URL toLocalURL(BookMetaData bmd)
-     {
-         File fulldir = toLocalDirectory(bmd);
-         try
-         {
-             return new URL(NetUtil.PROTOCOL_FILE, null, fulldir.getAbsolutePath());
-         }
-         catch (MalformedURLException ex)
-         {
-             assert false;
-             return null;
-         }
- 	}
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#isNewer(org.crosswire.jsword.book.BookMetaData)
-      */
-     public boolean isNewer(BookMetaData bmd)
-     {
-         URL local = toLocalURL(bmd);
-         SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
-         local = NetUtil.lengthenURL(local, sbmd.getDiskName() + SwordConstants.EXTENSION_CONF);
-         URL remote = toRemoteURL(bmd);
-         return NetUtil.isNewer(remote, local);
-     }
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#toLocalURL(org.crosswire.jsword.book.BookMetaData)
-      */
-     public File toLocalDirectory(BookMetaData bmd)
-     {
-         if (!(bmd instanceof SwordBookMetaData))
-         {
-             assert false;
-             return null;
-         }
- 
-         SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
- 
-         ModuleType type = sbmd.getModuleType();
-         String modpath = type.getInstallDirectory();
-         String destname = modpath + '/' + sbmd.getDiskName();
- 
-         File dldir = SwordBookDriver.getDownloadDir();
-         File moddir = new File(dldir, SwordConstants.DIR_DATA);
-         return new File(moddir, destname);
- 	}
- 
-     /* (non-Javadoc)
-      * @see java.lang.Comparable#compareTo(java.lang.Object)
-      */
-     public int compareTo(Object arg0)
-     {
-         HttpSwordInstaller myClass = (HttpSwordInstaller) arg0;
- 
-         int ret = host.compareTo(myClass.host);
-         if (ret != 0)
-         {
-             ret = directory.compareTo(myClass.directory);
-         }
-         return ret;
-     }
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.BookList#addBooksListener(org.crosswire.jsword.book.BooksListener)
-      */
-     public void addBooksListener(BooksListener li)
-     {
-         listeners.add(li);
-     }
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.BookList#removeBooksListener(org.crosswire.jsword.book.BooksListener)
-      */
-     public void removeBooksListener(BooksListener li)
-     {
-         listeners.remove(li);
-     }
- 
-     /**
-      * @return Returns the directory.
-      */
-     public String getDirectory()
-     {
-         return directory;
-     }
- 
-     /**
-      * @param directory The directory to set.
-      */
-     public void setDirectory(String directory)
-     {
-         this.directory = directory;
-     }
- 
-     /**
-      * @return Returns the host.
-      */
-     public String getHost()
-     {
-         return host;
-     }
- 
-     /**
-      * @param host The host to set.
-      */
-     public void setHost(String host)
-     {
-         this.host = host;
-     }
- 
-     /* (non-Javadoc)
       * @see java.lang.Object#equals(java.lang.Object)
       */
--- 127,130 ----
***************
*** 425,434 ****
          HttpSwordInstaller that = (HttpSwordInstaller) object;
  
!         if (!equals(this.host, that.host))
!         {
!             return false;
!         }
! 
!         if (!equals(this.directory, that.directory))
          {
              return false;
--- 137,141 ----
          HttpSwordInstaller that = (HttpSwordInstaller) object;
  
!         if (!super.equals(that))
          {
              return false;
***************
*** 439,599 ****
  
      /**
!      * Quick utility to check to see if 2 (potentially null) strings are equal
!      */
!     private boolean equals(String string1, String string2)
!     {
!         if (string1 == null)
!         {
!             return string2 == null;
!         }
!         return string1.equals(string2);
!     }
! 
!     /**
!      * Load the cached index file into memory
!      */
!     private void loadCachedIndex() throws InstallException
!     {
!         entries.clear();
! 
!         URL cache = getCachedIndexFile();
!         if (!NetUtil.isFile(cache))
!         {
!             reloadBookList();
!         }
! 
!         try
!         {
!             InputStream in = cache.openStream();
!             GZIPInputStream gin = new GZIPInputStream(in);
!             TarInputStream tin = new TarInputStream(gin);
! 
!             while (true)
!             {
!                 TarEntry entry = tin.getNextEntry();
!                 if (entry == null)
!                 {
!                     break;
!                 }
! 
!                 String internal = entry.getName();
!                 if (!entry.isDirectory())
!                 {
!                     try
!                     {
!                         int size = (int) entry.getSize();
!                         byte[] buffer = new byte[size];
!                         tin.read(buffer);
! 
!                         if (internal.endsWith(SwordConstants.EXTENSION_CONF))
!                         {
!                             internal = internal.substring(0, internal.length() - 5);
!                         }
! 
!                         if (internal.startsWith(SwordConstants.DIR_CONF + '/'))
!                         {
!                             internal = internal.substring(7);
!                         }
! 
!                         Reader rin = new InputStreamReader(new ByteArrayInputStream(buffer));
!                         SwordBookMetaData sbmd = new SwordBookMetaData(rin, internal);
! 
!                         if (sbmd.isSupported())
!                         {
!                             entries.put(sbmd.getName(), sbmd);
!                         }
!                     }
!                     catch (Exception ex)
!                     {
!                         log.warn("Failed to load config for entry: " + internal, ex); //$NON-NLS-1$
!                     }
!                 }
!             }
! 
!             IOUtil.close(tin);
!             IOUtil.close(gin);
!             IOUtil.close(in);
! 
!             loaded = true;
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.CACHE_ERROR, ex);
!         }
!     }
! 
!     /**
!      * The URL for the cached index file for this installer
!      */
!     private URL getCachedIndexFile() throws InstallException
!     {
!         try
!         {
!             URL scratchdir = Project.instance().getTempScratchSpace(getTempFileExtension(host, directory), false);
!             return NetUtil.lengthenURL(scratchdir, FILE_LIST_GZ);
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.URL_FAILED, ex);
!         }
!     }
! 
!     /**
!      * What are we using as a temp filename?
!      */
!     private static String getTempFileExtension(String host, String directory)
!     {
!         return DOWNLOAD_PREFIX + host + directory.replace('/', '_'); //$NON-NLS-1$
!     }
! 
!     /**
!      * Do we need to reload the index file
!      */
!     private boolean loaded;
! 
!     /**
!      * A map of the entries in this download area
!      */
!     protected Map entries = new HashMap();
! 
!     /**
!      * The sword index file
!      */
!     private static final String FILE_LIST_GZ = "mods.d.tar.gz"; //$NON-NLS-1$
! 
!     /**
!      * The relative path of the dir holding the index file
!      */
!     private static final String LIST_DIR = "raw"; //$NON-NLS-1$
! 
!     /**
!      * The relative path of the dir holding the zip files
!      */
!     private static final String PACKAGE_DIR = "packages/rawzip"; //$NON-NLS-1$
! 
!     /**
!      * The relative path of the dir holding the search index files
!      */
!     private static final String SEARCH_DIR = "seach/jsword/L1"; //$NON-NLS-1$
! 
!     /**
!      * The suffix of zip modules on this server
!      */
!     private static final String ZIP_SUFFIX = ".zip"; //$NON-NLS-1$
! 
!     /**
!      * When we cache a download index
       */
-     private static final String DOWNLOAD_PREFIX = "download-"; //$NON-NLS-1$
- 
-     private ArrayList listeners = new ArrayList();
-     protected String host;
-     protected String directory;
- 
      private static final String PROTOCOL_WEB = "web"; //$NON-NLS-1$
- 
-     /**
-      * The log stream
-      */
-     private static final Logger log = Logger.getLogger(HttpSwordInstaller.class);
  }
--- 146,151 ----
  
      /**
!      * We need to be ablee to provide a URL as part of the API
       */
      private static final String PROTOCOL_WEB = "web"; //$NON-NLS-1$
  }

Index: FtpSwordInstaller.java
===================================================================
RCS file: /cvs/jsword/jsword/java/jsword/org/crosswire/jsword/book/install/sword/FtpSwordInstaller.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** FtpSwordInstaller.java	10 Oct 2004 22:12:02 -0000	1.8
--- FtpSwordInstaller.java	15 Oct 2004 23:28:08 -0000	1.9
***************
*** 1,42 ****
  package org.crosswire.jsword.book.install.sword;
  
- import java.io.ByteArrayInputStream;
- import java.io.File;
  import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
  import java.io.OutputStream;
- import java.io.Reader;
  import java.net.MalformedURLException;
  import java.net.URL;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.zip.GZIPInputStream;
  
  import org.apache.commons.net.ftp.FTP;
  import org.apache.commons.net.ftp.FTPClient;
- import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.FTPReply;
  import org.crosswire.common.progress.Job;
- import org.crosswire.common.progress.JobManager;
  import org.crosswire.common.util.Logger;
  import org.crosswire.common.util.NetUtil;
- import org.crosswire.common.util.Reporter;
  import org.crosswire.jsword.book.BookMetaData;
- import org.crosswire.jsword.book.Books;
- import org.crosswire.jsword.book.basic.AbstractBookList;
  import org.crosswire.jsword.book.install.InstallException;
- import org.crosswire.jsword.book.install.Installer;
- import org.crosswire.jsword.book.sword.ModuleType;
- import org.crosswire.jsword.book.sword.SwordBookDriver;
  import org.crosswire.jsword.book.sword.SwordBookMetaData;
- import org.crosswire.jsword.book.sword.SwordConstants;
- import org.crosswire.jsword.util.Project;
- 
- import com.ice.tar.TarEntry;
- import com.ice.tar.TarInputStream;
  
  /**
--- 1,18 ----
***************
*** 64,90 ****
   * @version $Id$
   */
! public class FtpSwordInstaller extends AbstractBookList implements Installer, Comparable
  {
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#getIndex()
       */
!     public List getBookMetaDatas()
      {
!         try
!         {
!             if (!loaded)
!             {
!                 loadCachedIndex();
!             }
! 
!             List mutable = new ArrayList();
!             mutable.addAll(entries.values());
!             return Collections.unmodifiableList(mutable);
!         }
!         catch (InstallException ex)
!         {
!             log.error("Failed to reload cached index file", ex); //$NON-NLS-1$
!             return new ArrayList();
!         }
      }
  
--- 40,51 ----
   * @version $Id$
   */
! public class FtpSwordInstaller extends AbstractSwordInstaller implements Comparable
  {
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#getURL()
       */
!     public String getURL()
      {
!         return PROTOCOL_SWORD + ":" + username + ":" + password + "@" + host + directory; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }
  
***************
*** 102,106 ****
          SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
  
! 	    try
          {
              return new URL(NetUtil.PROTOCOL_FTP, host, directory + "/" + sbmd.getInitials() + ZIP_SUFFIX); //$NON-NLS-1$ //$NON-NLS-2$
--- 63,67 ----
          SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
  
!         try
          {
              return new URL(NetUtil.PROTOCOL_FTP, host, directory + "/" + sbmd.getInitials() + ZIP_SUFFIX); //$NON-NLS-1$ //$NON-NLS-2$
***************
*** 110,369 ****
              return null;
          }
- 	}
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#toLocalURL(org.crosswire.jsword.book.BookMetaData)
-      */
-     public URL toLocalURL(BookMetaData bmd)
-     {
-         if (!(bmd instanceof SwordBookMetaData))
-         {
-             assert false;
-             return null;
-         }
- 
-         SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
- 
-         ModuleType type = sbmd.getModuleType();
-         String modpath = type.getInstallDirectory();
-         String destname = modpath + '/' + sbmd.getDiskName();
- 
-         File dldir = SwordBookDriver.getDownloadDir();
-         File moddir = new File(dldir, SwordConstants.DIR_DATA);
-         File fulldir = new File(moddir, destname);
-         try
-         {
-             return new URL(NetUtil.PROTOCOL_FILE, null, fulldir.getAbsolutePath());
-         }
-         catch (MalformedURLException e)
-         {
-             assert false;
-             return null;
-         }
- 	}
- 
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#isNewer(org.crosswire.jsword.book.BookMetaData)
-      */
-     public boolean isNewer(BookMetaData bmd)
-     {
-         URL local = toLocalURL(bmd);
-         URL remote = toRemoteURL(bmd);
-         return NetUtil.isNewer(remote, local);
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#install(java.lang.String)
       */
!     public void install(BookMetaData bmd)
      {
!         if (!(bmd instanceof SwordBookMetaData))
!         {
!             assert false;
!             return;
!         }
! 
!         // Is the book already installed? Then nothing to do.
!         if (Books.installed().getBookMetaData(bmd.getName()) != null)
!         {
!             return;
!         }
! 
!         final SwordBookMetaData sbmd = (SwordBookMetaData) bmd;
  
!         // So now we know what we want to install - all we need to do
!         // is installer.install(name) however we are doing it in the
!         // background so we create a job for it.
!         final Thread worker = new Thread("DisplayPreLoader") //$NON-NLS-1$
          {
!             public void run()
              {
!                 URL predicturl = Project.instance().getWritablePropertiesURL("sword-install"); //$NON-NLS-1$
!                 Job job = JobManager.createJob(Msg.INSTALLING.toString(sbmd.getName()), predicturl, this, true);
! 
!                 yield();
! 
!                 try
!                 {
!                     job.setProgress(Msg.JOB_INIT.toString());
! 
!                     URL desturl = toLocalURL(sbmd);
!                     NetUtil.makeDirectory(desturl);
! 
!                     ModuleType type = sbmd.getModuleType();
!                     String modpath = type.getInstallDirectory();
!                     String destname = modpath + '/' + sbmd.getDiskName();
!                     downloadAll(job, host, USERNAME, PASSWORD, directory + '/' + SwordConstants.DIR_DATA + '/' + destname, desturl);
! 
!                     File dldir = SwordBookDriver.getDownloadDir();
!                     job.setProgress(Msg.JOB_CONFIG.toString());
!                     File confdir = new File(dldir, SwordConstants.DIR_CONF);
!                     confdir.mkdirs();
!                     File conf = new File(confdir, sbmd.getDiskName() + SwordConstants.EXTENSION_CONF);
!                     URL configurl = new URL(NetUtil.PROTOCOL_FILE, null, conf.getAbsolutePath());
!                     sbmd.save(configurl);
! 
!                     SwordBookDriver.registerNewBook(sbmd, dldir);
!                 }
!                 catch (Exception ex)
!                 {
!                     Reporter.informUser(this, ex);
!                     job.ignoreTimings();
!                 }
!                 finally
!                 {
!                     job.done();
!                 }
              }
!         };
! 
!         // this actually starts the thread off
!         worker.setPriority(Thread.MIN_PRIORITY);
!         worker.start();
!     }
! 
!     /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#downloadSearchIndex(org.crosswire.jsword.book.BookMetaData, java.net.URL)
!      */
!     public void downloadSearchIndex(BookMetaData bmd, URL localDest) throws InstallException
!     {
!         Job job = JobManager.createJob(Msg.JOB_DOWNLOADING.toString(), Thread.currentThread(), false);
! 
!         try
!         {
!             String dir = directory + '/' + SEARCH_DIR;
!             download(host, USERNAME, PASSWORD, dir, bmd.getInitials() + ZIP_SUFFIX, localDest);
!         }
!         catch (Exception ex)
!         {
!             job.ignoreTimings();
!             throw new InstallException(Msg.UNKNOWN_ERROR, ex);
!         }
!         finally
!         {
!             job.done();
!         }                
!     }
! 
!     /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.Installer#reloadIndex()
!      */
!     public void reloadBookList() throws InstallException
!     {
!         URL scratchfile = getCachedIndexFile();
!         download(host, USERNAME, PASSWORD, directory, FILE_LIST_GZ, scratchfile);
!         loaded = false;
!     }
! 
!     /**
!      * Load the cached index file into memory
!      */
!     private void loadCachedIndex() throws InstallException
!     {
!         entries.clear();
! 
!         URL cache = getCachedIndexFile();
!         if (!NetUtil.isFile(cache))
!         {
!             reloadBookList();
!         }
!         try
!         {
!             InputStream in = cache.openStream();
!             GZIPInputStream gin = new GZIPInputStream(in);
!             TarInputStream tin = new TarInputStream(gin);
! 
!             while (true)
              {
!                 TarEntry entry = tin.getNextEntry();
!                 if (entry == null)
!                 {
!                     break;
!                 }
! 
!                 String internal = entry.getName();
!                 if (!entry.isDirectory())
!                 {
!                     try
!                     {
!                         int size = (int) entry.getSize();
!                         byte[] buffer = new byte[size];
!                         tin.read(buffer);
! 
!                         if (internal.endsWith(SwordConstants.EXTENSION_CONF))
!                         {
!                             internal = internal.substring(0, internal.length() - 5);
!                         }
!                         if (internal.startsWith(SwordConstants.DIR_CONF + '/'))
!                         {
!                             internal = internal.substring(7);
!                         }
! 
!                         Reader rin = new InputStreamReader(new ByteArrayInputStream(buffer));
!                         SwordBookMetaData sbmd = new SwordBookMetaData(rin, internal);
! 
!                         if (sbmd.isSupported())
!                         {
!                             entries.put(sbmd.getName(), sbmd);
!                         }
!                     }
!                     catch (Exception ex)
!                     {
!                         log.warn("Failed to load config for entry: " + internal, ex); //$NON-NLS-1$
!                     }
!                 }
              }
! 
!             tin.close();
!             gin.close();
!             in.close();
!             loaded = true;
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.CACHE_ERROR, ex);
!         }
!     }
! 
!     /**
!      * The URL for the cached index file for this installer
!      */
!     private URL getCachedIndexFile() throws InstallException
!     {
!         try
!         {
!             URL scratchdir = Project.instance().getTempScratchSpace(getTempFileExtension(host, directory), false);
!             return NetUtil.lengthenURL(scratchdir, FILE_LIST_GZ);
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.URL_FAILED, ex);
!         }
!     }
! 
!     /**
!      * What are we using as a temp filename?
!      */
!     private static String getTempFileExtension(String host, String directory)
!     {
!         return DOWNLOAD_PREFIX + host + directory.replace('/', '_'); //$NON-NLS-1$
!     }
! 
!     /**
!      * Utility to download a file by FTP from a remote site
!      * @param site The place to download from
!      * @param user The user that does the downloading
!      * @param password The password of the above user
!      * @param dir The directory from which to download the file
!      * @param file The file to download
!      * @throws InstallException
!      */
!     private static void download(String site, String user, String password, String dir, String file, URL dest) throws InstallException
!     {
!         FTPClient ftp = new FTPClient();
! 
!         try
!         {
!             ftpInit(ftp, site, user, password, dir);
  
              // Check the download directory exists
--- 71,125 ----
              return null;
          }
      }
  
      /* (non-Javadoc)
!      * @see org.crosswire.jsword.book.install.sword.AbstractSwordInstaller#download(java.lang.String, java.lang.String, java.net.URL)
       */
!     protected void download(Job job, String dir, String file, URL dest) throws InstallException
      {
!         FTPClient ftp = new FTPClient();
  
!         try
          {
!             log.info("Connecting to site=" + host + " dir=" + dir); //$NON-NLS-1$ //$NON-NLS-2$
!             
!             // First connect
!             ftp.connect(host);
!             Thread.yield();
!             
!             log.info(ftp.getReplyString());
!             int reply1 = ftp.getReplyCode();
!             if (!FTPReply.isPositiveCompletion(reply1))
              {
!                 String text1 = ftp.getReplyString();
!                 throw new InstallException(Msg.CONNECT_REFUSED, new Object[] { host, new Integer(reply1), text1 });
              }
!             
!             // Authenticate
!             ftp.login(username, password);
!             Thread.yield();
!             
!             log.info(ftp.getReplyString());
!             reply1 = ftp.getReplyCode();
!             if (!FTPReply.isPositiveCompletion(reply1))
              {
!                 String text2 = ftp.getReplyString();
!                 throw new InstallException(Msg.AUTH_REFUSED, new Object[] { username, new Integer(reply1), text2 });
              }
!             
!             // Change directory
!             ftp.changeWorkingDirectory(dir);
!             Thread.yield();
!             
!             log.info(ftp.getReplyString());
!             reply1 = ftp.getReplyCode();
!             if (!FTPReply.isPositiveCompletion(reply1))
!             {
!                 String text3 = ftp.getReplyString();
!                 throw new InstallException(Msg.CWD_REFUSED, new Object[] { dir, new Integer(reply1), text3 });
!             }
!             
!             ftp.setFileType(FTP.BINARY_FILE_TYPE);
!             Thread.yield();
  
              // Check the download directory exists
***************
*** 389,526 ****
          finally
          {
!             disconnect(ftp);
!         }
!     }
! 
!     /**
!      * Utility to download a file by FTP from a remote site
!      * @param site The place to download from
!      * @param user The user that does the downloading
!      * @param password The password of the above user
!      * @param dir The directory from which to download the file
!      * @throws InstallException
!      */
!     protected static void downloadAll(Job job, String site, String user, String password, String dir, URL destdir) throws InstallException
!     {
!         FTPClient ftp = new FTPClient();
! 
!         try
!         {
!             job.setProgress(Msg.JOB_LOGIN.toString());
!             ftpInit(ftp, site, user, password, dir);
! 
!             job.setProgress(Msg.JOB_DOWNLOADING.toString());
!             downloadContents(destdir, ftp);
!         }
!         catch (InstallException ex)
!         {
!             throw ex;
!         }
!         catch (IOException ex)
!         {
!             throw new InstallException(Msg.UNKNOWN_ERROR, ex);
!         }
!         finally
!         {
!             disconnect(ftp);
!         }
!     }
! 
!     /**
!      * Recursively download the contents of the current ftp directory
!      * to the given url
!      */
!     private static void downloadContents(URL destdir, FTPClient ftp) throws IOException, InstallException
!     {
!         FTPFile[] files = ftp.listFiles();
!         for (int i = 0; i < files.length; i++)
!         {
!             String name = files[i].getName();
!             URL child = NetUtil.lengthenURL(destdir, name);
! 
!             if (files[i].isFile())
              {
!                 OutputStream out = NetUtil.getOutputStream(child);
! 
!                 ftp.retrieveFile(name, out);
!                 Thread.yield();
! 
!                 int reply = ftp.getReplyCode();
!                 if (!FTPReply.isPositiveCompletion(reply))
                  {
!                     String text = ftp.getReplyString();
!                     throw new InstallException(Msg.DOWNLOAD_REFUSED, new Object[] { FILE_LIST_GZ, new Integer(reply), text });
                  }
-                 out.close();
-             }
-             else
-             {
-                 downloadContents(child, ftp);
-             }
-         }
-     }
- 
-     /**
-      * Simple tway to connect to a remote site in preparation for a file listing
-      * or a download.
-      */
-     private static void ftpInit(FTPClient ftp, String site, String user, String password, String dir) throws IOException, InstallException
-     {
-         log.info("Connecting to site=" + site + " dir=" + dir); //$NON-NLS-1$ //$NON-NLS-2$
- 
-         // First connect
-         ftp.connect(site);
-         Thread.yield();
- 
-         log.info(ftp.getReplyString());
-         int reply = ftp.getReplyCode();
-         if (!FTPReply.isPositiveCompletion(reply))
-         {
-             String text = ftp.getReplyString();
-             throw new InstallException(Msg.CONNECT_REFUSED, new Object[] { site, new Integer(reply), text });
-         }
- 
-         // Authenticate
-         ftp.login(user, password);
-         Thread.yield();
- 
-         log.info(ftp.getReplyString());
-         reply = ftp.getReplyCode();
-         if (!FTPReply.isPositiveCompletion(reply))
-         {
-             String text = ftp.getReplyString();
-             throw new InstallException(Msg.AUTH_REFUSED, new Object[] { user, new Integer(reply), text });
-         }
- 
-         // Change directory
-         ftp.changeWorkingDirectory(dir);
-         Thread.yield();
- 
-         log.info(ftp.getReplyString());
-         reply = ftp.getReplyCode();
-         if (!FTPReply.isPositiveCompletion(reply))
-         {
-             String text = ftp.getReplyString();
-             throw new InstallException(Msg.CWD_REFUSED, new Object[] { dir, new Integer(reply), text });
-         }
- 
-         ftp.setFileType(FTP.BINARY_FILE_TYPE);
-         Thread.yield();
-     }
- 
-     /**
-      * Silently close an ftp connection, ignoring any exceptions
-      */
-     private static void disconnect(FTPClient ftp)
-     {
-         if (ftp.isConnected())
-         {
-             try
-             {
-                 ftp.disconnect();
-             }
-             catch (IOException ex2)
-             {
-                 log.error("disconnect error", ex2); //$NON-NLS-1$
              }
          }
--- 145,158 ----
          finally
          {
!             if (ftp.isConnected())
              {
!                 try
                  {
!                     ftp.disconnect();
!                 }
!                 catch (IOException ex2)
!                 {
!                     log.error("disconnect error", ex2); //$NON-NLS-1$
                  }
              }
          }
***************
*** 528,565 ****
  
      /**
-      * @return Returns the directory.
-      */
-     public String getDirectory()
-     {
-         return directory;
-     }
- 
-     /**
-      * @param directory The directory to set.
-      */
-     public void setDirectory(String directory)
-     {
-         this.directory = directory;
-         loaded = false;
-     }
- 
-     /**
-      * @return Returns the host.
-      */
-     public String getHost()
-     {
-         return host;
-     }
- 
-     /**
-      * @param host The host to set.
-      */
-     public void setHost(String host)
-     {
-         this.host = host;
-         loaded = false;
-     }
- 
-     /**
       * @return Returns the password.
       */
--- 160,163 ----
***************
*** 593,604 ****
      }
  
-     /* (non-Javadoc)
-      * @see org.crosswire.jsword.book.install.Installer#getURL()
-      */
-     public String getURL()
-     {
-         return PROTOCOL_SWORD + ":" + username + ":" + password + "@" + host + directory; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-     }
- 
      /**
       * Like getURL() except that we skip the password for display purposes.
--- 191,194 ----
***************
*** 622,631 ****
          FtpSwordInstaller that = (FtpSwordInstaller) object;
  
!         if (!equals(this.host, that.host))
!         {
!             return false;
!         }
! 
!         if (!equals(this.directory, that.directory))
          {
              return false;
--- 212,216 ----
          FtpSwordInstaller that = (FtpSwordInstaller) object;
  
!         if (!super.equals(that))
          {
              return false;
***************
*** 645,660 ****
      }
  
-     /**
-      * Quick utility to check to see if 2 (potentially null) strings are equal
-      */
-     private boolean equals(String string1, String string2)
-     {
-         if (string1 == null)
-         {
-             return string2 == null;
-         }
-         return string1.equals(string2);
-     }
- 
      /* (non-Javadoc)
       * @see java.lang.Object#hashCode()
--- 230,233 ----
***************
*** 662,694 ****
      public int hashCode()
      {
!         return host.hashCode() + directory.hashCode() + username.hashCode() + password.hashCode();
!     }
! 
!     /* (non-Javadoc)
!      * @see java.lang.Comparable#compareTo(java.lang.Object)
!      */
!     public int compareTo(Object object)
!     {
!         FtpSwordInstaller myClass = (FtpSwordInstaller) object;
! 
!         int ret = host.compareTo(myClass.host);
!         if (ret != 0)
!         {
!             ret = directory.compareTo(myClass.directory);
!         }
!         return ret;
      }
  
      /**
-      * Do we need to reload the index file
-      */
-     private boolean loaded;
- 
-     /**
-      * The remote hostname.
-      */
-     protected String host;
- 
-     /**
       * The remote username for a valid account on the <code>host</code>.
       */
--- 235,242 ----
      public int hashCode()
      {
!         return super.hashCode() + username.hashCode() + password.hashCode();
      }
  
      /**
       * The remote username for a valid account on the <code>host</code>.
       */
***************
*** 701,734 ****
  
      /**
-      * The directory containing modules on the <code>host</code>.
-      */
-     protected String directory = "/"; //$NON-NLS-1$
- 
-     /**
-      * A map of the entries in this download area
-      */
-     protected Map entries = new HashMap();
- 
-     /**
-      * The default anon username
-      */
-     private static final String USERNAME = "anonymous"; //$NON-NLS-1$
- 
-     /**
-      * The relative path of the dir holding the search index files
-      */
-     private static final String SEARCH_DIR = "seach/jsword/L1"; //$NON-NLS-1$
- 
-     /**
-      * The default anon password
-      */
-     private static final String PASSWORD = "anon at anon.com"; //$NON-NLS-1$
- 
-     /**
-      * The sword index file
-      */
-     private static final String FILE_LIST_GZ = "mods.d.tar.gz"; //$NON-NLS-1$
- 
-     /**
       * We need to be ablee to provide a URL as part of the API
       */
--- 249,252 ----
***************
*** 736,751 ****
  
      /**
-      * When we cache a download index
-      */
-     private static final String DOWNLOAD_PREFIX = "download-"; //$NON-NLS-1$
- 
-     /**
       * The log stream
       */
      private static final Logger log = Logger.getLogger(FtpSwordInstaller.class);
- 
-     /**
-      * The suffix of zip modules on this server
-      */
-     private static final String ZIP_SUFFIX = ".zip"; //$NON-NLS-1$
  }
--- 254,259 ----



More information about the jsword-svn mailing list