Coverage Report - org.paneris.bibliomania.metasearch.Metasearch
 
Classes in this File Line Coverage Branch Coverage Complexity
Metasearch
0%
0/32
0%
0/8
2.636
Metasearch$1
N/A
N/A
2.636
Metasearch$HitsEnumeration
0%
0/22
0%
0/8
2.636
Metasearch$SearchThread
0%
0/28
0%
0/4
2.636
 
 1  
 package org.paneris.bibliomania.metasearch;
 2  
 
 3  
 import java.util.Enumeration;
 4  
 import java.util.NoSuchElementException;
 5  
 import java.util.Vector;
 6  
 
 7  
 import org.melati.poem.transaction.ToTidyList;
 8  
 import org.paneris.bibliomania.BookStocking;
 9  
 import org.paneris.bibliomania.Bookshop;
 10  
 
 11  0
 public class Metasearch implements ToTidyList.Closeable {
 12  
 
 13  
   private Bookshop[] shops;
 14  
   private String title;
 15  
   private String author;
 16  
   private ToTidyList toTidy;
 17  
   private SearchThread[] threads;
 18  0
   private Vector results = new Vector();
 19  0
   private int runningThreads = 0;
 20  
 
 21  
   private class SearchThread extends Thread {
 22  
     private Bookshop shop;
 23  
 
 24  0
     public SearchThread(Bookshop shop) {
 25  0
       this.shop = shop;
 26  0
     }
 27  
 
 28  
     public void run() {
 29  
       try {
 30  0
         Enumeration books =
 31  
           shop.backend.booksMatching(shop, title, author, "", "", toTidy);
 32  0
         while (books.hasMoreElements()) {
 33  0
           BookStocking stocking = (BookStocking)books.nextElement();
 34  0
           shop.backend.resolve(stocking);
 35  0
           synchronized (results) {
 36  0
             results.addElement(stocking);
 37  0
             results.notifyAll();
 38  0
           }
 39  0
         }
 40  0
       } catch (Exception e) {
 41  0
         System.err.println("Metasearch.SearchThread: " + e);
 42  
       } finally {
 43  0
         synchronized (results) {
 44  0
           --runningThreads;
 45  0
           results.notifyAll();
 46  0
           if (runningThreads <= 0) {
 47  0
             synchronized (Metasearch.this) {
 48  0
               Metasearch.this.notifyAll();
 49  0
             }
 50  
           }
 51  0
         }
 52  0
       }
 53  0
     }
 54  
 
 55  
     public void close() {
 56  
       try {
 57  0
         stop();
 58  0
       } catch (Exception e) {
 59  0
       }
 60  0
     }
 61  
   }
 62  
 
 63  0
   private class HitsEnumeration implements Enumeration {
 64  
 
 65  0
     private int nextResultIndex = 0;
 66  0
     private Object next = null;
 67  
 
 68  
     public boolean hasMoreElements() {
 69  
       try {
 70  0
         synchronized (results) {
 71  0
           if (next != null)
 72  0
             return true;
 73  
 
 74  0
           while (nextResultIndex >= results.size()) {
 75  0
             if (runningThreads <= 0)
 76  0
               return false;
 77  0
             results.wait();
 78  
           }
 79  
 
 80  0
           next = results.elementAt(nextResultIndex++);
 81  0
           return true;
 82  0
         }
 83  0
       } catch (InterruptedException e) {
 84  0
         return false;
 85  
       }
 86  
     }
 87  
 
 88  
     public Object nextElement() {
 89  0
       synchronized (results) {
 90  0
         if (hasMoreElements()) {
 91  0
           Object it = next;
 92  0
           next = null;
 93  0
           return it;
 94  
         } else
 95  0
           throw new NoSuchElementException("No more search hits");
 96  0
       }
 97  
     }
 98  
   }
 99  
 
 100  
   public Metasearch(
 101  
     Bookshop[] shopsP,
 102  
     String title,
 103  
     String author,
 104  0
     ToTidyList toTidy) {
 105  0
     this.shops = shopsP;
 106  0
     this.title = title;
 107  0
     this.author = author;
 108  0
     this.toTidy = toTidy;
 109  
 
 110  0
     threads = new SearchThread[shops.length];
 111  0
     if (toTidy != null)
 112  0
       toTidy.add(this);
 113  
 
 114  0
     for (int s = 0; s < shops.length; ++s) {
 115  0
       (threads[s] = new SearchThread(shops[s])).start();
 116  0
       synchronized (results) {
 117  0
         ++runningThreads;
 118  0
       }
 119  
     }
 120  0
   }
 121  
 
 122  
   public Enumeration currentAndFutureResults() {
 123  0
     return new HitsEnumeration();
 124  
   }
 125  
 
 126  
   public Vector currentResults() {
 127  0
     return results;
 128  
   }
 129  
 
 130  
   public boolean running() {
 131  0
     return runningThreads > 0;
 132  
   }
 133  
 
 134  
   public void close() {
 135  
     try {
 136  0
       for (int i = 0; i < threads.length; ++i)
 137  
         try {
 138  0
           threads[i].stop();
 139  0
         } catch (Exception e) {
 140  0
         }
 141  
     } finally {
 142  0
       synchronized (this) {
 143  0
         runningThreads = 0;
 144  0
         notifyAll();
 145  0
       }
 146  0
     }
 147  0
   }
 148  
 
 149  
   protected void finalize() throws Throwable {
 150  0
     close();
 151  0
   }
 152  
 }