KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > search > UpdateSearchRequest


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.update.search;
12
13 import java.net.URL JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Set JavaDoc;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.MultiStatus;
23 import org.eclipse.core.runtime.OperationCanceledException;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.core.runtime.SubProgressMonitor;
26 import org.eclipse.osgi.util.NLS;
27 import org.eclipse.update.core.IFeature;
28 import org.eclipse.update.core.IFeatureReference;
29 import org.eclipse.update.core.ISite;
30 import org.eclipse.update.core.ISiteWithMirrors;
31 import org.eclipse.update.core.IURLEntry;
32 import org.eclipse.update.core.SiteManager;
33 import org.eclipse.update.internal.core.ExtendedSite;
34 import org.eclipse.update.internal.core.Messages;
35 import org.eclipse.update.internal.operations.UpdateUtils;
36 import org.eclipse.update.internal.search.SiteSearchCategory;
37 import org.eclipse.update.internal.search.UpdatePolicy;
38 import org.eclipse.update.internal.search.UpdateSiteAdapter;
39 import org.eclipse.update.internal.search.UpdatesSearchCategory;
40
41 /**
42  * This class is central to update search. The search pattern
43  * is encapsulated in update search category, while the search
44  * scope is defined in the scope object. When these two objects
45  * are defined and set, search can be performed using the
46  * provided method. Search results are reported to the
47  * result collector, while search progress is tracked using
48  * the progress monitor.
49  * <p>Classes that implement <samp>IUpdateSearchResultCollector</samp>
50  * should call 'accept' to test if the match should be
51  * accepted according to the filters added to the request.
52  *
53  * <p>
54  * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
55  * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
56  * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
57  * (repeatedly) as the API evolves.
58  * </p>
59  * @see UpdateSearchScope
60  * @see IUpdateSearchCategory
61  * @since 3.0
62  */

63 public class UpdateSearchRequest {
64     private IUpdateSearchCategory category;
65     private UpdateSearchScope scope;
66     private boolean searchInProgress = false;
67     private AggregateFilter aggregateFilter = new AggregateFilter();
68     
69     private static class UpdateSearchSite
70     extends UpdateSiteAdapter
71     implements IUpdateSearchSite {
72     private String JavaDoc[] categoriesToSkip;
73
74     public UpdateSearchSite(
75         String JavaDoc label,
76         URL JavaDoc siteURL,
77         String JavaDoc[] categoriesToSkip) {
78         super(label, siteURL);
79         this.categoriesToSkip = categoriesToSkip;
80     }
81     public String JavaDoc[] getCategoriesToSkip() {
82         return categoriesToSkip;
83     }
84 }
85
86     class MirroredUpdateSiteAdapter extends UpdateSiteAdapter {
87         public MirroredUpdateSiteAdapter(IURLEntry mirror) {
88             super(mirror.getAnnotation(), mirror.getURL());
89         }
90     }
91     
92     class AggregateFilter implements IUpdateSearchFilter {
93         private ArrayList JavaDoc filters;
94         public void addFilter(IUpdateSearchFilter filter) {
95             if (filters == null)
96                 filters = new ArrayList JavaDoc();
97             if (filters.contains(filter) == false)
98                 filters.add(filter);
99         }
100         
101         public void removeFilter(IUpdateSearchFilter filter) {
102             if (filters == null)
103                 return;
104             filters.remove(filter);
105         }
106     
107         /**
108          * @deprecated In 3.1 only the accept (IFeatureReference) will be used
109          */

110         public boolean accept(IFeature match) {
111             if (filters == null)
112                 return true;
113             for (int i = 0; i < filters.size(); i++) {
114                 IUpdateSearchFilter filter = (IUpdateSearchFilter) filters.get(i);
115                 if (filter.accept(match) == false)
116                     return false;
117             }
118             return true;
119         }
120         
121         public boolean accept(IFeatureReference match) {
122             if (filters == null)
123                 return true;
124             for (int i = 0; i < filters.size(); i++) {
125                 IUpdateSearchFilter filter = (IUpdateSearchFilter) filters.get(i);
126                 if (filter.accept(match) == false)
127                     return false;
128             }
129             return true;
130         }
131     }
132
133     /**
134      * Returns an updates search category for use in discovering updates
135      * to existing function on update sites.
136      *
137      * @return an updates search category
138      * @since 3.1
139      */

140     public static IUpdateSearchCategory createDefaultUpdatesSearchCategory() {
141         return new UpdatesSearchCategory();
142     }
143     
144     /**
145      * Returns a site search category for use in discovering new function on update sites.
146      *
147      * @return a site search category
148      * @since 3.1
149      */

150     public static IUpdateSearchCategory createDefaultSiteSearchCategory() {
151         return new SiteSearchCategory();
152     }
153     
154     /**
155      * The constructor that accepts the search category and
156      * scope objects.
157      * @param category the actual search pattern that should be applied
158      * @param scope a list of sites that need to be scanned during the search
159      */

160     public UpdateSearchRequest(
161         IUpdateSearchCategory category,
162         UpdateSearchScope scope) {
163         this.category = category;
164         this.scope = scope;
165     }
166     /**
167      * Returns the search catagory used in this request.
168      * @return the search category
169      */

170     
171     public IUpdateSearchCategory getCategory() {
172         return category;
173     }
174     
175     /**
176      * Returns the scope of this search request.
177      * @return search scope
178      */

179     
180     public UpdateSearchScope getScope() {
181         return scope;
182     }
183     /**
184      * Adds a filter to this request. This method does nothing
185      * if search is alrady in progress.
186      * @param filter the filter
187      * @see UpdateSearchRequest#removeFilter
188      */

189     public void addFilter(IUpdateSearchFilter filter) {
190         if (searchInProgress)
191             return;
192         aggregateFilter.addFilter(filter);
193     }
194     /**
195      * Removes the filter from this request. This method does
196      * nothing if search is alrady in progress.
197      * @param filter the filter to remove
198      * @see UpdateSearchRequest#addFilter
199      */

200
201     public void removeFilter(IUpdateSearchFilter filter) {
202         if (searchInProgress)
203             return;
204         aggregateFilter.removeFilter(filter);
205     }
206
207     /**
208      * Sets the scope object. It is possible to reuse the search request
209      * object by modifying the scope and re-running the search.
210      * @param scope the new search scope
211      */

212     public void setScope(UpdateSearchScope scope) {
213         this.scope = scope;
214     }
215     /**
216      * Tests whether this search request is current running.
217      * @return <samp>true</samp> if the search is currently running, <samp>false</samp> otherwise.
218      */

219     public boolean isSearchInProgress() {
220         return searchInProgress;
221     }
222
223     /**
224      * Runs the search using the category and scope configured into
225      * this request. As results arrive, they are passed to the
226      * search result collector object.
227      * @param collector matched features are passed to this object
228      * @param monitor used to track the search progress
229      * @throws CoreException
230      */

231     public void performSearch(
232         IUpdateSearchResultCollector collector,
233         IProgressMonitor monitor)
234         throws CoreException, OperationCanceledException {
235         
236         ArrayList JavaDoc statusList = new ArrayList JavaDoc();
237
238         searchInProgress = true;
239         IUpdateSearchQuery[] queries = category.getQueries();
240         IUpdateSearchSite[] candidates = scope.getSearchSites();
241         Set JavaDoc visitedSitesURL = new HashSet JavaDoc();
242         Set JavaDoc visitedSites = new HashSet JavaDoc();
243         for(int i = 0; i < candidates.length; i++) {
244             visitedSitesURL.add(candidates[i].getURL());
245             //visitedSites.add(candidates[i]);
246
}
247         URL JavaDoc updateMapURL = scope.getUpdateMapURL();
248         boolean searchFeatureProvidedSites = scope.isFeatureProvidedSitesEnabled();
249
250         if (!monitor.isCanceled()) {
251             
252             int nsearchsites = 0;
253             try {
254             for (int i = 0; i < queries.length; i++) {
255                 if (queries[i].getQuerySearchSite() != null)
256                     nsearchsites++;
257             }
258             } catch (Throwable JavaDoc t) {
259                 t.printStackTrace();
260                 
261             }
262             
263             int ntasks = nsearchsites + queries.length * candidates.length;
264             if (updateMapURL!=null) ntasks++;
265
266             monitor.beginTask(Messages.UpdateSearchRequest_searching, ntasks);
267             
268             try {
269                 UpdatePolicy updatePolicy=null;
270                 if (updateMapURL!=null) {
271                     updatePolicy = new UpdatePolicy();
272                     IStatus status =UpdateUtils.loadUpdatePolicy(updatePolicy, updateMapURL, new SubProgressMonitor(monitor, 1));
273                     if (status != null)
274                         statusList.add(status);
275                 }
276                 
277                 List JavaDoc combinedAssociateSites = new ArrayList JavaDoc();
278                 for (int i = 0; i < queries.length; i++) {
279                     IUpdateSearchQuery query = queries[i];
280                     IQueryUpdateSiteAdapter qsite = query.getQuerySearchSite();
281                     // currently, the next conditional is only executed (qsite!=null) when
282
// running an update search.
283
if (qsite != null && searchFeatureProvidedSites) {
284                         // do not update features that are installed in read-only locations
285
if (query instanceof UpdatesSearchCategory.UpdateQuery) {
286                             IFeature feature = ((UpdatesSearchCategory.UpdateQuery)query).getFeature();
287                             if (feature != null && !feature.getSite().getCurrentConfiguredSite().verifyUpdatableStatus().isOK())
288                                 continue;
289                         }
290                         // check for mapping
291
IUpdateSiteAdapter mappedSite = getMappedSite(updatePolicy, qsite);
292                         // when there is no mapped site the feature is not updatable
293
if (mappedSite == null || mappedSite.getURL() == null)
294                             continue;
295                         SubProgressMonitor subMonitor =
296                             new SubProgressMonitor(monitor, 1);
297                         List JavaDoc associateSites = new ArrayList JavaDoc();
298                         IStatus status =
299                             searchOneSite(
300                                 mappedSite,
301                                 null,
302                                 query,
303                                 collector,
304                                 associateSites,
305                                 subMonitor,
306                                 true);
307                         if (status != null)
308                             statusList.add(status);
309                         if (monitor.isCanceled())
310                             break;
311                         combinedAssociateSites = combineAssociateSites( combinedAssociateSites, associateSites, visitedSitesURL, visitedSites);
312                     }
313                     
314                     for (int j = 0; j < candidates.length; j++) {
315                         if (monitor.isCanceled()) {
316                             break;
317                         }
318                         IUpdateSearchSite source = candidates[j];
319                         SubProgressMonitor subMonitor =
320                             new SubProgressMonitor(monitor, 1);
321                         List JavaDoc associateSites = new ArrayList JavaDoc();
322                         IStatus status =
323                             searchOneSite(
324                                 source,
325                                 source.getCategoriesToSkip(),
326                                 query,
327                                 collector,
328                                 associateSites,
329                                 subMonitor,
330                                 true);
331                         if (status != null)
332                             statusList.add(status);
333                         combinedAssociateSites = combineAssociateSites( combinedAssociateSites, associateSites, visitedSitesURL, visitedSites);
334                     }
335                     if (monitor.isCanceled())
336                         break;
337                     
338                     
339                     for(int associateSitesDepth = 0; associateSitesDepth < 5; associateSitesDepth++) {
340                         List JavaDoc tempCombinedSites = new ArrayList JavaDoc();
341                         Iterator JavaDoc combinedAssociateSitesIterator = combinedAssociateSites.iterator();
342                         while(combinedAssociateSitesIterator.hasNext()) {
343                             
344                             IUpdateSearchSite source = (IUpdateSearchSite)combinedAssociateSitesIterator.next();
345                             
346                             List JavaDoc associateSites = new ArrayList JavaDoc();
347                             SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
348                             IStatus status =
349                                 searchOneSite(
350                                     source,
351                                     source.getCategoriesToSkip(),
352                                     query,
353                                     collector,
354                                     associateSites,
355                                     subMonitor,
356                                     true);
357                             combinedAssociateSites = combineAssociateSites( tempCombinedSites, associateSites, visitedSitesURL, visitedSites);
358                             if (status != null)
359                                 statusList.add(status);
360                         }
361                         combinedAssociateSites = tempCombinedSites;
362                         
363                     }
364                     if (monitor.isCanceled())
365                         break;
366                 }
367             } catch (CoreException e) {
368                 searchInProgress = false;
369                 monitor.done();
370                 throw e;
371             }
372         }
373         searchInProgress = false;
374         monitor.done();
375         
376
377         Iterator JavaDoc visitedSitesIterator = visitedSites.iterator();
378         while (visitedSitesIterator.hasNext()) {
379             IUpdateSearchSite associateSite = (IUpdateSearchSite)visitedSitesIterator.next();
380             scope.addSearchSite(associateSite.getLabel(), associateSite.getURL(), null);
381         }
382         if (statusList.size() > 0) {
383             if (statusList.size()==1 && ((IStatus)statusList.get(0)).getSeverity()==IStatus.CANCEL)
384                 throw new OperationCanceledException();
385             IStatus[] children =
386                 (IStatus[]) statusList.toArray(new IStatus[statusList.size()]);
387             MultiStatus multiStatus =
388                 new MultiStatus(
389                     "org.eclipse.update.core", //$NON-NLS-1$
390
ISite.SITE_ACCESS_EXCEPTION,
391                     children,
392                     Messages.Search_networkProblems,
393                     null);
394             
395             throw new CoreException(multiStatus);
396         }
397     }
398
399
400     private List JavaDoc combineAssociateSites(List JavaDoc combinedAssociateSites, List JavaDoc associateSites, Set JavaDoc visitedSitesURL, Set JavaDoc visitedSites) {
401         Iterator JavaDoc iterator = associateSites.iterator();
402
403         while(iterator.hasNext()) {
404             UpdateSearchSite associateSite = (UpdateSearchSite)iterator.next();
405             if ( !visitedSitesURL.contains(associateSite.getURL())) {
406                 combinedAssociateSites.add(associateSite);
407                 visitedSitesURL.add(associateSite.getURL());
408                 visitedSites.add(associateSite);
409             }
410             
411         }
412         return combinedAssociateSites;
413     }
414
415
416 /*
417  * See if this query site adapter is mapped in the map file
418  * to a different URL.
419  */

420     private IUpdateSiteAdapter getMappedSite(UpdatePolicy policy, IQueryUpdateSiteAdapter qsite) {
421         if (policy!=null && policy.isLoaded()) {
422             IUpdateSiteAdapter mappedSite = policy.getMappedSite(qsite.getMappingId());
423             if (mappedSite!=null)
424                 return mappedSite;
425             else // no match - use original site if fallback allowed, or nothing.
426
return policy.isFallbackAllowed()? qsite : null;
427         }
428         return qsite;
429     }
430
431 /*
432  * Search one site using the provided query.
433  */

434     private IStatus searchOneSite(
435         IUpdateSiteAdapter siteAdapter,
436         String JavaDoc[] categoriesToSkip,
437         IUpdateSearchQuery query,
438         IUpdateSearchResultCollector collector,
439         List JavaDoc associateSites,
440         SubProgressMonitor monitor,
441         boolean checkMirrors)
442         throws CoreException {
443         
444         String JavaDoc text = NLS.bind(Messages.UpdateSearchRequest_contacting, siteAdapter.getLabel());
445         monitor.subTask(text);
446         monitor.beginTask("", 10); //$NON-NLS-1$
447
URL JavaDoc siteURL = siteAdapter.getURL();
448
449         ISite site;
450         try {
451             site =
452                 SiteManager.getSite(
453                     siteURL,
454                     new SubProgressMonitor(monitor, 1));
455             
456             // If frozen connection was canceled, there will be no site.
457
if (site == null) {
458                 monitor.worked(9);
459                 return null;
460             }
461             
462             
463             // prompt the user to pick up a site (do not recursively go into mirror sites on the mirror site)
464
if ((collector instanceof IUpdateSearchResultCollectorFromMirror) &&
465                 (site instanceof ISiteWithMirrors) &&
466                 !(siteAdapter instanceof MirroredUpdateSiteAdapter)) {
467                 
468                 IURLEntry mirror = null;
469                 try {
470                     mirror = ((IUpdateSearchResultCollectorFromMirror)collector).getMirror((ISiteWithMirrors)site, siteAdapter.getLabel());
471                     if (site instanceof ExtendedSite) {
472                         ((ExtendedSite)site).setSelectedMirror(mirror);
473                     }
474                 }
475                 catch (OperationCanceledException e) {
476                     monitor.setCanceled(true);
477                     return Status.CANCEL_STATUS;
478                 }
479                 
480                 if (mirror != null)
481                     return searchOneSite(new MirroredUpdateSiteAdapter(mirror), categoriesToSkip, query, collector, associateSites, new SubProgressMonitor(monitor,1), false);
482             }
483         } catch (CoreException e) {
484             // Test the exception. If the exception is
485
// due to the site connection problems,
486
// allow the search to move on to
487
// the next site. Otherwise,
488
// rethrow the exception, causing the search
489
// to terminate.
490
IStatus status = e.getStatus();
491             if (status == null)
492 // || status.getCode() != ISite.SITE_ACCESS_EXCEPTION)
493
throw e;
494             monitor.worked(10);
495             return status;
496         }
497
498         text = NLS.bind(Messages.UpdateSearchRequest_checking, siteAdapter.getLabel());
499         monitor.getWrappedProgressMonitor().subTask(text);
500
501         if (site instanceof ExtendedSite) {
502             //System.out.println("ExtendedSite is here"); //$NON-NLS-1$
503
IURLEntry[] associateSitesList = ((ExtendedSite)site).getAssociateSites();
504             if (associateSitesList != null) {
505                 for(int i = 0; i < associateSitesList.length; i++) {
506                     associateSites.add(new UpdateSearchSite(associateSitesList[i].getAnnotation(), associateSitesList[i].getURL(), null));
507                 }
508             }
509         }
510         query.run(
511             site,
512             categoriesToSkip,
513             aggregateFilter,
514             collector,
515             new SubProgressMonitor(monitor, 9));
516         return null;
517     }
518 }
519
Popular Tags