KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > search > UpdatesSearchCategory


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.internal.search;
12
13 import java.util.ArrayList JavaDoc;
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.PluginVersionIdentifier;
18 import org.eclipse.core.runtime.Preferences;
19 import org.eclipse.update.configuration.IConfiguredSite;
20 import org.eclipse.update.configuration.IInstallConfiguration;
21 import org.eclipse.update.configuration.ILocalSite;
22 import org.eclipse.update.core.IFeature;
23 import org.eclipse.update.core.IFeatureReference;
24 import org.eclipse.update.core.IIncludedFeatureReference;
25 import org.eclipse.update.core.ISite;
26 import org.eclipse.update.core.ISiteFeatureReference;
27 import org.eclipse.update.core.IURLEntry;
28 import org.eclipse.update.core.IUpdateConstants;
29 import org.eclipse.update.core.SiteManager;
30 import org.eclipse.update.core.VersionedIdentifier;
31 import org.eclipse.update.internal.core.Messages;
32 import org.eclipse.update.internal.core.UpdateCore;
33 import org.eclipse.update.internal.operations.FeatureHierarchyElement;
34 import org.eclipse.update.internal.operations.UpdateUtils;
35 import org.eclipse.update.operations.IInstallFeatureOperation;
36 import org.eclipse.update.operations.OperationsManager;
37 import org.eclipse.update.search.IQueryUpdateSiteAdapter;
38 import org.eclipse.update.search.IUpdateSearchFilter;
39 import org.eclipse.update.search.IUpdateSearchQuery;
40 import org.eclipse.update.search.IUpdateSearchResultCollector;
41
42 public class UpdatesSearchCategory extends BaseSearchCategory {
43     private static final String JavaDoc CATEGORY_ID =
44         "org.eclipse.update.core.new-updates"; //$NON-NLS-1$
45
private IFeature [] features;
46     private boolean automatic;
47
48     class Candidate {
49         ArrayList JavaDoc children;
50         Candidate parent;
51         IFeatureReference ref;
52         public Candidate(IFeatureReference ref) {
53             this.ref = ref;
54         }
55         public Candidate(IFeatureReference ref, Candidate parent) {
56             this(ref);
57             this.parent = parent;
58         }
59         public void add(Candidate child) {
60             if (children == null)
61                 children = new ArrayList JavaDoc();
62             child.setParent(this);
63             children.add(child);
64         }
65         void setParent(Candidate parent) {
66             this.parent = parent;
67         }
68         public IFeatureReference getReference() {
69             return ref;
70         }
71         void setReference(IFeatureReference ref) {
72             this.ref = ref;
73         }
74         public IFeature getFeature(IProgressMonitor monitor) {
75             try {
76                 return ref.getFeature(monitor);
77             } catch (CoreException e) {
78                 return null;
79             }
80         }
81         public Candidate getParent() {
82             return parent;
83         }
84         public Candidate getRoot() {
85             Candidate root = this;
86
87             while (root.getParent() != null) {
88                 root = root.getParent();
89             }
90             return root;
91         }
92         public IURLEntry getUpdateEntry() {
93             int location = IUpdateConstants.SEARCH_ROOT;
94
95             if (ref instanceof IIncludedFeatureReference)
96                 location =
97                     ((IIncludedFeatureReference) ref).getSearchLocation();
98             if (parent == null || location == IUpdateConstants.SEARCH_SELF) {
99                 return getFeature(null).getUpdateSiteEntry();
100             }
101             return getRoot().getUpdateEntry();
102         }
103         public String JavaDoc toString() {
104             return ref.toString();
105         }
106         public boolean equals(Object JavaDoc source) {
107             if (source instanceof Candidate) {
108                 return this.ref.equals(((Candidate) source).getReference());
109             }
110             if (source instanceof IFeatureReference) {
111                 return this.ref.equals(source);
112             }
113             return false;
114         }
115         public void addToFlatList(ArrayList JavaDoc list, boolean updatableOnly) {
116             // add itself
117
if (!updatableOnly || isUpdatable())
118                 list.add(this);
119             // add children
120
if (children != null) {
121                 for (int i = 0; i < children.size(); i++) {
122                     Candidate child = (Candidate) children.get(i);
123                     child.addToFlatList(list, updatableOnly);
124                 }
125             }
126         }
127         public boolean isUpdatable() {
128             return (parent == null);
129         }
130     }
131
132     private static class Hit {
133         IFeature candidate;
134         IFeatureReference ref;
135         IInstallFeatureOperation patchFor;
136         boolean patch;
137         IInstallFeatureOperation job;
138         
139         public Hit(IFeature candidate, IFeatureReference ref) {
140             this.candidate = candidate;
141             this.ref = ref;
142         }
143         public Hit(IFeature candidate, IFeatureReference ref, boolean patch) {
144             this(candidate, ref);
145             this.patch = patch;
146         }
147
148         public Hit(IFeature candidate, IFeatureReference ref, IInstallFeatureOperation patchFor) {
149             this(candidate, ref, true);
150             this.patchFor = patchFor;
151         }
152
153         public IInstallFeatureOperation getJob() {
154             if (job == null) {
155                 try {
156                     IFeature feature = ref.getFeature(null);
157                     job = OperationsManager.getOperationFactory().createInstallOperation(null, feature, null, null, null);
158                 } catch (CoreException e) {
159                     UpdateCore.log(e);
160                 }
161             }
162             return job;
163         }
164
165         public boolean isPatch() {
166             return patch;
167         }
168         public IInstallFeatureOperation getPatchedJob() {
169             return patchFor;
170         }
171     }
172
173     public class UpdateQuery implements IUpdateSearchQuery {
174         IFeature candidate;
175         IQueryUpdateSiteAdapter adapter;
176
177         public UpdateQuery(
178             IFeature candidate,
179             IURLEntry updateEntry) {
180             this.candidate = candidate;
181             if (updateEntry != null && updateEntry.getURL() != null)
182                 adapter =
183                     new QueryUpdateSiteAdapter(
184                         getLabelForEntry(updateEntry),
185                         updateEntry.getURL(),
186                         candidate.getVersionedIdentifier().getIdentifier());
187         }
188         private String JavaDoc getLabelForEntry(IURLEntry entry) {
189             String JavaDoc label = entry.getAnnotation();
190             if (label == null || label.length() == 0)
191                 label = entry.getURL().toString();
192             return label;
193         }
194
195         public IQueryUpdateSiteAdapter getQuerySearchSite() {
196             return adapter;
197         }
198         private boolean isBroken() {
199             try {
200                 IStatus status =
201                     SiteManager.getLocalSite().getFeatureStatus(candidate);
202                 return status.getSeverity() == IStatus.ERROR;
203             } catch (CoreException e) {
204                 return false;
205             }
206         }
207         private boolean isMissingOptionalChildren(IFeature feature) {
208             try {
209                 IIncludedFeatureReference[] children =
210                     feature.getIncludedFeatureReferences();
211                 for (int i = 0; i < children.length; i++) {
212                     IIncludedFeatureReference ref = children[i];
213                     try {
214                         IFeature child = ref.getFeature(null);
215                         // If we are here, the child is not missing.
216
// Check it's children recursively.
217
if (isMissingOptionalChildren(child))
218                             return true;
219                     } catch (CoreException e) {
220                         // Missing child. Return true if optional,
221
// otherwise it is a broken feature that we
222
// do not care about.
223
if (ref.isOptional()) {
224                             return FeatureHierarchyElement.hasOlderVersion(ref);
225                         }
226                     }
227                 }
228             } catch (CoreException e) {
229             }
230             return false;
231         }
232         public void run(
233             ISite site,
234             String JavaDoc[] categoriesToSkip,
235             IUpdateSearchFilter filter,
236             IUpdateSearchResultCollector collector,
237             IProgressMonitor monitor) {
238             ArrayList JavaDoc hits = new ArrayList JavaDoc();
239             boolean broken = isBroken();
240             boolean missingOptionalChildren = false;
241
242             // Don't bother to compute missing optional children
243
// if the feature is broken - all we want is to
244
// see if we should allow same-version re-install.
245
if (!broken)
246                 missingOptionalChildren = isMissingOptionalChildren(candidate);
247             ISiteFeatureReference[] refs = site.getFeatureReferences();
248             monitor.beginTask("", refs.length + 1); //$NON-NLS-1$
249
ArrayList JavaDoc updateJobs = new ArrayList JavaDoc();
250             for (int i = 0; i < refs.length; i++) {
251                 ISiteFeatureReference ref = refs[i];
252                 try {
253                     if (isNewerVersion(candidate.getVersionedIdentifier(),ref.getVersionedIdentifier())) {
254                         Hit h = new Hit(candidate, ref);
255                         hits.add(h);
256                         IInstallFeatureOperation job = h.getJob();
257                         if (job != null)
258                             updateJobs.add(job);
259                     } else {
260                         // accept the same feature if the installed
261
// feature is broken
262
if ((broken || missingOptionalChildren)
263                             && candidate.getVersionedIdentifier().equals(
264                                 ref.getVersionedIdentifier())){
265                             hits.add(new Hit(candidate, ref));
266                             continue;
267                         }
268                         else {
269                             // check for patches
270
if (isPatch(candidate, ref)){
271                                 hits.add(new Hit(candidate, ref, true));
272                                 continue;
273                             }
274                         }
275                     }
276                 } catch (CoreException e) {
277                 }
278                 monitor.worked(1);
279                 if (monitor.isCanceled()){
280                     return;
281                 }
282                 
283             }
284             // accept patches for updated features
285
for (int n = 0; n < updateJobs.size(); n++) {
286                 IInstallFeatureOperation job = (IInstallFeatureOperation) updateJobs
287                         .get(n);
288                     IFeature newCandidate = job.getFeature();
289                     for (int i = 0; i < refs.length; i++) {
290                         ISiteFeatureReference ref = refs[i];
291                         if (isPatch(newCandidate, ref)) {
292                             Hit h = new Hit(newCandidate, ref, job);
293                             hits.add(h);
294                             continue;
295                         }
296                         //monitor.worked(1);
297
if (monitor.isCanceled()) {
298                             return;
299                         }
300                     }
301             }
302             if (hits.size() > 0) {
303                 collectValidHits(hits, filter, collector);
304             }
305             monitor.worked(1);
306             monitor.done();
307         }
308         
309         /**
310          * Returns IFeature associated with the IUpdateSearchQuery
311          */

312         public IFeature getFeature() {
313             return candidate;
314         }
315     }
316
317     private ArrayList JavaDoc candidates;
318
319     public UpdatesSearchCategory() {
320         this(true);
321     }
322     
323     public UpdatesSearchCategory(boolean automatic) {
324         super(CATEGORY_ID);
325         this.automatic = automatic;
326     }
327
328     private void collectValidHits(
329         ArrayList JavaDoc hits,
330         IUpdateSearchFilter filter,
331         IUpdateSearchResultCollector collector) {
332         //Object[] array = hits.toArray();
333
IFeature topHit = null;
334         for (int i = 0; i < hits.size(); i++) {
335             Hit hit = (Hit) hits.get(i);
336             IInstallFeatureOperation job = hit.getJob();
337             if (job == null)
338                 continue;
339             // do not accept updates without a license
340
if (!UpdateUtils.hasLicense(job.getFeature())) {
341                 UpdateCore.log(job.getFeature().getVersionedIdentifier() + ": " + Messages.DefaultFeatureParser_NoLicenseText, null); //$NON-NLS-1$
342
continue;
343             }
344             IStatus status = null;
345             
346             // Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=132450
347
// Only validate for automatic updates because
348
// non-automatic once will arrive in the review wizard
349
// where additional validation will be performed
350
if (automatic) {
351                 if( hit.getPatchedJob()==null){
352                     status = OperationsManager.getValidator().validatePendingInstall(job.getOldFeature(), job.getFeature());
353                 }else{
354                     status = OperationsManager.getValidator().validatePendingChanges(new IInstallFeatureOperation[]{hit.getPatchedJob(), job});
355                 }
356             }
357             if (status == null || status.getCode() == IStatus.WARNING) {
358                 if (hit.isPatch()) {
359                     IFeature patch = job.getFeature();
360                     // Do not add the patch if already installed
361
IFeature[] sameId = UpdateUtils.getInstalledFeatures(patch, false);
362                     if (sameId.length==0) {
363                         if (filter.accept(patch))
364                             collector.accept(patch);
365                     }
366                 }
367                 else {
368                     topHit = job.getFeature();
369                     if (filter.accept(topHit))
370                         collector.accept(topHit);
371                 }
372             }
373         }
374     }
375
376     private void initialize() {
377         candidates = new ArrayList JavaDoc();
378         try {
379             ILocalSite localSite = SiteManager.getLocalSite();
380             IInstallConfiguration config = localSite.getCurrentConfiguration();
381             IConfiguredSite[] isites = config.getConfiguredSites();
382             for (int i = 0; i < isites.length; i++) {
383                 contributeCandidates(isites[i]);
384             }
385         } catch (CoreException e) {
386             UpdateCore.log(
387                 Messages.UpdatesSearchCategory_errorSearchingForUpdates,
388                 e);
389         }
390     }
391
392     private void contributeCandidates(IConfiguredSite isite)
393         throws CoreException {
394         IFeatureReference[] refs = isite.getConfiguredFeatures();
395         ArrayList JavaDoc candidatesPerSite = new ArrayList JavaDoc();
396         for (int i = 0; i < refs.length; i++) {
397             IFeatureReference ref = refs[i];
398             // Don't waste time searching for updates to
399
// patches.
400
try {
401                 if (UpdateUtils.isPatch(ref.getFeature(null)))
402                     continue;
403             }
404             catch (CoreException e) {
405                 continue;
406             }
407             Candidate c = new Candidate(ref);
408             candidatesPerSite.add(c);
409         }
410         // Create a tree from a flat list
411
buildHierarchy(candidatesPerSite);
412         // Add the remaining root candidates to
413
// the global list of candidates.
414
candidates.addAll(candidatesPerSite);
415     }
416
417     private void buildHierarchy(ArrayList JavaDoc candidates) throws CoreException {
418         Candidate[] array =
419             (Candidate[]) candidates.toArray(new Candidate[candidates.size()]);
420         // filter out included features so that only top-level features remain on the list
421
for (int i = 0; i < array.length; i++) {
422             Candidate parent = array[i];
423             IFeature feature = parent.getFeature(null);
424             IFeatureReference[] included =
425                 feature.getIncludedFeatureReferences();
426             for (int j = 0; j < included.length; j++) {
427                 IFeatureReference fref = included[j];
428                 Candidate child = findCandidate(candidates, fref);
429                 if (child != null) {
430                     parent.add(child);
431                     child.setReference(fref);
432                     candidates.remove(child);
433                 }
434             }
435         }
436     }
437     private Candidate findCandidate(ArrayList JavaDoc list, IFeatureReference ref) {
438         for (int i = 0; i < list.size(); i++) {
439             Candidate c = (Candidate) list.get(i);
440             if (c.ref.equals(ref))
441                 return c;
442         }
443         return null;
444     }
445
446     public IUpdateSearchQuery[] getQueries() {
447         initialize();
448         ArrayList JavaDoc allCandidates = getAllCandidates();
449
450         IUpdateSearchQuery[] queries =
451             new IUpdateSearchQuery[allCandidates.size()];
452         for (int i = 0; i < queries.length; i++) {
453             Candidate candidate = (Candidate) allCandidates.get(i);
454             IFeature feature = candidate.getFeature(null);
455             IURLEntry updateEntry = candidate.getUpdateEntry();
456             if (feature == null) {
457                 queries[i] = null;
458             } else {
459                 queries[i] = new UpdateQuery(feature, updateEntry);
460             }
461         }
462         return queries;
463     }
464     
465 /**
466  * Sets the features for which new updates need to be found. If
467  * not set, updates will be searched for all the installed
468  * and configured features.
469  * @param features the features to search updates for
470  */

471     public void setFeatures(IFeature [] features) {
472         this.features = features;
473     }
474     
475 /**
476  * Returns an array of features for which updates need to
477  * be found.
478  * @return an array of features or <samp>null</samp> if not
479  * set.
480  */

481     public IFeature [] getFeatures() {
482         return features;
483     }
484     /**
485      * @param fvi
486      * @param cvi
487      * @return fvi < cvi
488      */

489     private boolean isNewerVersion(
490         VersionedIdentifier fvi,
491         VersionedIdentifier cvi) {
492         if (!fvi.getIdentifier().equals(cvi.getIdentifier()))
493             return false;
494         PluginVersionIdentifier fv = fvi.getVersion();
495         PluginVersionIdentifier cv = cvi.getVersion();
496         String JavaDoc mode = getUpdateVersionsMode();
497         boolean greater = cv.isGreaterThan(fv);
498         if (!greater)
499             return false;
500         if (mode.equals(UpdateCore.EQUIVALENT_VALUE))
501             return cv.isEquivalentTo(fv);
502         else if (mode.equals(UpdateCore.COMPATIBLE_VALUE))
503             return cv.isCompatibleWith(fv);
504         else
505             return false;
506     }
507
508     private boolean isPatch(IFeature candidate, ISiteFeatureReference ref) {
509         if (ref.isPatch() == false)
510             return false;
511         try {
512             IFeature feature = ref.getFeature(null);
513             if( UpdateUtils.isPatch(candidate, feature))
514                 return true;
515             // Check if patch is for children
516
try {
517                 IIncludedFeatureReference[] children =
518                     candidate.getIncludedFeatureReferences();
519                 for (int i = 0; i < children.length; i++) {
520                     IIncludedFeatureReference cref = children[i];
521                     try {
522                         IFeature child = cref.getFeature(null);
523                         if (isPatch(child, ref))
524                             return true;
525                     } catch (CoreException e) {
526                     }
527                 }
528             } catch (CoreException e) {
529             }
530             return false;
531         } catch (CoreException e) {
532             return false;
533         }
534     }
535     
536     private String JavaDoc getUpdateVersionsMode() {
537         Preferences store = UpdateCore.getPlugin().getPluginPreferences();
538         return store.getString(UpdateCore.P_UPDATE_VERSIONS);
539     }
540 /*
541  * This method recursively walks the list of candidates
542  * building the flat that starts with the roots but
543  * also includes all the children that are updatable
544  * (use 'include' clause with a match that is not 'perfect').
545  */

546     private ArrayList JavaDoc getAllCandidates() {
547         ArrayList JavaDoc selected = new ArrayList JavaDoc();
548         for (int i=0; i<candidates.size(); i++) {
549             Candidate c = (Candidate)candidates.get(i);
550             if (isOnTheList(c))
551                 c.addToFlatList(selected, true);
552         }
553         return selected;
554     }
555     
556     private boolean isOnTheList(Candidate c) {
557         if (features==null) return true;
558         VersionedIdentifier vid;
559         try {
560             vid = c.getReference().getVersionedIdentifier();
561         }
562         catch (CoreException e) {
563             return false;
564         }
565         for (int i=0; i<features.length; i++) {
566             IFeature feature = features[i];
567             VersionedIdentifier fvid = feature.getVersionedIdentifier();
568             if (fvid.equals(vid))
569                 return true;
570         }
571         return false;
572     }
573 }
574
Popular Tags