Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/fetish/directory/Search.java


1   package com.fetish.directory;
2   
3   import java.util.Vector;
4   import net.jini.core.lookup.ServiceMatches;
5   import net.jini.core.lookup.ServiceItem;
6   import net.jini.core.lookup.ServiceID;
7   
8   /**
9    * Class with information about a search process. <br>
10   * It holds the responses from all asked FADA nodes.
11   */
12  public class Search {
13  
14    private Object lock;
15    private Object lockpending;
16    private long maxWaitTime;
17    private Vector pendingThreads;
18    private long expiryDate;
19  
20    public static final long MAX_WAIT_TIME = 10000;
21     
22     /** This search identifier */
23    SearchID searchID;
24     
25     /** Number of pending searches */
26    long pending = 0;
27  
28     /** Vector of ServiceItem elements with services found for this search */
29    private Vector results;
30  
31     /** Maximum number of responses */
32      int maxResponses = Integer.MAX_VALUE;
33  
34    /**
35     * Constructs a new Search object with the specified SearchID and default maximum wait time.
36     */
37    public Search( SearchID id, int maxResponses ) {
38      this.lock = new Object();
39      this.lockpending = new Object();
40      this.pending = 0;
41         this.searchID = id;
42         this.results = new Vector( 0, 1 );
43         this.pendingThreads = new Vector( 0, 1 );
44         this.maxWaitTime = MAX_WAIT_TIME;
45         this.maxResponses = maxResponses;
46         this.expiryDate = System.currentTimeMillis();
47    }
48  
49    /**
50     * Constructs a new Search object with the specified SearchID and maximum wait time.
51     */
52    public Search( SearchID id, long maxWaitTime, int maxResponses ) {
53      this.lock = new Object();
54      this.lockpending = new Object();
55      this.pending = 0;
56         this.searchID = id;
57         this.results = new Vector( 0, 1 );
58         this.pendingThreads = new Vector( 0, 1 );
59         this.maxWaitTime = maxWaitTime;
60         this.maxResponses = maxResponses;
61         this.expiryDate = System.currentTimeMillis();
62    }
63  
64    // Do we need this one?
65    //public Search( SearchID id, long numSearches ) {
66      //this.lock = new Object();
67      //this.pending = numSearches;
68      //this.searchID = id;
69      //this.results = new Vector( 0, 1 );
70    //}
71    /**
72     * Adds <code>started</code> to the amount of started searches to wait
73     * results from.<br>
74     */
75    public void startedSearches( int started ) {
76      synchronized( this.lockpending ) {
77        this.pending += started;
78      }
79    }
80  
81    /**
82     * Adds one to the amount of started searches for the FADA node identified
83     * by <code>sid</code> ServiceID.<br>
84     */
85    public void startedSearches( ServiceID sid ) {
86      if( !this.pendingThreads.contains( sid ) ) {
87        this.pendingThreads.add( sid );
88      }
89    }
90     
91    /**
92     * Obtains the SearchID for this Search object
93     */
94    public SearchID getSearchID() {
95      return this.searchID;
96    }
97  
98    /**
99     * Obtains the expiry date for this Search object
100    */
101   public long getExpiryDate() {
102     return this.expiryDate;
103   }
104 
105   /**
106    * Sets the expiry date for this Search object
107    */
108   public void setExpiryDate( long date ) {
109     this.expiryDate = date;
110   }
111 
112   /**
113    * Puts obtained results in this Search object.<br>
114    * This method decreases the count of started searches to allow
115    * early return of the <code>getResults</code> method.
116    */
117   public synchronized void addResult (ServiceMatches sm) {
118 
119      // extract the serviceItems from the serviceMatches
120     if (sm != null) {
121       for (int i=0; i<sm.totalMatches; i++) {
122         results.addElement(sm.items[i]); 
123       }
124     } else
125     synchronized( this.lockpending ) {
126       pending--;
127       if ( /*( pending <= 0 ) ||*/ ( this.maxResponses <= results.size() ) ) {
128         synchronized( this.lock ) {
129           this.lock.notify();
130         }
131       } else {
132       }
133     }
134   }
135 
136   /**
137    * Puts obtained results in this Search object for the FADA node
138    * identified by <code>sid</code> ServiceID.
139    * This method decreases the count of started searches to allow
140    * early return of the <code>getResults</code> method.
141    */
142   public synchronized void addResult ( ServiceID sid, ServiceMatches sm ) {
143     // Add results on Search object
144     if( this.pendingThreads.contains( sid ) ) {
145       this.pendingThreads.remove( sid );
146       synchronized( this.lockpending ) {
147         pending--;
148         if ( /*( pending <= 0 ) ||*/ ( this.maxResponses <= results.size() ) ) {
149           synchronized( this.lock ) {
150             this.lock.notify();
151           }
152         }
153       }
154     }
155   }
156 
157   /**
158    * Announces that a search process for this Search has finished.
159    * This method decreases the count of started searches for this
160    * Search object.
161    */
162   public void finishedSearch() {
163     synchronized( this.lockpending ) {
164       pending--;
165       //if( pending <= 0 ) {
166       // No more pending threads on this search id
167         //synchronized( this.lock ) {
168           //this.lock.notify();
169         //}
170       //}
171     }
172   }
173 
174   /**
175    * Obtains the results of the search process.
176    * This method blocks the calling thread until the search process has
177    * finished, which happens when:<p>
178    * <ul>
179    * <li>The amount of responses reaches <i>maxResponses OR</i></li>
180    * <li>maxWaitTime milliseconds have passed since call to this 
181    * method <i>OR</i></li>
182    * <li>All started search threads have finished</li>
183    * </ul>
184    * @return The ServiceMatches class for the results of the search.
185    */
186   public ServiceMatches getResults() {
187       
188     try {
189       synchronized( this.lock ) {
190         this.lock.wait( this.maxWaitTime );
191       }
192     } catch( InterruptedException e ) {
193     }
194 
195     // construct a serviceMatches from the serviceItem elements
196          
197     // In order to maintain Jini semantics, a null array must be the 
198     // items array if no result is found ( Vector.toArray() constructs
199     // a 0 elements array when Vector has no elements
200 
201     ServiceItem[] items = null;
202     if ( results.size() > 0 ) {
203       items = ( ServiceItem[] )results.toArray(
204         new ServiceItem[ results.size() ]
205       );
206     }
207 
208     return new ServiceMatches( items, results.size() );
209   }
210 /*
211   public boolean equals(Object o) {
212      if ( o instanceof Search ) {
213         return ((Search)o).equals(this.id);
214      }
215      return false;
216   }
217 */
218 }