1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2008
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: BookIndexer.java 1466 2007-07-02 02:48:09Z dmsmith $
21   */
22  package org.crosswire.jsword.bridge;
23  
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.crosswire.jsword.book.Book;
28  import org.crosswire.jsword.book.BookException;
29  import org.crosswire.jsword.book.BookFilter;
30  import org.crosswire.jsword.book.BookFilters;
31  import org.crosswire.jsword.book.Books;
32  import org.crosswire.jsword.book.install.InstallException;
33  import org.crosswire.jsword.book.install.InstallManager;
34  import org.crosswire.jsword.book.install.Installer;
35  
36  /**
37   * Exports the Book in SWORD's imp format. This is identical to SWORD's mod2imp.
38   * Note: it does not work with GenBook.
39   * 
40   * @see gnu.lgpl.License for license details.<br>
41   *      The copyright to this program is held by it's authors.
42   * @author DM Smith [dmsmith555 at yahoo dot com]
43   */
44  public class BookInstaller {
45  
46      public BookInstaller() {
47          installManager = new InstallManager();
48      }
49  
50      /**
51       * Uninstall a book.
52       * 
53       * @param book
54       *            the book to delete
55       * @throws BookException
56       */
57      public void deleteBook(Book book) throws BookException {
58          // Make the book unavailable.
59          // This is normally done via listeners.
60          Books.installed().removeBook(book);
61  
62          // Actually do the delete
63          // This should be a call on installer.
64          book.getDriver().delete(book);
65      }
66  
67      /**
68       * Get a list of all known installers.
69       * 
70       * @return the list of installers
71       */
72      public Map<String, Installer> getInstallers() {
73          // Ask the Install Manager for a map of all known remote repositories
74          // sites
75          return installManager.getInstallers();
76      }
77  
78      /**
79       * Get a list of all installed books.
80       * 
81       * @return the list of installed books
82       */
83      public static List<Book> getInstalledBooks() {
84          return Books.installed().getBooks();
85      }
86  
87      /**
88       * Get a list of installed books by BookFilter.
89       * 
90       * @param filter
91       *            The book filter
92       * @see BookFilter
93       * @see Books
94       */
95      public static List<Book> getInstalledBooks(BookFilter filter) {
96          return Books.installed().getBooks(filter);
97      }
98  
99      /**
100      * Get a list of books by CustomFilter specification
101      * 
102      * @param filterSpec
103      *            The filter string
104      * @see BookFilters#getCustom(java.lang.String)
105      * @see Books
106      */
107     public static List<Book> getInstalledBooks(String filterSpec) {
108         return getInstalledBooks(BookFilters.getCustom(filterSpec));
109     }
110 
111     /**
112      * Get a particular installed book by initials.
113      * 
114      * @param bookInitials
115      *            The book name to search for
116      * @return The found book. Null otherwise.
117      */
118     public static Book getInstalledBook(String bookInitials) {
119         return Books.installed().getBook(bookInitials);
120     }
121 
122     /**
123      * Get a list of all known books for an installer.
124      * 
125      * @param repositoryName
126      * @return the list of books at that repository
127      */
128     public List<Book> getRepositoryBooks(String repositoryName) {
129         return installManager.getInstaller(repositoryName).getBooks();
130     }
131 
132     /**
133      * Get a list of books in a repository by BookFilter.
134      * 
135      * @param filter
136      *            The book filter
137      * @see BookFilter
138      * @see Books
139      */
140     public List<Book> getRepositoryBooks(String repositoryName, BookFilter filter) {
141         return installManager.getInstaller(repositoryName).getBooks(filter);
142     }
143 
144     /**
145      * Get a list of books in a repository by CustomFilter specification
146      * 
147      * @param filterSpec
148      *            The filter string
149      * @see BookFilters#getCustom(java.lang.String)
150      * @see Books
151      */
152     public List<Book> getRepositoryBooks(String repositoryName, String filterSpec) {
153         return getRepositoryBooks(repositoryName, BookFilters.getCustom(filterSpec));
154     }
155 
156     /**
157      * Get a particular installed book by initials.
158      * 
159      * @param bookInitials
160      *            The book name to search for
161      * @return The found book. Null otherwise.
162      */
163     public Book getRepositoryBook(String repositoryName, String bookInitials) {
164         return installManager.getInstaller(repositoryName).getBook(bookInitials);
165     }
166 
167     /**
168      * Reload the local cache for a remote repository.
169      * 
170      * @param repositoryName
171      * @throws InstallException
172      */
173     public void reloadBookList(String repositoryName) throws InstallException {
174         installManager.getInstaller(repositoryName).reloadBookList();
175     }
176 
177     /**
178      * Get a Book from the repository. Note this does not install it.
179      * 
180      * @param repositoryName
181      *            the repository from which to get the book
182      * @param bookName
183      *            the name of the book to get
184      * @return the Book
185      */
186     public Book getBook(String repositoryName, String bookName) {
187         return installManager.getInstaller(repositoryName).getBook(bookName);
188     }
189 
190     /**
191      * Install a book, overwriting it if the book to be installed is newer.
192      * 
193      * @param repositoryName
194      *            the name of the repository from which to get the book
195      * @param book
196      *            the book to get
197      * @throws BookException
198      * @throws InstallException
199      */
200     public void installBook(String repositoryName, Book book) throws BookException, InstallException {
201         // An installer knows how to install books
202         Installer installer = installManager.getInstaller(repositoryName);
203 
204         // Delete the book, if present
205         // At the moment, JSword will not re-install. Later it will, if the
206         // remote version is greater.
207         if (Books.installed().getBook(book.getInitials()) != null) {
208             deleteBook(book);
209         }
210 
211         // Now install it. Note this is a background task.
212         installer.install(book);
213     }
214 
215     private InstallManager installManager;
216 
217     /**
218      * BookInstaller can manage the installation of books with the following
219      * capabilities.
220      * 
221      * Usage: BookInstaller [option]<br/>
222      * Options:
223      * <table border="0">
224      * <tr>
225      * <td>uninstall</td>
226      * <td>bookName</td>
227      * <td>Uninstall book</td>
228      * </tr>
229      * <tr>
230      * <td>sources</td>
231      * <td>&nbsp;</td>
232      * <td>List source repositories</td>
233      * </tr>
234      * <tr>
235      * <td>list</td>
236      * <td>&nbsp;</td>
237      * <td>List installed books</td>
238      * </tr>
239      * <tr>
240      * <td>list</td>
241      * <td>repositoryName</td>
242      * <td>list available books from a repository</td>
243      * </tr>
244      * <tr>
245      * <td>reload</td>
246      * <td>repositoryName</td>
247      * <td>Reload the local cache for a repository</td>
248      * </tr>
249      * <tr>
250      * <td>install</td>
251      * <td>repositoryName bookName</td>
252      * <td>Install a book from a repository</td>
253      * </tr>
254      * </table>
255      * 
256      * @param args
257      */
258     public static void main(String[] args) {
259         if (args.length < 1) {
260             usage();
261             return;
262         }
263 
264         System.err.print("BookInstaller");
265         for (int i = 0; i < args.length; i++) {
266             System.err.print(' ');
267             System.err.print(args[i]);
268         }
269         System.err.print('\n');
270 
271         BookInstaller installer = new BookInstaller();
272 
273         String operation = args[0];
274         if (operation.equalsIgnoreCase("uninstall")) {
275             if (args.length == 2) {
276                 Book b = Books.installed().getBook(args[1]);
277                 if (b == null) {
278                     System.err.println("Book not found");
279                     return;
280                 }
281                 try {
282                     installer.deleteBook(b);
283                 } catch (BookException e) {
284                     e.printStackTrace();
285                 }
286             } else {
287                 usage();
288             }
289         } else if (operation.equalsIgnoreCase("sources")) {
290             // Get all the installers one after the other
291             Map<String, Installer> installers = installer.getInstallers();
292             for (String name : installers.keySet()) {
293                 System.out.println(name);
294             }
295         } else if (operation.equalsIgnoreCase("list")) {
296             if (args.length == 1) {
297                 for (Book book : BookInstaller.getInstalledBooks()) {
298                     System.out.println(book.getInitials());
299                 }
300             } else if (args.length == 2) {
301                 for (Book book : installer.getRepositoryBooks(args[1])) {
302                     System.out.println(book.getInitials());
303                 }
304             } else {
305                 usage();
306             }
307         } else if (operation.equalsIgnoreCase("reload")) {
308             if (args.length == 2) {
309                 try {
310                     installer.reloadBookList(args[1]);
311                 } catch (InstallException e) {
312                     e.printStackTrace();
313                 }
314             } else {
315                 usage();
316             }
317         } else if (operation.equalsIgnoreCase("install")) {
318             if (args.length == 3) {
319                 Book b = installer.getBook(args[1], args[2]);
320                 if (b == null) {
321                     System.err.println("Book not found");
322                     return;
323                 }
324                 try {
325                     installer.installBook(args[1], b);
326                 } catch (BookException e) {
327                     e.printStackTrace();
328                 } catch (InstallException e) {
329                     e.printStackTrace();
330                 }
331             } else {
332                 usage();
333             }
334         } else {
335             usage();
336         }
337     }
338 
339     public static void usage() {
340         System.err.println("usage: BookInstaller <option>");
341         System.err.println("Options:");
342         System.err.println("    uninstall bookName                 Uninstall book");
343         System.err.println("    sources                            List remote source repositories");
344         System.err.println("    list                               List installed books");
345         System.err.println("    list      repositoryName           List available books from a repository");
346         System.err.println("    reload    repositoryName           Reload local cache for a repository");
347         System.err.println("    install   repositoryName bookName  Install a book from a repository");
348     }
349 }
350